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
?
A background process is associated with the specific terminal that started it, but does not block access to the shell. Instead, it executes in the background, leaving the user able to interact with the system while the command runs.
To move foreground jobs in the background, we use the bg command in the Linux system. bg (background) – The bg command is used to move foreground jobs in the background. It resumes execution of a suspended process in the background. If no job is specified, then the bg command work upon the currently running process.
Programs and commands run as foreground processes by default. To run a process in the background, place an ampersand (&) at the end of the command name that you use to start the process.
Running shell command or script in background using nohup command. Another way you can run a command in the background is using the nohup command. The nohup command, short for no hang up, is a command that keeps a process running even after exiting the 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 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With