diff options
Diffstat (limited to 'src/lib9/notify.c')
-rw-r--r-- | src/lib9/notify.c | 297 |
1 files changed, 0 insertions, 297 deletions
diff --git a/src/lib9/notify.c b/src/lib9/notify.c deleted file mode 100644 index 84999b887..000000000 --- a/src/lib9/notify.c +++ /dev/null @@ -1,297 +0,0 @@ -/* -Plan 9 from User Space src/lib9/notify.c -http://code.swtch.com/plan9port/src/tip/src/lib9/notify.c - -Copyright 2001-2007 Russ Cox. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -/* - * Signal handling for Plan 9 programs. - * We stubbornly use the strings from Plan 9 instead - * of the enumerated Unix constants. - * There are some weird translations. In particular, - * a "kill" note is the same as SIGTERM in Unix. - * There is no equivalent note to Unix's SIGKILL, since - * it's not a deliverable signal anyway. - * - * We do not handle SIGABRT or SIGSEGV, mainly because - * the thread library queues its notes for later, and we want - * to dump core with the state at time of delivery. - * - * We have to add some extra entry points to provide the - * ability to tweak which signals are deliverable and which - * are acted upon. Notifydisable and notifyenable play with - * the process signal mask. Notifyignore enables the signal - * but will not call notifyf when it comes in. This is occasionally - * useful. - */ - -#include <u.h> -#include <signal.h> -#define NOPLAN9DEFINES -#include <libc.h> - -extern char *_p9sigstr(int, char*); -extern int _p9strsig(char*); - -typedef struct Sig Sig; -struct Sig -{ - int sig; /* signal number */ - int flags; -}; - -enum -{ - Restart = 1<<0, - Ignore = 1<<1 -}; - -static Sig sigs[] = { - SIGHUP, 0, - SIGINT, 0, - SIGQUIT, 0, - SIGILL, 0, - SIGTRAP, 0, -/* SIGABRT, 0, */ -#ifdef SIGEMT - SIGEMT, 0, -#endif - SIGFPE, 0, - SIGBUS, 0, -/* SIGSEGV, 0, */ - SIGCHLD, Restart|Ignore, - SIGSYS, 0, - SIGPIPE, Ignore, - SIGALRM, 0, - SIGTERM, 0, - SIGTSTP, Restart|Ignore, -/* SIGTTIN, Restart|Ignore, */ -/* SIGTTOU, Restart|Ignore, */ - SIGXCPU, 0, - SIGXFSZ, 0, - SIGVTALRM, 0, - SIGUSR1, 0, - SIGUSR2, 0, -#ifdef SIGWINCH - SIGWINCH, Restart|Ignore, -#endif -#ifdef SIGINFO - SIGINFO, Restart|Ignore, -#endif -}; - -static Sig* -findsig(int s) -{ - int i; - - for(i=0; i<nelem(sigs); i++) - if(sigs[i].sig == s) - return &sigs[i]; - return nil; -} - -/* - * The thread library initializes _notejmpbuf to its own - * routine which provides a per-pthread jump buffer. - * If we're not using the thread library, we assume we are - * single-threaded. - */ -typedef struct Jmp Jmp; -struct Jmp -{ - p9jmp_buf b; -}; - -static Jmp onejmp; - -static Jmp* -getonejmp(void) -{ - return &onejmp; -} - -Jmp *(*_notejmpbuf)(void) = getonejmp; -static void noteinit(void); - -/* - * Actual signal handler. - */ - -static void (*notifyf)(void*, char*); /* Plan 9 handler */ - -static void -signotify(int sig) -{ - char tmp[64]; - Jmp *j; - Sig *s; - - j = (*_notejmpbuf)(); - switch(p9setjmp(j->b)){ - case 0: - if(notifyf) - (*notifyf)(nil, _p9sigstr(sig, tmp)); - /* fall through */ - case 1: /* noted(NDFLT) */ - if(0)print("DEFAULT %d\n", sig); - s = findsig(sig); - if(s && (s->flags&Ignore)) - return; - signal(sig, SIG_DFL); - raise(sig); - _exit(1); - case 2: /* noted(NCONT) */ - if(0)print("HANDLED %d\n", sig); - return; - } -} - -static void -signonotify(int sig) -{ - USED(sig); -} - -int -noted(int v) -{ - p9longjmp((*_notejmpbuf)()->b, v==NCONT ? 2 : 1); - abort(); - return 0; -} - -int -notify(void (*f)(void*, char*)) -{ - static int init; - - notifyf = f; - if(!init){ - init = 1; - noteinit(); - } - return 0; -} - -/* - * Nonsense about enabling and disabling signals. - */ -typedef void Sighandler(int); -static Sighandler* -handler(int s) -{ - struct sigaction sa; - - sigaction(s, nil, &sa); - return sa.sa_handler; -} - -static int -notesetenable(int sig, int enabled) -{ - sigset_t mask, omask; - - if(sig == 0) - return -1; - - sigemptyset(&mask); - sigaddset(&mask, sig); - sigprocmask(enabled ? SIG_UNBLOCK : SIG_BLOCK, &mask, &omask); - return !sigismember(&omask, sig); -} - -int -noteenable(char *msg) -{ - return notesetenable(_p9strsig(msg), 1); -} - -int -notedisable(char *msg) -{ - return notesetenable(_p9strsig(msg), 0); -} - -static int -notifyseton(int s, int on) -{ - Sig *sig; - struct sigaction sa, osa; - - sig = findsig(s); - if(sig == nil) - return -1; - memset(&sa, 0, sizeof sa); - sa.sa_handler = on ? signotify : signonotify; - if(sig->flags&Restart) - sa.sa_flags |= SA_RESTART; - - /* - * We can't allow signals within signals because there's - * only one jump buffer. - */ - sigfillset(&sa.sa_mask); - - /* - * Install handler. - */ - sigaction(sig->sig, &sa, &osa); - return osa.sa_handler == signotify; -} - -int -notifyon(char *msg) -{ - return notifyseton(_p9strsig(msg), 1); -} - -int -notifyoff(char *msg) -{ - return notifyseton(_p9strsig(msg), 0); -} - -/* - * Initialization follows sigs table. - */ -static void -noteinit(void) -{ - int i; - Sig *sig; - - for(i=0; i<nelem(sigs); i++){ - sig = &sigs[i]; - /* - * If someone has already installed a handler, - * It's probably some ld preload nonsense, - * like pct (a SIGVTALRM-based profiler). - * Or maybe someone has already called notifyon/notifyoff. - * Leave it alone. - */ - if(handler(sig->sig) != SIG_DFL) - continue; - notifyseton(sig->sig, 1); - } -} - |