--------------------------------------------------------------------------- Signal Handler rules * Only the following signals need to be handled by a program INT, TERM, HUP and after debugging is complete QUIT (core dumps) * When the handler returns, the signal will interupt system calls that can wait, with a EINTR error return. these calls include open, read, write, wait, ioctl, pause, accept The solution is to ``NEVER RETURN FROM A SIGNAL HANDLER'' and either exit the program or do a long jump back to the main loop. Setting a flag violates this rule. * On old systems that do not have `signal blocking' (IE sigvec()) the signal is reset back to the default handler. This means you must reset the signal as the first thing in the signal handler. Even so you can miss some signals, and have your program exit via the default signal handler. * The C library is NOT re-entrent. IE: you can't call some routines from within a signal handler. The following are especally bad to use (if whey are in current use inside the main program. malloc; * Setting SIGCLD to SIG_IGN causes all children of the program to automatically wait on children. NOTE that the parent will however never see the childs return status. * NOTE: the KILL signal (9) can not be catght or blocked and it IS an error to try. --------------------------------------------------------------------------- Setting a signal() * define a bad signal to keep lint from complaining * DO NOT redirect signals that were ignored in the parent (if you can) #define BADSIG (void(*)())-1 /* keep lint from complaining */ static void setsig(sig, funct) /* Only set a signal if it is default, and check error return */ int sig; void (*funct)(); { if( sig = SIGKILL ) return; /* ignore error for KILL signal */ /* sigblock around this ? */ /* ignore sign for a moment while we check on it */ switch ( signal( sig, SIG_IGN ) ) { case SIGBAD: /* signal call errored */ syserr( "signal" ); return; case SIG_IGN: return; /* signal ignored */ case SIG_DFL: break; /* ok replace the signal */ default: /* this should never happen */ fatal("signal is already caught!"); } if ( signal( sig, funct ) == BADSIG ) syserr("signal"); } ---------------------------------------------------------------------------