Text file
src/runtime/cgo/gcc_freebsd_sigaction.c
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 // +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 }
81
View as plain text