github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/cgo/gcc_freebsd_sigaction.c (about) 1 // Copyright 2018 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 freebsd && amd64 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 // os_freebsd.go. This definition — and its conversion to and from struct 17 // sigaction — are specific to freebsd/amd64. 18 typedef struct { 19 uint32_t __bits[_SIG_WORDS]; 20 } go_sigset_t; 21 typedef struct { 22 uintptr_t handler; 23 int32_t flags; 24 go_sigset_t mask; 25 } go_sigaction_t; 26 27 int32_t 28 x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *oldgoact) { 29 int32_t ret; 30 struct sigaction act; 31 struct sigaction oldact; 32 size_t i; 33 34 _cgo_tsan_acquire(); 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.__bits[i/32] & ((uint32_t)(1)<<(i&31))) { 48 sigaddset(&act.sa_mask, i+1); 49 } 50 } 51 act.sa_flags = goact->flags; 52 } 53 54 ret = sigaction(signum, goact ? &act : NULL, oldgoact ? &oldact : NULL); 55 if (ret == -1) { 56 // runtime.sigaction expects _cgo_sigaction to return errno on error. 57 _cgo_tsan_release(); 58 return errno; 59 } 60 61 if (oldgoact) { 62 if (oldact.sa_flags & SA_SIGINFO) { 63 oldgoact->handler = (uintptr_t)(oldact.sa_sigaction); 64 } else { 65 oldgoact->handler = (uintptr_t)(oldact.sa_handler); 66 } 67 for (i = 0 ; i < _SIG_WORDS; i++) { 68 oldgoact->mask.__bits[i] = 0; 69 } 70 for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) { 71 if (sigismember(&oldact.sa_mask, i+1) == 1) { 72 oldgoact->mask.__bits[i/32] |= (uint32_t)(1)<<(i&31); 73 } 74 } 75 oldgoact->flags = oldact.sa_flags; 76 } 77 78 _cgo_tsan_release(); 79 return ret; 80 }