Sending a process to the background and returning control to my shell Sending a process to the background and returning control to my shell shell shell

Sending a process to the background and returning control to my shell


tcsetpgrp() works on process groups, not individual processes. What you want to do is this:

  1. When you create a new pipeline, call setpgid() to put all the members of the pipeline in a new process group (with the PID of the first process in the pipeline as the PGID). (A pipeline is a sequence of processes started by your shell when it sees a request like ls | grep foo | wc -l - the simplest pipeline has just one process in it). Normally you would call setpgid(0, 0) from the first process in the pipeline, before calling exec().

  2. Use tcsetpgrp() to manage which process group is in the foreground. If you move a process group from the foreground to the background, you would set the shell's own process group as the foreground process group - you can get this with getpgid(0) in the shell.

  3. When the shell is in the background, it should use a blocking waitpid() call to wait for a child process to exit rather than show a prompt. Once every process in the foreground pipeline has exited, it should put itself back into the foreground again (and show a prompt).

  4. When the shell is in the foreground, it should call waitpid() with the WNOHANG and WUNTRACED flags to check on the status of child processes just before you show the prompt - this will inform you when they have stopped or exited, and let you inform the user.


You should take a look at fork to create the child process. Then, use exec in the child to run the desired command.


If your shell starts a process using & to background it, the $! shell variable will contain the PID of the child process. You can then send signals to that process, or use wait $! to wait for it to complete.