so I’m working on a simulated linux shell using C (homework), and I have it exiting the program if the user just simply types in “quit”.
However, if they throw “exit” somewhere inside a command… “cat file ; exit”
I need it to execute the command like normal, then quit.
I know that I still have to filter the string entered and strip it of the exit, but for now, I’m just simply trying to get it to recognize the substring of “exit” using strstr() and to exit the program. It just keeps looping if input contains a string with substring “exit” currently.
Thank you.
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define bSize 1000 void driveLoop(); char *userInput(void); int main(int argc, char **argv){ driveLoop(); return 0; } void driveLoop(void){ char *comTokens[100]; char *tempTokens; char *command; char *cd; char *cdDir; char *cdTemp; char cdBuf[bSize]; char checkExit[] = "exit"; for (;;){ printf("> "); command = userInput(); if (!command) break; char *exitPtr = strstr(command, checkExit); // using strstr on the pointer containing the input int i = 0; tempTokens = strtok(command, " tn"); while (tempTokens && i < 99){ comTokens[i++] = tempTokens; tempTokens = strtok(NULL, "tn"); } if (strcmp(comTokens[0], "exit") == 0){ // this exit is working normally exit(0); } if (strcmp(comTokens[0], "cd") == 0){ cd = getcwd(cdBuf, sizeof(cdBuf)); cdDir = strcat(cd, "/"); cdTemp = strcat(cdDir, comTokens[1]); continue; } comTokens[i] = NULL; pid_t cFork = fork(); if (cFork == (pid_t) - 1){ perror("fork"); } else if (cFork == 0){ execvp(comTokens[0], comTokens); perror("exec"); if (exitPtr != NULL){ // here's where I'm calling the exit exit(0); // nothing happens though. It just keeps looping. } } else { int status; waitpid(cFork, &status, 0); } } } char *userInput(void){ char *input = NULL; size_t size = 0; getline(&input, &size, stdin); return input; }
Advertisement
Answer
else if (cFork == 0){ execvp(comTokens[0], comTokens); perror("exec"); if (exitPtr != NULL){ // here's where I'm calling the exit exit(0); // nothing happens though. It just keeps looping. } }
execvp
doesn’t return if it succeeds, so your if
will normally never be executed. (And if execvp
does return, you probably want to exit the child unconditionally, preferably with _exit()
.)
What you really want is for the parent process to exit. So you probably wanted to put this code in the parent branch of the fork:
else { int status; waitpid(cFork, &status, 0); // add it here if (exitPtr != NULL){ exit(0); } }