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

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -