Trying to build a shell implementation in linux for an assignment and am having trouble. I get the following error after running 3/4 times into the loop
* Error in `./1': realloc(): invalid next size: 0x000000000132c150 * Aborted (core dumped)
I have left parts of the code out as it's long and I know there's no issues with them. If there's other parts you need I can add them too. Thanks in advance :)
Note: argc and argv are global variables
int argc = 0;
char **argv = NULL;
int main(void)
{
while(1)
{
catch_signal();
printDate();
readCommand();
if(strcmp(argv[0], "cd") == 0)
{
changeDirectory();
}
else
{
executeCommand();
}
//free(argv);
}
}
void readCommand()
{
char *buffer = NULL;
char *token = " ";
char *p;
size_t len = 0;
int i = 0;
getline(&buffer, &len, stdin);
p = strtok(buffer, "\n");
p = strtok(buffer, token);
while(p)
{
argv = realloc(argv, sizeof(char *) * ++i);
argv[i - 1] = p;
p = strtok(NULL, token);
}
argc = i;
argv[argc] = NULL;
free(p);
}
void executeCommand()
{
int status;
pid_t pid;
if((pid = fork()) < 0)
{
printf("Error: forking child process failed.");
}
else if(pid == 0)
{
if(execvp(argv[0], argv) < 0)
{
printf("error");
exit(1);
}
}
else
{
while(wait(&status) != pid);
}
}
You are reallocating the argv array 1 pointer too short. There is not enough space for the final NULL
pointer. Consider replacing the while(p)
loop with this code:
if (!p) {
/* deal with empty command line */
}
while (p) {
argv = realloc(argv, sizeof(char *) * (i + 2));
argv[i++] = p;
p = strtok(NULL, token);
}
p
should start as NULL
if the user entered an actual command. But what if buffer contains an empty string or just a blank one? strtok
will return NULL
directly in these cases. You should ignore such command lines.