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