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:
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 likels | grep foo | wc -l
- the simplest pipeline has just one process in it). Normally you would callsetpgid(0, 0)
from the first process in the pipeline, before callingexec()
.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 withgetpgid(0)
in the shell.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).When the shell is in the foreground, it should call
waitpid()
with theWNOHANG
andWUNTRACED
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.