March 27, 2006
Coverage:
[USP] Chapter 8
sigsuspend Function
- blocks and waits atomically
- returns when signal handler returns
- on return, resets the mask back to what is was before the call
- example 1: code to wait for a particular signal
- example 2: code to wait for a particular signal while not
blocking other signals
- notice that when sigsuspend returns, the
process signal mask is reset to the value it had
before sigsuspend was called
- example 3: cleaner version of code from example 2
C Object Implementations for Signal-based Control
- simplesuspend.c: object which safely blocks on a specific signal
- simplesuspendtest.c: driver that waits for SIGUSR1
- notifyonoff.c: object which provides two-signal control
for turning a service on or off
- uses 2 signals to control the setting/clearing of a flag
- initnotify: takes two signals
- signo1 - sets the notify flag
- signo2 - clears the notify flag
- waitnotifyon: waits until notify flag is set on by
delivery of signo1
- biff.c: a safe implementation of biff based on
notifyonoff.c
- biff y: sends SIGUSR1
- biff n: sends SIGUSR2
sigwait Function
- the complement of sigsuspend
- both take a signal set
- sigwait takes those signals that are to be waited for,
while sigsuspend takes those that are to be blocked
- signals in the set passed to sigwait should be
blocked prior to the call
- the number of the pending signal removed from the pending
signals is pointed to by signo
- sigwait does not change the process mask, while
sigsuspend does
- countsignals.c: a program which uses sigwait
and counts the number of SIGUSR1 signals received
Important Issues in the Handling of Signals
- should we restart POSIX library functions interrupted by signals?
- it depends on the particular call
- slow POSIX library calls are those interrupted by signals
- they return when the signal handler returns
- terminal i/o and reads from a pipe are considered slow,
i.e., they can block a process for an undetermined period of time
- disk i/o blocks for shorter periods
- functions like getpid do not block at all
- errno will get set to EINTR if function
interrupted by a signal
- program must handle this error and possibly restart the system
call
- no logical way to determine, must see man page
- should signal handlers call non-reentrant functions (e.g., strtok)?
- in this context, asynchronous means `at any time'
- signals add concurrency to a program, why?
- since they occur asynchronously, a process may catch a
signal while executing a library function!
- e.g., suppose a signal, whose handler calls strtok, interrupts
the execution of strtok
- a function is async-signal safe if it can be
safely called from a signal handler
- many POSIX calls are not async-signal safe due to the use of
- static data structures
- malloc or free
- global data structures
- bottom line: you must exercise caution when calling
library functions from within signal handlers
- see table of async-signal safe library functions on p. 285
- how to handle errors that use errno?
- problem is errors in signal handler can interfere
with error handling of rest of program
- example:
- part of a program returns -1 and sets errno
- now a signal is caught (and handled) before the error message
is printed
- if the signal handler calls a function which causes errno
to be changed, an incorrect error might be reported
- simple solution: make signal handlers save and restore errno
if they use functions that might change it
- follow signal-handling guidelines at top of p.286
References
[USP] K. A. Robbins and S. Robbins. UNIX Systems Programming: Concurrency,
Communication, and Threads. Prentice Hall, 2003