github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/signal_unix.c (about)

     1  // Copyright 2012 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin dragonfly freebsd linux netbsd openbsd solaris
     6  
     7  #include <sys/time.h>
     8  
     9  #include "runtime.h"
    10  #include "defs.h"
    11  #include "signal_unix.h"
    12  
    13  extern SigTab runtime_sigtab[];
    14  
    15  void
    16  runtime_initsig(void)
    17  {
    18  	int32 i;
    19  	SigTab *t;
    20  
    21  	// First call: basic setup.
    22  	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
    23  		t = &runtime_sigtab[i];
    24  		if((t->flags == 0) || (t->flags & SigDefault))
    25  			continue;
    26  
    27  		// For some signals, we respect an inherited SIG_IGN handler
    28  		// rather than insist on installing our own default handler.
    29  		// Even these signals can be fetched using the os/signal package.
    30  		switch(t->sig) {
    31  		case SIGHUP:
    32  		case SIGINT:
    33  			if(runtime_getsig(i) == GO_SIG_IGN) {
    34  				t->flags = SigNotify | SigIgnored;
    35  				continue;
    36  			}
    37  		}
    38  
    39  		t->flags |= SigHandling;
    40  		runtime_setsig(i, runtime_sighandler, true);
    41  	}
    42  }
    43  
    44  void
    45  runtime_sigenable(uint32 sig)
    46  {
    47  	int32 i;
    48  	SigTab *t;
    49  
    50  	t = nil;
    51  	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
    52  		if(runtime_sigtab[i].sig == (int32)sig) {
    53  			t = &runtime_sigtab[i];
    54  			break;
    55  		}
    56  	}
    57  
    58  	if(t == nil)
    59  		return;
    60  
    61  	if((t->flags & SigNotify) && !(t->flags & SigHandling)) {
    62  		t->flags |= SigHandling;
    63  		if(runtime_getsig(i) == GO_SIG_IGN)
    64  			t->flags |= SigIgnored;
    65  		runtime_setsig(i, runtime_sighandler, true);
    66  	}
    67  }
    68  
    69  void
    70  runtime_sigdisable(uint32 sig)
    71  {
    72  	int32 i;
    73  	SigTab *t;
    74  
    75  	t = nil;
    76  	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
    77  		if(runtime_sigtab[i].sig == (int32)sig) {
    78  			t = &runtime_sigtab[i];
    79  			break;
    80  		}
    81  	}
    82  
    83  	if(t == nil)
    84  		return;
    85  
    86  	if((t->flags & SigNotify) && (t->flags & SigHandling)) {
    87  		t->flags &= ~SigHandling;
    88  		if(t->flags & SigIgnored)
    89  			runtime_setsig(i, GO_SIG_IGN, true);
    90  		else
    91  			runtime_setsig(i, GO_SIG_DFL, true);
    92  	}
    93  }
    94  
    95  void
    96  runtime_sigignore(uint32 sig)
    97  {
    98  	int32 i;
    99  	SigTab *t;
   100  
   101  	t = nil;
   102  	for(i = 0; runtime_sigtab[i].sig != -1; i++) {
   103  		if(runtime_sigtab[i].sig == (int32)sig) {
   104  			t = &runtime_sigtab[i];
   105  			break;
   106  		}
   107  	}
   108  
   109  	if(t == nil)
   110  		return;
   111  
   112  	if((t->flags & SigNotify) != 0) {
   113  		t->flags &= ~SigHandling;
   114  		runtime_setsig(i, GO_SIG_IGN, true);
   115  	}
   116  }
   117  
   118  void
   119  runtime_resetcpuprofiler(int32 hz)
   120  {
   121  	struct itimerval it;
   122  
   123  	runtime_memclr((byte*)&it, sizeof it);
   124  	if(hz == 0) {
   125  		runtime_setitimer(ITIMER_PROF, &it, nil);
   126  	} else {
   127  		it.it_interval.tv_sec = 0;
   128  		it.it_interval.tv_usec = 1000000 / hz;
   129  		it.it_value = it.it_interval;
   130  		runtime_setitimer(ITIMER_PROF, &it, nil);
   131  	}
   132  	runtime_m()->profilehz = hz;
   133  }
   134  
   135  void
   136  os_sigpipe(void)
   137  {
   138  	int32 i;
   139  
   140  	for(i = 0; runtime_sigtab[i].sig != -1; i++)
   141  		if(runtime_sigtab[i].sig == SIGPIPE)
   142  			break;
   143  	runtime_setsig(i, GO_SIG_DFL, false);
   144  	runtime_raise(SIGPIPE);
   145  }
   146  
   147  void
   148  runtime_unblocksignals(void)
   149  {
   150  	sigset_t sigset_none;
   151  	sigemptyset(&sigset_none);
   152  	pthread_sigmask(SIG_SETMASK, &sigset_none, nil);
   153  }
   154  
   155  void
   156  runtime_crash(void)
   157  {
   158  	int32 i;
   159  
   160  #ifdef GOOS_darwin
   161  	// OS X core dumps are linear dumps of the mapped memory,
   162  	// from the first virtual byte to the last, with zeros in the gaps.
   163  	// Because of the way we arrange the address space on 64-bit systems,
   164  	// this means the OS X core file will be >128 GB and even on a zippy
   165  	// workstation can take OS X well over an hour to write (uninterruptible).
   166  	// Save users from making that mistake.
   167  	if(sizeof(void*) == 8)
   168  		return;
   169  #endif
   170  
   171  	runtime_unblocksignals();
   172  	for(i = 0; runtime_sigtab[i].sig != -1; i++)
   173  		if(runtime_sigtab[i].sig == SIGABRT)
   174  			break;
   175  	runtime_setsig(i, GO_SIG_DFL, false);
   176  	runtime_raise(SIGABRT);
   177  }
   178  
   179  void
   180  runtime_raise(int32 sig)
   181  {
   182  	raise(sig);
   183  }