I’m writing a simple shell that accepts some standard commands like cd and ls in C. I’m trying to implement a feature where the user can enter a “;” in between commands so that a bunch of commands can be written on the same line and be executed separately. So if I input “cd Desktop; ls” the shell should cd to Desktop and print the what’s in the directory. The problem is it only executes the first command. Here’s my main method:
char input[1024];
while(1)
{
printf("%s ", prompt);
fgets(input, 1024, stdin);
char delims[] = ";";
char *result = NULL;
result = strtok( input, delims );
while( result != NULL )
{
printf("%s\n", result);
char * copy = malloc(strlen(result) + 1); //Create a copy of the input token
strcpy(copy, result);
format(copy);
if(programs)
{
handle();
cleanup(programs);
programs = NULL;
}
free(copy);
result = strtok( NULL, delims );
cmdno++;
}
}
First I try to break up the input into tokens based on “;” and then feed the token to the format() method which looks like this:
int format(char input[])
{
input = strtok(input, "\n");
...
}
I know that strtok makes changes to the original string, which is why I create a copy of the token first before passing it to format. Is what I’m doing correct??
You can’t mix multiple
strtokcalls. Here’s what’s happening:inputsostrtoktakes note and stores stuff internallyinputcopyso againstrtoktakes note, thereby destroying the previous infostrtokonly knows about thecopybusiness and doesn’t know anything about the originalinput.The main problem is that
strtokdoesn’t know that you’re doing two things at the same time. From its point of view, you simply started processing a different string before finishing the first string.Possible solutions:
strtok_rif you have it. It’s not standard C (but it is standard POSIX). Therstands for reentrantcopybefore finishing withinputAbout that last point:
char *and fill it withstrtokwithout pausing to split sub-tokens. So each element should be a different command";"split, start processing each of the array elements