|  | // Copyright 2012 The Go Authors.  All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | // +build darwin dragonfly freebsd linux netbsd openbsd solaris | 
|  |  | 
|  | #include <sys/time.h> | 
|  |  | 
|  | #include "runtime.h" | 
|  | #include "defs.h" | 
|  | #include "signal_unix.h" | 
|  |  | 
|  | extern SigTab runtime_sigtab[]; | 
|  |  | 
|  | void | 
|  | runtime_initsig(void) | 
|  | { | 
|  | int32 i; | 
|  | SigTab *t; | 
|  |  | 
|  | // First call: basic setup. | 
|  | for(i = 0; runtime_sigtab[i].sig != -1; i++) { | 
|  | 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(t->sig) { | 
|  | case SIGHUP: | 
|  | case SIGINT: | 
|  | if(runtime_getsig(i) == GO_SIG_IGN) { | 
|  | t->flags = SigNotify | SigIgnored; | 
|  | continue; | 
|  | } | 
|  | } | 
|  |  | 
|  | t->flags |= SigHandling; | 
|  | runtime_setsig(i, runtime_sighandler, true); | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | runtime_sigenable(uint32 sig) | 
|  | { | 
|  | int32 i; | 
|  | SigTab *t; | 
|  |  | 
|  | t = nil; | 
|  | for(i = 0; runtime_sigtab[i].sig != -1; i++) { | 
|  | if(runtime_sigtab[i].sig == (int32)sig) { | 
|  | t = &runtime_sigtab[i]; | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | if(t == nil) | 
|  | return; | 
|  |  | 
|  | if((t->flags & SigNotify) && !(t->flags & SigHandling)) { | 
|  | t->flags |= SigHandling; | 
|  | if(runtime_getsig(i) == GO_SIG_IGN) | 
|  | t->flags |= SigIgnored; | 
|  | runtime_setsig(i, runtime_sighandler, true); | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | runtime_sigdisable(uint32 sig) | 
|  | { | 
|  | int32 i; | 
|  | SigTab *t; | 
|  |  | 
|  | t = nil; | 
|  | for(i = 0; runtime_sigtab[i].sig != -1; i++) { | 
|  | if(runtime_sigtab[i].sig == (int32)sig) { | 
|  | t = &runtime_sigtab[i]; | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | if(t == nil) | 
|  | return; | 
|  |  | 
|  | if((t->flags & SigNotify) && (t->flags & SigHandling)) { | 
|  | t->flags &= ~SigHandling; | 
|  | if(t->flags & SigIgnored) | 
|  | runtime_setsig(i, GO_SIG_IGN, true); | 
|  | else | 
|  | runtime_setsig(i, GO_SIG_DFL, true); | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | runtime_resetcpuprofiler(int32 hz) | 
|  | { | 
|  | struct itimerval it; | 
|  |  | 
|  | runtime_memclr((byte*)&it, sizeof it); | 
|  | if(hz == 0) { | 
|  | runtime_setitimer(ITIMER_PROF, &it, nil); | 
|  | } else { | 
|  | it.it_interval.tv_sec = 0; | 
|  | it.it_interval.tv_usec = 1000000 / hz; | 
|  | it.it_value = it.it_interval; | 
|  | runtime_setitimer(ITIMER_PROF, &it, nil); | 
|  | } | 
|  | runtime_m()->profilehz = hz; | 
|  | } | 
|  |  | 
|  | void | 
|  | os_sigpipe(void) | 
|  | { | 
|  | int32 i; | 
|  |  | 
|  | for(i = 0; runtime_sigtab[i].sig != -1; i++) | 
|  | if(runtime_sigtab[i].sig == SIGPIPE) | 
|  | break; | 
|  | runtime_setsig(i, GO_SIG_DFL, false); | 
|  | runtime_raise(SIGPIPE); | 
|  | } | 
|  |  | 
|  | void | 
|  | runtime_unblocksignals(void) | 
|  | { | 
|  | sigset_t sigset_none; | 
|  | sigemptyset(&sigset_none); | 
|  | pthread_sigmask(SIG_SETMASK, &sigset_none, nil); | 
|  | } | 
|  |  | 
|  | void | 
|  | runtime_crash(void) | 
|  | { | 
|  | int32 i; | 
|  |  | 
|  | #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_unblocksignals(); | 
|  | for(i = 0; runtime_sigtab[i].sig != -1; i++) | 
|  | if(runtime_sigtab[i].sig == SIGABRT) | 
|  | break; | 
|  | runtime_setsig(i, GO_SIG_DFL, false); | 
|  | runtime_raise(SIGABRT); | 
|  | } | 
|  |  | 
|  | void | 
|  | runtime_raise(int32 sig) | 
|  | { | 
|  | raise(sig); | 
|  | } |