You are on page 1of 20

Signals

Signal Concepts
 Signals are software interrupts
 Used to handle asynchronous events
 Each signal is a positive integer, defined by
standardized names
 All the signals start with SIG
 SIGKILL = 9
 SIGTERM = 15
 SIGCHLD = 17
 SIGINT = 2
Signal Concepts
 Signals are defined in <signal.h>
 man 7 signal for complete list of signals
and their numeric values
 kill –l for full list of signals on a system
 64 signals. The first 32 are traditional
signals, the rest are for real time
applications
Conditions That Can Generate
Signals
 Generated by terminal
 ctrl-c, ctrl-\, ctrl-z etc
 Hardware exceptions can generate signals
 Division by zero, bad memory reference, etc
 “kill” shell command: ex – kill pid
 kill function call
int kill(pid_t pid, int sig);
 Software can generate signals
 SIGALRM, SIGPIPE, etc
 Page 292-298 has descriptions of each signal
Signal Dispositions
 Ignore the signal
 SIG_IGN
 Note: SIGKILL and SIGSTOP can not be ignored
 Catch the signal
 Register a custom signal handler to be run when
the process is sent the corresponding signal
 Allow default action
 SIG_DFL
 All signals have a default action. See page 292 fig
10.1
Signal Function
void (*signal(int signo, void (*func)(int)))(int);
OR
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
 signo is the signal number to handle
 func defines how to handle the signal
 SIG_IGN
 SIG_DFL
 Function pointer of a custom handler
 Returns previous disposition if ok, or
SIG_ERR on error
Unreliable Signals
 In older versions of UNIX, signals could
be lost and the process would never
know
 Processes had little control over signals.
It could catch or ignore the signal
 Sometimes we want to temporarily
block signals and process them later to
protect a critical section of code
Reentrant Functions
 Reentrant functions can be interrupted at any
point and resumed later without error
 Reentrant functions are thread and signal
safe
 If the signal handler is reentrant and does not
call exit then when it finishes, the process will
continue where it was interrupted without
error
 Page 306 lists functions guaranteed by
POSIX.1 to be reentrant
Reliable-Signal Terminology
and Semantics
 A signal is said to be generated or raised
for a process when an event happens that
causes the signal to occur
 A signal is delivered to a process when it
takes action based on that signal
 During the time between generation and
delivery, a signal is said to be pending
 A process may block some signals using a
signal mask that defines which signals are
currently blocked for the process
kill and raise functions
int kill(pid_t pid, int sig);
int raise(int sig);

 kill sends a signal to a process or group of processes


 pid > 0 – send to process with PID = pid
 pid = 0 – send to all processes with PGID = PGID of caller
 pid < 0 – send to all processes with PGID = |pid|
 To send signals to other processes, EUID must match

 raise allows a process to send a signal to itself


alarm and pause
unsigned int alarm(unsigned int seconds);
 Sets a timer in clock seconds (not exact)

 When time is up, SIGALRM is sent to the process.

Default action is to terminate the process


 Only 1 alarm per process

 Returns
 0 if no previous alarm set, or if previous alarm had less than
1 second left
 Number of seconds left before alarm
 alarm(0) cancels any pending alarms
alarm and pause
int pause(void);
 Suspends a process until it receives a signal

 Returns -1 with errno set to EINTR

 Can use alarm and pause to put a process to

sleep for a specified amount of time


 Note: we must set the handler for SIGALRM

before calling alarm or a race condition can


occur that may result in program termination
(default action for SIGALRM)
POSIX Signal APIs
 A type is defined to hold a set of signals
sigset_t
 5 functions to manipulate a signal set
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
sigprocmask function
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
 If oldset is not NULL, it points to the previous
signal set for this process
 If set is NULL, current mask is unchanged
and how parameter is ignored
 If set is not NULL, then how specifies how the
current mask is modified by set
 SIG_BLOCK - signals in set are added to mask
 SIG_UNBLOCK – signals in set are removed
 SIG_MASK – mask is replaced by set
sigaction function
int sigaction(int signum, const struct sigaction
*act, struct sigaction *oldact);
struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;

}
sigaction function
 sa_flags
 SA_RESETHAND or SA_ONESHOT. Resets
the handler to the default after it has been
executed once
 SA_RESTART. Restarts system calls if they
were interrupted by this signal
 See page 326 for full list of flags
sigpending function
int sigpending(sigset_t *set);
 Returns set of pending signals that are

blocked for this process


 Returns 0 if ok, -1 on error
sigsuspend function
 Provides an atomic way to unblock a
signal and then wait for it to occur
int sigsuspend(const sigset_t *mask);
 Sets the signal mask to mask and then
suspends the processes until a signal
occurs
 Returns -1 with errno set to EINTR
abort function
void abort(void);
 Causes the process to terminate and

generates a core file


 Sends SIGABRT to the process. If the

handler doesn’t terminate the process


when it returns abort itself will
strsignal function
char *strsignal(int sig);
 Given a signal number, returns a string

representation of it

You might also like