Transcript Signals

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 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 kill function call int kill(pid_t pid, int sig); Software can generate signals  SIGALRM, SIGPIPE, etc pid 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 func   is the signal number to handle 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 If If    oldset signal set for this process set and set how is not NULL, it points to the previous is NULL, current mask is unchanged parameter is ignored is not NULL, then how current mask is modified by specifies how the set SIG_BLOCK - signals in set SIG_UNBLOCK – signals in are added to mask 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 occurs mask and then suspends the processes until a signal  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