teleTele teleTele - 1 month ago 7
C Question

strtok() overwrites its source string

I'm writing a toy bash shell. My goal right now is to cycle through the environment looking for the path a specific command can be found at. Right now I am delimiting the PATH (e.g. "/home/user/bin:home/user/.local/bin:/usr/local/sbin" etc) by ":", and for each path that gives me, copying that path to the new string

, and then concatenating "/cmd" to the end.

My problem is that when I try to copy the contents of path into
, any changes I make to
are then reflected onto path. As the code is right now,
will only be set to "home/user/bin" once, cycle through and be set to the same thing again, then the tokenizer hits "NULL" and terminates the while loop.

This suggests that
are sharing a memory address, but since strcpy theoretically makes a new copy in memory, I must be doing something wrong with my strings and pointers.

Any idea what's causing this unexpected behavior?

Edit: this code executes just as expected when I comment out strcpy

A stripped-down version of my code is below:

int findpath(char* cmd, command_t* p_cmd) {
char* path_var;

path_var = getenv( "PATH" );

char* path;
char tempEnv[sizeof(path_var)];
strcpy(tempEnv, path_var);
path = strtok(tempEnv, ":");

while(path != NULL) {
char fullPath[1000];
strcpy(finalPath, path);
printf("path: %s\n", path);
printf("finalPath: %s\n", finalPath);
path = strtok(NULL, ":");

cxw cxw

BLUEPIXY is right: the tempEnv isn't big enough for your string. Try:

char *tempEnv;
tempEnv = malloc(strlen(path_var)+1);
strcpy(tempEnv, path_var);

and at the end


With the proviso that this is full of holes. You should be using safer string functions, e.g., as described here. For example, don't assume path_var is NULL-terminated. Use strncpy instead of strcpy. And a host of other rules, which I am not including here since your goal appears to be learning rather than production code. Happy hacking!