diff options
Diffstat (limited to 'src/pkg/runtime/signal_unix.c')
-rw-r--r-- | src/pkg/runtime/signal_unix.c | 72 |
1 files changed, 61 insertions, 11 deletions
diff --git a/src/pkg/runtime/signal_unix.c b/src/pkg/runtime/signal_unix.c index 9b7e8b03a..54e461f99 100644 --- a/src/pkg/runtime/signal_unix.c +++ b/src/pkg/runtime/signal_unix.c @@ -7,6 +7,7 @@ #include "runtime.h" #include "defs_GOOS_GOARCH.h" #include "os_GOOS.h" +#include "signal_unix.h" extern SigTab runtime·sigtab[]; @@ -21,6 +22,20 @@ runtime·initsig(void) t = &runtime·sigtab[i]; if((t->flags == 0) || (t->flags & SigDefault)) continue; + + // For some signals, we respect an inherited SIG_IGN handler + // rather than insist on installing our own default handler. + // Even these signals can be fetched using the os/signal package. + switch(i) { + case SIGHUP: + case SIGINT: + if(runtime·getsig(i) == SIG_IGN) { + t->flags = SigNotify | SigIgnored; + continue; + } + } + + t->flags |= SigHandling; runtime·setsig(i, runtime·sighandler, true); } } @@ -28,18 +43,35 @@ runtime·initsig(void) void runtime·sigenable(uint32 sig) { - int32 i; SigTab *t; - for(i = 0; i<NSIG; i++) { - // ~0 means all signals. - if(~sig == 0 || i == sig) { - t = &runtime·sigtab[i]; - if(t->flags & SigDefault) { - runtime·setsig(i, runtime·sighandler, true); - t->flags &= ~SigDefault; // make this idempotent - } - } + if(sig >= NSIG) + return; + + t = &runtime·sigtab[sig]; + if((t->flags & SigNotify) && !(t->flags & SigHandling)) { + t->flags |= SigHandling; + if(runtime·getsig(sig) == SIG_IGN) + t->flags |= SigIgnored; + runtime·setsig(sig, runtime·sighandler, true); + } +} + +void +runtime·sigdisable(uint32 sig) +{ + SigTab *t; + + if(sig >= NSIG) + return; + + t = &runtime·sigtab[sig]; + if((t->flags & SigNotify) && (t->flags & SigHandling)) { + t->flags &= ~SigHandling; + if(t->flags & SigIgnored) + runtime·setsig(sig, SIG_IGN, true); + else + runtime·setsig(sig, SIG_DFL, true); } } @@ -66,5 +98,23 @@ void os·sigpipe(void) { runtime·setsig(SIGPIPE, SIG_DFL, false); - runtime·raisesigpipe(); + runtime·raise(SIGPIPE); +} + +void +runtime·crash(void) +{ +#ifdef GOOS_darwin + // OS X core dumps are linear dumps of the mapped memory, + // from the first virtual byte to the last, with zeros in the gaps. + // Because of the way we arrange the address space on 64-bit systems, + // this means the OS X core file will be >128 GB and even on a zippy + // workstation can take OS X well over an hour to write (uninterruptible). + // Save users from making that mistake. + if(sizeof(void*) == 8) + return; +#endif + + runtime·setsig(SIGABRT, SIG_DFL, false); + runtime·raise(SIGABRT); } |