Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 639
user1420913 Avatar asked May 28 '12 03:05

user1420913


People also ask

How does shell handle background process?

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.

How do I move a process to the background in Linux?

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.

How do you run shell commands as foreground and background processes?

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.

How do you direct the shell to execute a command in the background?

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.


1 Answers

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.

like image 175
caf Avatar answered Sep 18 '22 14:09

caf