Sending a process to the background and returning control to my shell
background-process, c, linux, process-group, shell
Solution
`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 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()`.
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.
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 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.
Problem
I am programming a shell for my CS class and part of the project involves running a process in the background if the '&' character is passed in by the user. If a process is run in the foreground, I simply `execvp` the process and it remains in control of the terminal since it is in the foreground. However, if it is a background process, I must return control to my main shell after starting the execution of the process. I understand that the system call `tcsetpgrp(pid_t)` places the process passed in as argument in the foreground, but I don't quite understand how to use it. Should I call `tcsetpgrp` after `execvp` if it is a background process? If so, can I obtain the pid of my shell just by calling `getpid`?