github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/src/runtime/cgo/gcc_sigaction.c (about) 1 // Copyright 2016 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 linux,amd64 6 7 #include <errno.h> 8 #include <stddef.h> 9 #include <stdint.h> 10 #include <string.h> 11 #include <signal.h> 12 13 // go_sigaction_t is a C version of the sigactiont struct from 14 // defs_linux_amd64.go. This definition — and its conversion to and from struct 15 // sigaction — are specific to linux/amd64. 16 typedef struct { 17 uintptr_t handler; 18 uint64_t flags; 19 uintptr_t restorer; 20 uint64_t mask; 21 } go_sigaction_t; 22 23 // SA_RESTORER is part of the kernel interface. 24 // This is GNU/Linux i386/amd64 specific. 25 #ifndef SA_RESTORER 26 #define SA_RESTORER 0x4000000 27 #endif 28 29 int32_t 30 x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *oldgoact) { 31 int32_t ret; 32 struct sigaction act; 33 struct sigaction oldact; 34 int i; 35 36 memset(&act, 0, sizeof act); 37 memset(&oldact, 0, sizeof oldact); 38 39 if (goact) { 40 if (goact->flags & SA_SIGINFO) { 41 act.sa_sigaction = (void(*)(int, siginfo_t*, void*))(goact->handler); 42 } else { 43 act.sa_handler = (void(*)(int))(goact->handler); 44 } 45 sigemptyset(&act.sa_mask); 46 for (i = 0; i < 8 * sizeof(goact->mask); i++) { 47 if (goact->mask & ((uint64_t)(1)<<i)) { 48 sigaddset(&act.sa_mask, i+1); 49 } 50 } 51 act.sa_flags = goact->flags & ~SA_RESTORER; 52 } 53 54 ret = sigaction(signum, goact ? &act : NULL, oldgoact ? &oldact : NULL); 55 if (ret == -1) { 56 /* This is what the Go code expects on failure. */ 57 return errno; 58 } 59 60 if (oldgoact) { 61 if (oldact.sa_flags & SA_SIGINFO) { 62 oldgoact->handler = (uintptr_t)(oldact.sa_sigaction); 63 } else { 64 oldgoact->handler = (uintptr_t)(oldact.sa_handler); 65 } 66 oldgoact->mask = 0; 67 for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) { 68 if (sigismember(&act.sa_mask, i+1) == 1) { 69 oldgoact->mask |= (uint64_t)(1)<<i; 70 } 71 } 72 oldgoact->flags = act.sa_flags; 73 } 74 75 return ret; 76 }