c - Why does this code not get executed? -
i'm making own shell program. have keep history of last 10 commands user inputs. whenever user enters command isn't regular command (for example history, hi, fakecommand, etc.) placed in history. whenever user inputs real command (example ls, ps, top, cat, etc.) not added history.
i think might have execvp command, since believe command creates fork , makes child execute command. i'm not sure should since put command in history before execute execvp.
//a method increments histindex int incrementindex(int index) { if (index != 9) return index+1; else return 0; } //a method adds current command history void updatehistory(char *history[], char command[], int histindex) { history[histindex] = realloc(history[histindex], max_length); //allocating space strcpy(history[histindex], command); //put current command in history } int main(int argc, char *argv[]) { //while true, while (1) { int pid = fork(); //fork, or start first process if (pid != 0) { //if pid not 0, parent, wait(null); } else { //otherwise, have child printf("%s> ", getenv("user")); //print out user's name + > fgets(input, max, stdin); //get users input strtok(input, "\n"); //take entire line , set input updatehistory(history, input, histindex); //updating history histindex = incrementindex(histindex); if (strcmp(input, "exit")==0) { //if input exit, exit exit(0); } //else if current command history, print last 10 commands else if (strcmp(input, "history")==0) { gethistory(history, histindex); } //otherwise, else { numtokens = make_tokenlist(input, tokens); tokens[numtokens] = null; char cmd[max_length]; strcpy(cmd, tokens[0]); execvp(cmd, tokens); printf("error: %s not found.\n", cmd); } } } }
separate processes have own separate memory space (unless special shared memory, etc.). whatever updates heap or stack structures in child process (such modifying history), has no effect in parent.
you creating child fork()
, reading user input in child. child updates own copy of history, has no effect on whatever history parent knows about. execvp()
not fork, replaces current process executed file. replaces entire child process, , lose history updated in child.
you have children making children, not want, explains why think adding invalid commands history. (it is, not correctly.) illustration of sequence of events:
parent ------ fork() ------> child wait() ----- ... read input ... updatehistory() ... exit if "exit" ... print history if "history" ... execvp() (if execvp() succeeded, child consumed, executed file terminates , parent stops waiting. if execvp() failed, fall through top of while loop!) fork() ---------> child's child wait() ------------- ... read input ... updatehistory() ... exit if "exit" ... print history if "history" ... execvp()
the child's child has inherited child's memory, knows updated history. why think adding failed commands history. is, it's worse that.
it seems should reading input in parent, updating history in parent, (given valid command), fork
off child process consumed execvp
run command. let parent wait
child finish. way, parent maintains history. 1 primary purpose forking child in first place because execvp
replaces calling process. since want parent live on, let eat child.
try (i'll leave abstract pseudocode):
parent ------ read input updatehistory() exit if "exit" print history if "history" if invalid, go [read input] if valid: fork() ------> child wait() ----- ... execvp() ... <------- if successful, executable terminates ... <------- if failed, print error , exit (either way, child ends) parent goes [read input]
another thing worth mentioning, whenever fork()
, should check 3 possible return values: -1 (error in fork()
), >0 (in parent process), , 0 (in child process).
Comments
Post a Comment