CPS 445 Lecture notes: Command shells
Coverage: [USP] Chapter 11
Basic shell setup
(regenerated from [ATT])
see [USP] §§11.1-11.3 for more details
Signal handling in the foreground
- a <ctrl-c> should not cause the shell to exit;
shell should ignore SIGINT and SIGQUIT
and block them
- since child should be able to be terminated, child
must set the handlers for SIGINT and SIGQUIT
back to the default before execing
- ush3.c;
signalsetup.c
- improvement in ush4.c;
shell should not just ignore SIGINT;
it should deal with it;
- furthermore, shell should only block SIGINT
and SIGQUIT when absolutely necessary
- if shell (parent) receives a SIGINT,
parent clears the input line and returns to prompt through
siglongjump
- child (command) should not do this
- child should take the default action, which is to exit
- parent blocks the signal before the fork
- child restores the default action prior to unblocking;
done by default with execvp
- child cannot wait for this feature in execvp;
a signal may come in between unblocking the signal
and the call to execvp
- William Kimball asks `why not just remove the if statement
entirely from the child?'
- why is wait now at the top of the loop?
Back to signal handling in the foreground
- William Kimball asks `why not just remove the if statement
entirely from the child?'
because the exec will not unblock by default
- why is wait now at the top of the loop?
- how to integrate with pipelines and background processes?
Process groups, sessions, and controlling terminals: context
- pipes need process groups
- background processes need sessions and controlling terminals
Process groups
- a process group is a collection of processes;
established so a group of processes can receive a signal as a unit
- process group id: associated with each process
- use negative sign with kill
- the process id of process group leader is equal in value to the
id of the process group
- group persists as long as some process is in it;
thus, a group may be without a leader
- child processes inherit the group id of their parent
- setpgid: allows a process to change its group
- id of calling process assumed if passed a 0 for pid
- the process with pid becomes the leader if passed a 0 for
gpid
- parent can use this function to change the group
of its child before a call to exec
- a child can establish a new group for itself by calling
this function with pgid set to the value of its pid
- getpgrp returns the process group id of the caller
Sessions
Controlling terminals
- a session may have a controlling terminal associated with it
- shell uses the controlling terminal to interact with user
- a controlling terminal is associated with only one session
- while session may contain multiple groups, only one at a time
can perform I/O through the controlling terminal
- called the foreground process group or foreground job
- others are called the background process groups or
background jobs;
processes in this group
are not affected by keyboard input from the terminal controlling the
session to which it belongs
- main purpose of job control is to shift processes between these
two groups
- ctermid: used to obtain the name of the caller's controlling
terminal
- Example 11.22: <ctrl-c> during
execution of ls -l | sort -n +4 | more;
all 4 processes belong to the foreground process group
- Example 11.23: <ctrl-c> during
execution of ls -l | sort -n +4 | more &
See nice summary on p. 391
Background processes
- shell does not wait for a background process
- background process is not killed by a SIGINT
from the keyboard
- rusers & is a long running command
which is good for purposes of testing background processes
- ush5.c handles background processes
- must determine if an & is present
on the command line before forking;
because both parent and child need this information
- parent does not wait
- child calls setpgid to detach itself
from the foreground process group of its session
- demonstration of zombies
- ush6.c address the problem of zombie processes
- fork twice thus creating a child and grandchild
- child exits immediately
- this leaves the grandchild as an orphan adopted by init
- now have parent wait for all children, even background
processes
- graphical depiction
- new problem: shell must be able to detect of background process
was stopped due to a SIGSTOP
- waitpid has an option for detecting children stopped by
signals
- however, due to the extra fork, the command is run as
a grandchild of the shell, not a child
- solution: do not use extra call to fork; call
waitpid with WNOHANG
- more direct solution approach
- implemented in ush7.c
References
| [ATT] |
UNIX System Calls and Libraries -- Part 1, Version 2.1.1, AT&T, 1990. |
| [USP] |
K.A. Robbins and S. Robbins.
UNIX Systems Programming: Concurrency, Communication, and Threads.
Prentice Hall, Upper Saddle River, NJ, Second edition, 2003.
|
|