Overview Last Week: ● How to program UNIX processes (Chapters 7-9) ● fork() and exec() Unix System Programming This Week, and next week: ● UNIX inter-process communication mechanisms: signals, Signals » (next week) pipes and FIFOs. ● How to program with UNIX signals (Chapter 10) » http://en.wikipedia.org/wiki/Unix_signal ● Non-local jumps (Chapter 7) ● Focus on the sigaction() function 1 2 Maria Hybinette, UGA Maria Hybinette, UGA Outline What is a Signal? ● A signal is an asynchronous event which is delivered to a process (instantiated by a small ● What is a UNIX signal? message) ● Signal types ● Asynchronous means that the event can occur ● Generating signals at any time (e.g., posting at a bulletin board ) ● Responding to a signal » may be unrelated to the execution of the process ● Common uses of a signal – e.g., user types Ctrl-C , or the modem hangs ( SIGINT ) – e.g,, user types Ctrl-Z ( SIGTSTP ) ● Implementing a read() time-out ● Sent from kernel (e.g. detects divide by zero ● Non-local jumps setjmp()/longjmp() ( SIGFPE ) or could be at the request of another ● POSIX signals process to send to another) ● Interrupted system calls ● Only information that a signal carries is its ● System calls inside handlers unique ID and that it arrived 3 4 Maria Hybinette, UGA Maria Hybinette, UGA Signal Types (31 in POSIX) Signal Sources terminal memory ID Name Description Default Action driver management shell command Ctr-C 2 SIGINT Interrupt from keyboard ( ^C ) terminate SIGINT SIGHUP Quit from keyboard ( ^\ ) terminate & core 3 SIGQUIT SIGSEGV 9 SIGKILL kill -9 terminate kernelsig SIGKILL,SIGCONT SIGPIPE 11 SIGSEGV Invalid memory reference terminate & core alarm() clock � rings � terminate 14 SIGALRM SIGWINCH SIGALRM Child stopped or terminated ! ignore 17 SIGCHLD Terminal, window 16 SIGUSR1 user-defined signal type terminate manager a process SIGUSR1 ● /usr/include/sys/iso/signal_iso.h on atlas (solaris) other user ● /usr/src/kernels/2.6.32-431.29.*/include/linux/signal.h SIGFPE processes ● /usr/include/signal.h (user space) ! 5 6 Running a.out process (division by 0, floating point exception) Maria Hybinette, UGA Maria Hybinette, UGA
Generating a Signal kill() ● Use the UNIX command: {saffron} ./fork_example {saffron} kill -KILL 6676 #include <signal.h> Terminating Parent, PID = 6675 int kill( pid_t pid, int signo ); » sends a SIGKILL signal to Running Child, PID = 6676 {saffron} ps processor ID ( pid) 6676 PID TTY TIME CMD ● Send a signal to a process (or group of processes). 6585 ttyp9 00:00:00 tcsh » check pid via (and also to 6676 ttyp9 00:00:06 fork_example ● Return 0 if ok, -1 on error. make sure it died) {saffron} kill –s 9 6676 {saffron} ps {saffron} ps -l PID TTY TIME CMD ● pid Meaning 6585 ttyp9 00:00:00 tcsh 6678 ttyp9 00:00:00 ps > 0 send signal to process pid ● kill is not a good name; send signal to all processes == 0 send_signal might be whose process group ID better. equals the sender � s pgid . e.g. parent kills all children ● How do we do this in a program? 7 8 Maria Hybinette, UGA Maria Hybinette, UGA Responding to a Signal signal() #include <signal.h> After receiving a signal a process can: ● 1. Ignore/Discard/Block out the signal (not possible with void (*signal( int signo, void (*func)(int) ))(int); SIGKILL or SIGSTOP ) 2. Catch the signal; execute a signal handler function, and typedef void Sigfunc( int ); /* Plauger 1992 definition */ then possibly resume execution or terminate Sigfunc *signal( int signo, Sigfunc *handler ); 3. Carry out the default action for that signal ● Signal returns a pointer to a function that returns an int (i.e. it The choice is called the process �� signal returns a pointer to Sigfunc ) ● disposition ● Specify a signal handler function to deal with a signal type. ● Returns previous signal disposition if OK, SIG_ERR on error. How is a process � disposition set? ● 9 10 Maria Hybinette, UGA Maria Hybinette, UGA Sketch on how to program with 5. signal returns a pointer 4. The handler 2. The signal to be to a function. function signals Actual Prototype caught or ignored The return type is the same Receives a single is given as argument as the function that is passed integer signo in, argument and i.e., a function that takes an returns void ● The actual prototype, listed in the � man � page is a bit int main() int and returns a void perplexing but is an expansion of the Sigfunc type: { signal( SIGINT, foo ); : void (*signal( int signo, void (*handler)(int)))(int); /* do usual things until SIGINT */ return 0; ● signal returns a pointer to the previous signal handler } void foo( int signo ) 3. The function to be { 6. The returned #include <signal.h> called when the : /* deal with SIGINT signal */ 1. signal takes two function typedef void Sigfunc(int); /* Plauger 1992 */ specified signal is arguments: takes a integer Sigfunc *signal( int signo, Sigfunc *handler ); received is given as signo and handler parameter. return; /* return to program */ a pointer to the } function handler 11 12 Maria Hybinette, UGA Maria Hybinette, UGA
External Signal Example: signal_example.c {saffron:ingrid:54} signal_example #include <stdio.h> int main( void ) 0: Received SIGUSR1 #include <signal.h> { 1: Received SIGUSR1 2: Received SIGUSR2 #include <unistd.h> int i = 0; [1] + Stopped (signal) if( signal( SIGUSR1, sig_usr ) == SIG_ERR ) signal_example static void sig_usr( int signo ) perror( "Cannot catch SIGUSR1\n" ); {saffron:ingrid:26} fg signal_example { if( signal( SIGUSR2, sig_usr ) == SIG_ERR ) 3: Received SIGUSR1 if( signo == SIGUSR1 ) perror( "Cannot catch SIGUSR2\n" ); Quit printf( "Received SIGUSR1\n" ); else if( signo == SIGUSR2 ) while( 1 ) printf( "Received SIGUSR2\n" ); { {saffron:ingrid:55} kill -l= else printf( "%d: ", i ); {saffron:ingrid:56} ps -l { pause(); /* until signal handler fprintf( stderr, "ERROR: received signal %d\n", signo ); has processed signal */ {saffron:ingrid:23} kill -USR1 1255 exit(1); i++; {saffron:ingrid:24} kill -USR1 1255 } } {saffron:ingrid:25} kill -USR2 1255 {saffron:ingrid:26} kill -STOP 1255 return; return 0; ps –u {saffron:ingrid:27} kill -CONT 1255 } } {saffron:ingrid:28} kill -USR1 1255 kill -SIGUSR2 21084 {saffron:ingrid:29} kill QUIT 1255 13 14 Maria Hybinette, UGA Maria Hybinette, UGA Internal Signal Example: Special Sigfunc * Values signal_example2.c #include <stdio.h> int main( void ) #include <signal.h> { ● Value Meaning #include <unistd.h> int i = 0; if( signal( SIGALRM, handler ) == SIG_ERR ) int beeps = 0; perror( "Cannot catch SIGALRM\n" ); Ignore / discard the signal. alarm(1); SIG_IGN static void handler( int signo ) while( 1 ) { { Use default action to handle signal. SIG_DFL printf( "BEEP\n" ); printf( "%d: ", i ); fflush(stdout); pause(); i++; } Returned by signal() as an error. SIG_ERR if( ++beeps < 5 ) return 0; } alarm(1); else { {cinnamon} signal_example2 printf("BOOM!\n"); 0: BEEP exit(0); 1: BEEP } 2: BEEP 3: BEEP return; } 4: BEEP BOOM! 15 16 Maria Hybinette, UGA Maria Hybinette, UGA Multiple Signals pause() ● If many signals of the same type are waiting to #include <unistd.h> be handled (e.g. two SIGINT s), then most UNIXs int pause(void); will only deliver one of them. » the others are thrown away - i.e. pending signals are ● Suspend the calling process until a signal is not queued caught. » for each signal type, just have a single bit indicating ● Returns -1 with errno assigned EINTR . whether or not the signal has occured (Linux assigns it ERESTARTNOHAND ). ● If many signals of different types are waiting to be handled (e.g. a SIGINT , SIGSEGV , SIGUSR1 ), ● pause() only returns after a signal handler they are not delivered in any fixed order. has returned. 17 18 Maria Hybinette, UGA Maria Hybinette, UGA
Recommend
More recommend