try to avoid calling notify on the "dumb" signals

This commit is contained in:
rsc 2004-10-22 17:12:11 +00:00
parent 99834d136f
commit aa200fe309

View file

@ -8,35 +8,36 @@ extern char *_p9sigstr(int, char*);
static struct { static struct {
int sig; int sig;
int restart; int restart;
int dumb;
} sigs[] = { } sigs[] = {
SIGHUP, 0, SIGHUP, 0, 0,
SIGINT, 0, SIGINT, 0, 0,
SIGQUIT, 0, SIGQUIT, 0, 0,
SIGILL, 0, SIGILL, 0, 0,
SIGTRAP, 0, SIGTRAP, 0, 0,
/* SIGABRT, */ /* SIGABRT, */
#ifdef SIGEMT #ifdef SIGEMT
SIGEMT, 0, SIGEMT, 0, 0,
#endif #endif
SIGFPE, 0, SIGFPE, 0, 0,
SIGBUS, 0, SIGBUS, 0, 0,
/* SIGSEGV, */ /* SIGSEGV, */
SIGCHLD, 1, SIGCHLD, 1, 1,
SIGSYS, 0, SIGSYS, 0, 0,
SIGPIPE, 0, SIGPIPE, 0, 1,
SIGALRM, 0, SIGALRM, 0, 0,
SIGTERM, 0, SIGTERM, 0, 0,
SIGTSTP, 1, SIGTSTP, 1, 1,
SIGTTIN, 1, SIGTTIN, 1, 1,
SIGTTOU, 1, SIGTTOU, 1, 1,
SIGXCPU, 0, SIGXCPU, 0, 0,
SIGXFSZ, 0, SIGXFSZ, 0, 0,
SIGVTALRM, 0, SIGVTALRM, 0, 0,
SIGUSR1, 0, SIGUSR1, 0, 0,
SIGUSR2, 0, SIGUSR2, 0, 0,
SIGWINCH, 1, SIGWINCH, 1, 1,
#ifdef SIGINFO #ifdef SIGINFO
SIGINFO, 0, SIGINFO, 0, 0,
#endif #endif
}; };
@ -56,6 +57,13 @@ getonejmp(void)
Jmp *(*_notejmpbuf)(void) = getonejmp; Jmp *(*_notejmpbuf)(void) = getonejmp;
static void (*notifyf)(void*, char*); static void (*notifyf)(void*, char*);
static int alldumb;
static void
nop(int sig)
{
USED(sig);
}
static void static void
notifysigf(int sig) notifysigf(int sig)
@ -85,40 +93,71 @@ noted(int v)
return 0; return 0;
} }
int static void
notify(void (*f)(void*, char*)) handlesig(int s, int r, int skip)
{ {
int i;
struct sigaction sa, osa; struct sigaction sa, osa;
memset(&sa, 0, sizeof sa);
if(f == 0)
sa.sa_handler = SIG_DFL;
else{
notifyf = f;
sa.sa_handler = notifysigf;
}
for(i=0; i<nelem(sigs); i++){
/* /*
* If someone has already installed a handler, * If someone has already installed a handler,
* It's probably some ld preload nonsense, * It's probably some ld preload nonsense,
* like pct (a SIGVTALRM-based profiler). * like pct (a SIGVTALRM-based profiler).
* Leave it alone. * Leave it alone.
*/ */
sigaction(sigs[i].sig, nil, &osa); sigaction(s, nil, &osa);
if(osa.sa_handler != SIG_DFL) if(osa.sa_handler != SIG_DFL && osa.sa_handler != notifysigf && osa.sa_handler != nop)
continue; return;
memset(&sa, 0, sizeof sa);
if(skip)
sa.sa_handler = nop;
else if(notifyf == 0)
sa.sa_handler = SIG_DFL;
else
sa.sa_handler = notifysigf;
/* /*
* We assume that one jump buffer per thread * We assume that one jump buffer per thread
* is okay, which means that we can't deal with * is okay, which means that we can't deal with
* signal handlers called during signal handlers. * signal handlers called during signal handlers.
*/ */
sigfillset(&sa.sa_mask); sigfillset(&sa.sa_mask);
if(sigs[i].restart) if(r)
sa.sa_flags |= SA_RESTART; sa.sa_flags |= SA_RESTART;
else else
sa.sa_flags &= ~SA_RESTART; sa.sa_flags &= ~SA_RESTART;
sigaction(sigs[i].sig, &sa, nil); 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; 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);
}