380 likes | 564 Views
Signals Overview. A signal is an event generated by the UNIX system in response to some condition. Upon receipt of a signal a process may take some action. Signal generation: by error conditions (memory segment violations, floating point processor errors, illegal instructions)
E N D
Signals Overview • A signal is an event generated by the UNIX system in response to some condition. • Upon receipt of a signal a process may take some action. • Signal generation: • by error conditions (memory segment violations, floating point processor errors, illegal instructions) • by shell and terminal handlers • by one process to another to send information • In all cases, programming interface is same. Applied Operating System Concepts
Signal names • Must include signal.h • All signal names begin with “SIG” • Linux supports all POSIX.1 signals as well as other signals • To get a list of all Linux supported signals do: man -S 7 signal Applied Operating System Concepts
Signal Names (POSIX.1) This signal can’t be caught! Applied Operating System Concepts
Signals (POSIX.1) • If a process receives one of these signals without first arranging to catch it, the process will be terminated (with extreme prejudice) • Signals marked with a ‘*’ will take implementation-dependent action • usually a core dump Applied Operating System Concepts
Additional Signals (POSIX.1) Yes, the last signal is SIGTTOU and not SITTOUT Applied Operating System Concepts
Additional Signals • SIGCHLD can be used to manage child processes. • ignored by default • Remaining signals cause the process receiving them to stop • except SIGCONT which causes the receiving process to resume. • These additional signals are used by shell programs for job control. • rarely used by user programs. Applied Operating System Concepts
non-POSIX.1 Signals • SIGVTALRM and SIGPROF used by timers. Applied Operating System Concepts
Sending Signals at the command line • Interrupt character (ctrl-C) causes the SIGINT signal to be sent to the foreground process. • normally causes the process to terminate • To send a signal to a process other than the current foreground process use the kill command. • takes an optional signal number or name • also takes the PID of the receiving process (usually get via ps) kill -HUP 512 this sends the hangup command (SIGHUP) to process 512 Applied Operating System Concepts
Sending Signals at the command line • killall command allows you to send a signal to all processes running a specified command. • Not supported by all UNIX versions; Linux does support. • Useful when don’t know PID • Also useful to signal several processes running the same command • Common use: to tell the inetd program to re-read it’s configuration options: killall -HUP inetd Applied Operating System Concepts
Signal Handling • How does a process capture a signal? • Can use the system call signal to define a function (that already exists in your program) that will capture a specific signal • Can also use the system call sigaction to define a function (that already exists in your program) that will capture a specific signal Applied Operating System Concepts
The signal function itself returns a pointer to a function. The return type is the same as the function that is passed in, i.e., a function that takes an int and returns a void The signal to be caught or ignored is given as argument sig The func function receives a single integer argument and returns void The function to be called when the specified signal is received is given as a pointer to the function func Signal is a function that takes two arguments: sig and func The returned function takes a integer parameter. Signal Handling • Use the signal handling library: signal.h • Then can use the signal call: #include <signal.h> void (*signal (int sig, void (*func)(int))) (int); Applied Operating System Concepts
Signal Handling • The signal function returns a function of the same type • i.e., it returns a function that takes an int and returns a void • The function returned is the previous value of the function set up to handle the signal. • Note that the default behavior is automatically restored after the specified signal has been caught (if something else is not returned) in some older versions of Linux. • The signal function can take two special values for its second parameter: • SIG_IGN which means ignore the signal from now on. • SIG_DFL which means restore the default behavior for this signal next time. Applied Operating System Concepts
So the second time a SIGINT (ctrl-c) is received, the default behavior (i.e., quit) is done. The SIGINT signal is generated by ctrl-c keystroke The second arg is the name of the function ouch A function name is really a pointer to the function Since function ouch does not return a function or a special constant, the default behavior is implemented after the first call Example #include <signal.h> #include <stdio.h> #include <unistd.h> void ouch(int sig){ printf("OUCH! - I got signal %d\n", sig); } int main(){ (void) signal(SIGINT, ouch); while(1) { printf("Hello World!\n"); sleep(1); } } Applied Operating System Concepts
Other UNIX’s • In some versions of UNIX (e.g., Berkeley derivatives) do not restore default behavior. • To get the default behavior after first call could use line like signal(SIGINT, SIG_DFL); within the function ouch. Applied Operating System Concepts
Signal Handling • If you want the same signal handler to handle the next instance of the signal also, have to call the signal function again. • would have to establish the same signal handler • problem: there is a short period of time between when the signal is handled and the same signal handler is established again. • It’s possible for a second signal to be received in this time and terminate the program! Applied Operating System Concepts
To keep catching the signal with this function, must call the signal system call again. Problem: from the time that the interrupt function starts to just before the signal handler is re-established the signal will not be handled. Signal Handling #include <signal.h> #include <stdio.h> #include <unistd.h> void ouch(int sig){ printf("OUCH! - I got signal %d\n", sig); (void) signal(SIGINT, ouch); } int main(){ (void) signal(SIGINT, ouch); while(1) { printf("Hello World!\n"); sleep(1); } } If another SIGINT signal is received during this time, default behavior will be done, i.e., program will terminate. Applied Operating System Concepts
Signal Raising • Use kill system call to send a signal to another process. #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); Applied Operating System Concepts
Signal Raising • int kill(pid_t pid, int sig); • sends the signal sig to the process with pid pid • returns 0 on success • returns -1 if fails. • Sets errno to EINVAL if signal given is not a valid one • Sets errno to EPERM if sender doesn’t have permission to send • Sets errno to ESRCH if process pid doesn’t exist Applied Operating System Concepts
Signal Raising • int kill(pid_t pid, int sig); • sending process must have permission to send the signal to the pid process • Normally means both processes must have the same user ID • I.e., can only send a signal to one of your own processes. • The supervisor may send signals to any process. Applied Operating System Concepts
Signal Raising • Use alarm system call to schedule a SIGALRM signal at some time in the future. #include <unistd.h> unsigned int alarm(unsigned int seconds); Applied Operating System Concepts
Signal Raising • unsigned int alarm(unsigned int seconds): • Schedules the delivery of a SIGALRM signal in seconds time. • Alarm will probably be delivered shortly after that because of system delays • value of 0 will cancel any outstanding alarm request • calling alarm before the signal is received will cause the alarm to be rescheduled. • Each process may have only one outstanding alarm. • returns the number of seconds left to go before any outstanding alarm call would be sent. Applied Operating System Concepts
Signal Raising #include <signal.h> #include <stdio.h> #include <unistd.h> void ding(int sig) { printf("alarm has gone off\n"); } Applied Operating System Concepts
Child sends alarm to parent Set up signal handler pause system call causes program to suspend until a signal is received. Signal Raising int main() { int pid; printf("alarm application starting\n"); if((pid = fork()) == 0) { sleep(5); kill(getppid(), SIGALRM); exit(0); } printf("waiting for alarm to go off\n"); (void) signal(SIGALRM, ding); pause(); printf("done\n"); exit(0); } Applied Operating System Concepts
Signal Raising • Use pause system call to suspend yourself until a signal occurs #include <unistd.h> int pause(void); • returns -1 if the next received signal doesn’t cause the program to terminate • In this case errno is set to EINTR Applied Operating System Concepts
Signal Raising • Problem with signals: • can cause race conditions • example: call a pause to wait for a signal • if signal occurs before the call to pause then your program may wait indefinitely. Applied Operating System Concepts
A robust signals interface • A robust signals interface:sigaction • POSIX replacement for signal • Specify which signal to handle and how to handle the signal • Can find out the previous settings for that signal Applied Operating System Concepts
A robust signals interface • A robust signals interface #include <signal.h> int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); • where the sigaction structure is used to define the actions to be taken on receipt of the signal specified by sig. • sigaction is defined in signal.h Applied Operating System Concepts
A robust signals interface • struct sigaction is defined in signal.h It has 3 fields: struct sigaction{ void (* sa_handler)( ) // function // or could use this function instead: void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask int sa_flags } • sa-handler is either a function or SIG_DFL or SIG-IGN • Sigaction also accepts a new type of function for sa-handler. • If set SA_SIGINFO bit in sa_flags then can use the second function instead of the third Use one of these two functions in your sigaction struct; can’t use both Applied Operating System Concepts
A robust signals interface int sigaction(int sig, const struct sigaction *act,struct sigaction *oact); • sets the action associated with the signal sig. • If oact is not null, sigaction writes the previous signal action to the location it refers to. • if act is null, this is all sigaction does. • If act is not null, the action for the specified signal is set. Applied Operating System Concepts
A robust signals interface int sigaction(int sig, const struct sigaction *act,struct sigaction *oact); • returns 0 if successful • returns -1 if not • if not successful also sets errno to EINVAL if the specified signal is invalid or if an attempt is made to catch or ignore a signal that can’t be caught or ignored. Applied Operating System Concepts
A robust signals interface int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); • act points to a sigaction struct (which has 3 fields defined earlier) • The sa_handler field of this struct is a pointer to a function called when signal sig is received. • special value SIG_IGN in the sa_handler field means ignore signal • special value SIG_DFL in the sa_handler field means restore default action. Applied Operating System Concepts
A robust signals interface int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); • The bits in thesa_mask field specifies a set of signals to be added to the process’ signal mask before sa_handler function is called. • This set of signals will be blocked and won’t be delivered to the process. • Prevents the race condition that happens with signal call shown earlier. Applied Operating System Concepts
A robust signals interface int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); • signals caught with handlers set bysigactionare by default notreset • Thesa_flagsfield must be set to contain the valueRA_RESETHANDif you want the default behavior restored. • Possible sa_flags values: SA_NOCLDSTOP Don’t generate SIGCHLD when child processes stop SA_RESETHAND Reset signal action to SIG_DFL on receipt SA_RESTART Restart interruptible functions rather than error with EINTR SA_NODEFER Don’t add thesignal to the signal mask when caught Applied Operating System Concepts
A robust signals interface • SA_RESTART • Restart interruptible functions rather than error with EINTR • Many sys calls are interruptable. • When they receive a signal, they will return with an error and errno will be set to EINTR to indicate that the function returned due to a signal. • If SA_RESTART is set then a function that might o.w. be interrupted by a signal will instead be restarted one the signal handling function has bee executed. Applied Operating System Concepts
A robust signals interface • SA_NODEFER • Don’t add thesignal to the signal mask when caught • Ordinarily, when a signal handling function is being executed, the signal received is added to the process signal mask for the duration of the handling function. • This prevents a subsequent occurrence of the same signal • Normally this is good: if code is not re-entrant, another same signal may cause problems. • If SA_NODEFER flag is set, the signal mask is not altered when it receives this signal and another signal may occur • Safe functions (guaranteed by X/Open spec to either be re-enterent or not to raise signals themselves) are listed in the Beginning Linux Programming book. Applied Operating System Concepts
A robust signals interface #include <signal.h> #include <stdio.h> #include <unistd.h> void ouch(int sig) { printf("OUCH! - I got signal %d\n", sig); } Applied Operating System Concepts
struct sigaction{ void (*) (int) sa_handler sigset_t sa_mask int sa_flags } Set the signal handler to be the function ouch No flags are needed here. Possible flags include: SA_NOCLDSTOP SA_RESETHAND SA_RESTART SA_NODEFER We can manipulate sets of signals. We do not need to do this here. See Beginning Linux Programming for details This call sets the signal handler for the SIGINT (ctrl-C) signal A robust signals interface 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); } } Applied Operating System Concepts
A robust signals interface • This function will continually capture the ctrl-C (SIGINT) signal. • Default behavior is not restored after a signal is caught. • To terminate the program, must type ctrl-\, the SIGQUIT signal. Applied Operating System Concepts