aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/notify.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-10-22 17:12:11 +0000
committerrsc <devnull@localhost>2004-10-22 17:12:11 +0000
commitaa200fe309dbb3292a218bcdf93615738963109a (patch)
tree79a3f77b73e76d3e8ed001c489c16a2ed6b24ebd /src/lib9/notify.c
parent99834d136f84b9ddb216d9e20f22c608f87a3a39 (diff)
downloadplan9port-aa200fe309dbb3292a218bcdf93615738963109a.tar.gz
plan9port-aa200fe309dbb3292a218bcdf93615738963109a.tar.bz2
plan9port-aa200fe309dbb3292a218bcdf93615738963109a.zip
try to avoid calling notify on the "dumb" signals
Diffstat (limited to 'src/lib9/notify.c')
-rw-r--r--src/lib9/notify.c143
1 files changed, 91 insertions, 52 deletions
diff --git a/src/lib9/notify.c b/src/lib9/notify.c
index 7f22e0fa..da075d71 100644
--- a/src/lib9/notify.c
+++ b/src/lib9/notify.c
@@ -8,35 +8,36 @@ extern char *_p9sigstr(int, char*);
static struct {
int sig;
int restart;
+ int dumb;
} sigs[] = {
- SIGHUP, 0,
- SIGINT, 0,
- SIGQUIT, 0,
- SIGILL, 0,
- SIGTRAP, 0,
+ SIGHUP, 0, 0,
+ SIGINT, 0, 0,
+ SIGQUIT, 0, 0,
+ SIGILL, 0, 0,
+ SIGTRAP, 0, 0,
/* SIGABRT, */
#ifdef SIGEMT
- SIGEMT, 0,
+ SIGEMT, 0, 0,
#endif
- SIGFPE, 0,
- SIGBUS, 0,
+ SIGFPE, 0, 0,
+ SIGBUS, 0, 0,
/* SIGSEGV, */
- SIGCHLD, 1,
- SIGSYS, 0,
- SIGPIPE, 0,
- SIGALRM, 0,
- SIGTERM, 0,
- SIGTSTP, 1,
- SIGTTIN, 1,
- SIGTTOU, 1,
- SIGXCPU, 0,
- SIGXFSZ, 0,
- SIGVTALRM, 0,
- SIGUSR1, 0,
- SIGUSR2, 0,
- SIGWINCH, 1,
+ SIGCHLD, 1, 1,
+ SIGSYS, 0, 0,
+ SIGPIPE, 0, 1,
+ SIGALRM, 0, 0,
+ SIGTERM, 0, 0,
+ SIGTSTP, 1, 1,
+ SIGTTIN, 1, 1,
+ SIGTTOU, 1, 1,
+ SIGXCPU, 0, 0,
+ SIGXFSZ, 0, 0,
+ SIGVTALRM, 0, 0,
+ SIGUSR1, 0, 0,
+ SIGUSR2, 0, 0,
+ SIGWINCH, 1, 1,
#ifdef SIGINFO
- SIGINFO, 0,
+ SIGINFO, 0, 0,
#endif
};
@@ -56,6 +57,13 @@ getonejmp(void)
Jmp *(*_notejmpbuf)(void) = getonejmp;
static void (*notifyf)(void*, char*);
+static int alldumb;
+
+static void
+nop(int sig)
+{
+ USED(sig);
+}
static void
notifysigf(int sig)
@@ -85,40 +93,71 @@ noted(int v)
return 0;
}
-int
-notify(void (*f)(void*, char*))
+static void
+handlesig(int s, int r, int skip)
{
- int i;
struct sigaction sa, osa;
+ /*
+ * If someone has already installed a handler,
+ * It's probably some ld preload nonsense,
+ * like pct (a SIGVTALRM-based profiler).
+ * Leave it alone.
+ */
+ sigaction(s, nil, &osa);
+ if(osa.sa_handler != SIG_DFL && osa.sa_handler != notifysigf && osa.sa_handler != nop)
+ return;
+
memset(&sa, 0, sizeof sa);
- if(f == 0)
+ if(skip)
+ sa.sa_handler = nop;
+ else if(notifyf == 0)
sa.sa_handler = SIG_DFL;
- else{
- notifyf = f;
+ else
sa.sa_handler = notifysigf;
- }
- for(i=0; i<nelem(sigs); i++){
- /*
- * If someone has already installed a handler,
- * It's probably some ld preload nonsense,
- * like pct (a SIGVTALRM-based profiler).
- * Leave it alone.
- */
- sigaction(sigs[i].sig, nil, &osa);
- if(osa.sa_handler != SIG_DFL)
- continue;
- /*
- * We assume that one jump buffer per thread
- * is okay, which means that we can't deal with
- * signal handlers called during signal handlers.
- */
- sigfillset(&sa.sa_mask);
- if(sigs[i].restart)
- sa.sa_flags |= SA_RESTART;
- else
- sa.sa_flags &= ~SA_RESTART;
- sigaction(sigs[i].sig, &sa, nil);
- }
+
+ /*
+ * We assume that one jump buffer per thread
+ * is okay, which means that we can't deal with
+ * signal handlers called during signal handlers.
+ */
+ sigfillset(&sa.sa_mask);
+ if(r)
+ sa.sa_flags |= SA_RESTART;
+ else
+ sa.sa_flags &= ~SA_RESTART;
+ sigaction(s, &sa, nil);
+}
+
+int
+notify(void (*f)(void*, char*))
+{
+ int i;
+
+ notifyf = f;
+ for(i=0; i<nelem(sigs); i++)
+ handlesig(sigs[i].sig, sigs[i].restart, sigs[i].dumb && !alldumb);
return 0;
}
+
+void
+notifyall(int all)
+{
+ int i;
+
+ alldumb = all;
+ for(i=0; i<nelem(sigs); i++)
+ if(sigs[i].dumb)
+ handlesig(sigs[i].sig, sigs[i].restart, !all);
+}
+
+void
+notifyatsig(int sig, int use)
+{
+ int i;
+
+ for(i=0; i<nelem(sigs); i++)
+ if(sigs[i].sig == sig)
+ handlesig(sigs[i].sig, sigs[i].restart, 0);
+}
+