#include "lib.h" #include "sys9.h" #include #include #include #include extern sigset_t _psigblocked; static struct { char *msg; /* just check prefix */ int num; } sigtab[] = { {"hangup", SIGHUP}, {"interrupt", SIGINT}, {"quit", SIGQUIT}, {"alarm", SIGALRM}, {"sys: trap: illegal instruction", SIGILL}, {"sys: trap: reserved instruction", SIGILL}, {"sys: trap: reserved", SIGILL}, {"sys: trap: arithmetic overflow", SIGFPE}, {"abort", SIGABRT}, {"sys: fp:", SIGFPE}, {"exit", SIGKILL}, {"die", SIGKILL}, {"kill", SIGKILL}, {"sys: trap: bus error", SIGSEGV}, {"sys: trap: address error", SIGSEGV}, {"sys: trap: TLB", SIGSEGV}, {"sys: write on closed pipe", SIGPIPE}, {"alarm", SIGALRM}, {"term", SIGTERM}, {"usr1", SIGUSR1}, {"usr2", SIGUSR2}, }; #define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0]))) void (*_sighdlr[MAXSIG+1])(int, char*, Ureg*); /* 0 initialized: SIG_DFL */ /* consider moving to */ typedef void (*sighandler_t)(int); typedef void (*isighandler_t)(int, char*, Ureg*); void (*signal(int sig, void (*func)(int)))(int) { sighandler_t oldf; if(sig <= 0 || sig > MAXSIG){ errno = EINVAL; return SIG_ERR; } oldf = (sighandler_t)_sighdlr[sig]; if(sig == SIGKILL) return oldf; /* can't catch or ignore SIGKILL */ _sighdlr[sig] = (isighandler_t)func; return oldf; } /* BAD CODE - see /sys/src/ape/lib/ap/$objtype/setjmp.s for real code int sigsetjmp(sigjmp_buf buf, int savemask) { int r; buf[0] = savemask; buf[1] = _psigblocked; return setjmp(&buf[2]); } */ /* * BUG: improper handling of process signal mask */ int sigaction(int sig, struct sigaction *act, struct sigaction *oact) { if(sig <= 0 || sig > MAXSIG || sig == SIGKILL){ errno = EINVAL; return -1; } if(oact){ oact->sa_handler = _sighdlr[sig]; oact->sa_mask = _psigblocked; oact->sa_flags = 0; } if(act){ _sighdlr[sig] = act->sa_handler; } return 0; } /* this is registered in _envsetup */ int _notehandler(void *v, char *msg) { int i; void(*f)(int, char*, Ureg*); Ureg *u; extern void _doatexits(void); /* in stdio/exit.c */ u = v; if(_finishing) _finish(0, 0); for(i = 0; i