Linux Signals
Linux Signals
Process 4387
Process 4134
Signal
A signal is an event generated by Linux in response to some condition, which may cause a process to take some action when it receives the signal. Raise is the term that indicates the generation of a signal Catch is the term to indicate the receipt of a signal
Raising a signal
A signal may be generated by a shell and terminal handlers to cause interrupts A signal may be explicitly sent by one process to another
14 15 30,10,16 31,12,17
SIGTTOU
22,22,27
Stop
In general, if a process receives a signal without first arranging to catch it, the process will be terminated The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored. SIGCHILD is ignored by default SIGCONT causes a process to resume
A foreground process can be sent the SIGINT signal by typing Ctrl-C A background process can be sent a signal via the kill command: $ kill -SIGKILL 3021 $ kill -SIGALRM 3456
Handling a signal
An integer signal to be caught or ignored The function to be called when the specific signal is received.
Sending signals
A process may send a signal to another process via the kill system call: #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig);
The alarm function can be used by a process to schedule a SIG_ALRM signal at a point the future #include <unistd.h> unsigned int alarm(unsigned int secs);
alarm.c
#include #include #include #include <sys/types.h> <signal.h> <stdio.h> <unistd.h>
static int alarm_fired = 0; void ding(int sig) { alarm_fired = 1; } int main() { int pid; printf("alarm application starting\n");
alarm.c
/* child: wait 5 sec, send SIGALRM to parent */ if((pid = fork()) == 0) { sleep(5); kill(getppid(), SIGALRM); exit(0); } /* parent: set signal hander, wait for alarm */ printf("waiting for alarm to go off\n"); (void) signal(SIGALRM, ding); pause(); /* suspend execution until signaled */ if (alarm_fired) printf("Ding!\n"); printf("done\n"); exit(0); }
X/Open specification recommends a more robust programming interface for signals: int sigaction( int sig, const struct sigaction *act, struct sigaction *oact);
struct sigaction
sa_handler is a function, SIG_DFL, or SIG_IGN sa_mask specifies signals that are blocked (not sent to sa_handler) If sa_flags = SA_RESETHAND, handlers are set to default once this handler is called
sigaction, again
int sigaction( int sig, const struct sigaction *act, struct sigaction *oact);
If oact NULL, write previous signal action to location specified by oact If act NULL, the action for the specified signal is set.
ctrlc2.c
#include <signal.h> #include <stdio.h> #include <unistd.h> void ouch(int sig) { printf("OUCH! - I got signal %d\n", sig); }
ctrlc2.c
int main() { struct sigaction act; act.sa_handler = ouch; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGINT, &act, 0); while(1) { printf("Hello World!\n"); sleep(1); } }
ctrlc2.c
[mike@localhost chapter11]$ ctrlc2 Hello World! OUCH! - I got signal 2 (I pressed Ctrl-C) Hello World! OUCH! - I got signal 2 (I pressed Ctrl-C) Hello World! Hello World! Hello World! (I pressed Ctrl-Z) [2]+ Stopped ctrlc2 [mike@localhost chapter11]$
sigaction
For more information about sigaction, consult pp. 470 476 of your text, as well as the man pages for sigaction.
Many Linux system calls are interruptiblewhen they receive a signal they will return with an error Certain system calls are considered to be unsafe when they are called from within a signal handler. System call functions that are considered to be safe when called from a signal handler are listed on page 474 of your text.