#include #include #include #include #include #define NODEFINE #include #include #include #include "sig.h" static void pm_sigaction(int, siginfo_t*, void*); static void installhandler(int i) { struct sigaction act; memset(&act, 0, sizeof act); if(i==SIGCHLD) act.sa_flags |= SA_NOCLDSTOP; if(pm_sigtab[i].handle){ act.sa_sigaction = pm_sigaction; act.sa_flags |= SA_SIGINFO; }else act.sa_handler = SIG_DFL; sigaction(i, &act, nil); siginterrupt(i, !pm_sigtab[i].restart); } static void installhandlers(void) { int i; for(i=0; i= pm_nsigtab){ if(pm_debug & PmDebugNote) pm_fprint(2, "pm_sigaction: got bad signal %d\n", sig); pm_abort(); } up = pm_getup(); up->sigres = -1; if(pm_debug & PmDebugNote) pm_fprint(2, "pm_sigaction: got signal %d (%s), calling handler\n", sig, pm_sigtab[sig].desc); if(_setjmp(up->sigbuf)==0) (*notifyf)(nil, pm_sigtab[sig].desc); switch(up->sigres){ default: if(pm_debug & PmDebugNote) pm_fprint(2, "pm_sigaction: handler didn't call noted\n"); pm_abort(); case PM_NCONT: if(pm_debug & PmDebugNote) pm_fprint(2, "pm_sigaction: handler NCONT\n"); return; case PM_NDFLT: if(pm_debug & PmDebugNote) pm_fprint(2, "pm_sigaction: handler NDFLT\n"); break; } /* default handling */ switch(sig){ case SIGURG: case SIGSTOP: case SIGTSTP: case SIGCONT: case SIGCHLD: case SIGTTIN: case SIGTTOU: case SIGIO: case SIGWINCH: case SIGINFO: if(pm_debug & PmDebugNote) pm_fprint(2, "pm_sigaction: ignoring signal\n"); return; } if(pm_debug & PmDebugNote) pm_fprint(2, "pm_sigaction: unhandled signal, dying\n"); for(i=0; isigres = res; _longjmp(up->sigbuf, 1); abort(); return -1; } void pm_notejmp(void *arg, pm_jmp_buf jb, int val) { USED(arg); siglongjmp(jb, val); } void pm_longjmp(pm_jmp_buf jb, int val) { siglongjmp(jb, val); } int pm_notify(void (*fn)(void*, char*)) { if(fn == nil) fn = default_notify; notifyf = fn; return 0; }