0

Im currently working on a class work in the Introduction to Operative Systems course, and we are asked to build a simple command interpreter in C. For this interpreter, if we put '&' before a comand we execute it in the background and if we put ';' we execute it as usual (in the foreground). We are using fork and process management functions, so when we are in the parent process, if we typed ';' we simply wait until the child process (executing the comand, for example pwd), and if we put '&' we just dont wait and we break from the switch-case on where we are.

this is the code:

err = get_arguments(buf, n, arg, MAXARG); //if we type & sleep 5 we get the sleep 5 in the arg
      id = fork();      
      switch (id){
        case -1: 
          errore("fork");
          break;
        case  0: /* child process */
          /* execute the command using execvp */
          pid = getpid();
          pid_parent = getppid();
          if(buf[0] == '&') {
            printf("-U------- Child: just created (PID %d - Parent PID: %d): now executing'%s ...' in the background...\n",
                pid, pid_parent, arg[0]);
          } else if(buf[0] == ';') {
            printf("-U------- Umea naiz: sortu berria (PID %d - Parent PID: %d): orain '%s ...' exekutatzera aurreko planoan...\n",
                pid, pid_parent, arg[0]);
          }
          execvp(arg[0], arg);
          printf("-U------- Child (PID %d): i'm here only if an error has ocurred\n",
                pid);
          errore("exec");
          break;
        default: /* parent */
          pid_child = id;
          pid = getpid();
          printf("-G------- Parent (PID %d): child process '%s ...' (PID %d) started \n",
                pid, arg[0], pid_child);
          if(buf[0] == '&') { // if we want to execute in the background 
            break; //break and don't wait for the child to stop
          } else if(buf[0] == ';') { // if it's in the foreground
            /* wait until child finishes */
            pid_finished = wait(&status);
            if ( pid_finished != pid_child) { 
              errore("wait");
            } else {
              if (WIFEXITED(status)){        // get the return code
                child_return_code = WEXITSTATUS(status);
                printf("-G------- Parent (PID %d): a child process (PID %d) has finished with the %d return code\n",
                  pid, pid_finished, child_return_code);
              }
            };
          }
          break; 
      }
    }
    for (n = 0; n < BUFSIZE; n++) buf[n] = '\0';
    write(1, "prompt$ ", 9); //write the prompt again

When I write ; pwd for example, it obviously works great. How ever, i want the parent process to know when a child process that has been executed in the background, has finished. And when if happens, print it's id and the return code.

I don't know how to do this, because when execvp is used, the code that comes after it only gets executed when an error happens. So how can I know when this child process has finished in the background?

My code was in spanish so maybe something is spelled wrong, I tried my best.

Thank you so much!

Julen
  • 11
  • 6
  • You can start many background commands and some may never end. Handle the event https://stackoverflow.com/q/61289666/1216776 – stark May 14 '21 at 11:11
  • When the child finishes, the parent will receive a SIGCHLD. The parent needs to keep track of its children and respond. – William Pursell May 14 '21 at 12:20
  • When the SIGCHLD arrives, write a single byte into a pipe. In the parent's main loop, add that pipe to the set that is watched by the `select`. The parent is spending most of its time waiting for input from the user, and that may be implemented with an `epoll` or something other than `select`, but should certainly not just be a simple `read`. The parent will have a data structure about its children which keeps track of the pids of all active children. Find the one that is terminated and deal with it appropriately. – William Pursell May 14 '21 at 12:45
  • https://stackoverflow.com/questions/5530904/handling-sigchld-how-to-record-the-return-values-of-children-as-they-die – William Pursell May 14 '21 at 12:46
  • thanks! I'll try it – Julen May 14 '21 at 14:03

0 Answers0