22
22
#include "libc/calls/internal.h"
23
23
#include "libc/calls/sig.internal.h"
24
24
#include "libc/calls/state.internal.h"
25
- #include "libc/calls/struct/sigaction-freebsd.internal.h"
26
- #include "libc/calls/struct/sigaction-linux.internal.h"
27
- #include "libc/calls/struct/sigaction-netbsd.h"
28
- #include "libc/calls/struct/sigaction-openbsd.internal.h"
29
- #include "libc/calls/struct/sigaction-xnu.internal.h"
30
25
#include "libc/calls/struct/sigaction.h"
31
26
#include "libc/calls/struct/sigaction.internal.h"
32
27
#include "libc/calls/struct/siginfo.internal.h"
46
41
#include "libc/mem/mem.h"
47
42
#include "libc/runtime/runtime.h"
48
43
#include "libc/str/str.h"
44
+ #include "libc/sysv/consts/limits.h"
49
45
#include "libc/sysv/consts/sa.h"
50
46
#include "libc/sysv/consts/sig.h"
51
47
#include "libc/sysv/errfuns.h"
@@ -58,110 +54,111 @@ STATIC_YOINK("strsignal"); // for kprintf()
58
54
59
55
#define SA_RESTORER 0x04000000
60
56
61
- #ifndef SWITCHEROO
62
- #define SWITCHEROO (S1 , S2 , A , B , C , D ) \
63
- do { \
64
- autotype((S2).A) a = (typeof((S2).A))(S1).A; \
65
- autotype((S2).B) b = (typeof((S2).B))(S1).B; \
66
- autotype((S2).C) c = (typeof((S2).C))(S1).C; \
67
- typeof((S2).D) d; \
68
- bzero(&d, sizeof(d)); \
69
- memcpy(&d, &((S1).D), MIN(sizeof(d), sizeof((S1).D))); \
70
- (S2).A = a; \
71
- (S2).B = b; \
72
- (S2).C = c; \
73
- bzero(&((S2).D), sizeof((S2).D)); \
74
- memcpy(&((S2).D), &d, MIN(sizeof(d), sizeof((S2).D))); \
75
- } while (0);
76
- #endif
77
-
78
- union metasigaction {
79
- struct sigaction cosmo ;
80
- struct sigaction_linux linux ;
81
- struct sigaction_freebsd freebsd ;
82
- struct sigaction_openbsd openbsd ;
83
- struct sigaction_netbsd netbsd ;
84
- struct sigaction_xnu_in xnu_in ;
85
- struct sigaction_xnu_out xnu_out ;
86
- };
87
-
88
- void __sigenter_xnu (int , struct siginfo * , void * ) hidden ;
89
- void __sigenter_linux (int , struct siginfo * , void * ) hidden ;
90
- void __sigenter_netbsd (int , struct siginfo * , void * ) hidden ;
91
- void __sigenter_freebsd (int , struct siginfo * , void * ) hidden ;
92
- void __sigenter_openbsd (int , struct siginfo * , void * ) hidden ;
93
-
94
57
static void sigaction_cosmo2native (union metasigaction * sa ) {
58
+ void * handler ;
59
+ uint64_t flags ;
60
+ void * restorer ;
61
+ uint32_t mask [4 ];
95
62
if (!sa ) return ;
96
- switch (__hostos ) {
97
- case _HOSTLINUX :
98
- SWITCHEROO (sa -> cosmo , sa -> linux , sa_handler , sa_flags , sa_restorer ,
99
- sa_mask );
100
- break ;
101
- case _HOSTXNU :
102
- SWITCHEROO (sa -> cosmo , sa -> xnu_in , sa_handler , sa_flags , sa_restorer ,
103
- sa_mask );
104
- break ;
105
- case _HOSTFREEBSD :
106
- SWITCHEROO (sa -> cosmo , sa -> freebsd , sa_handler , sa_flags , sa_flags ,
107
- sa_mask );
108
- break ;
109
- case _HOSTOPENBSD :
110
- SWITCHEROO (sa -> cosmo , sa -> openbsd , sa_handler , sa_flags , sa_flags ,
111
- sa_mask );
112
- break ;
113
- case _HOSTNETBSD :
114
- SWITCHEROO (sa -> cosmo , sa -> netbsd , sa_handler , sa_flags , sa_flags ,
115
- sa_mask );
116
- break ;
117
- default :
118
- break ;
63
+ flags = sa -> cosmo .sa_flags ;
64
+ handler = sa -> cosmo .sa_handler ;
65
+ restorer = sa -> cosmo .sa_restorer ;
66
+ mask [0 ] = sa -> cosmo .sa_mask .__bits [0 ];
67
+ mask [1 ] = sa -> cosmo .sa_mask .__bits [0 ] >> 32 ;
68
+ mask [2 ] = sa -> cosmo .sa_mask .__bits [1 ];
69
+ mask [3 ] = sa -> cosmo .sa_mask .__bits [1 ] >> 32 ;
70
+ if (IsLinux ()) {
71
+ sa -> linux .sa_flags = flags ;
72
+ sa -> linux .sa_handler = handler ;
73
+ sa -> linux .sa_restorer = restorer ;
74
+ sa -> linux .sa_mask [0 ] = mask [0 ];
75
+ sa -> linux .sa_mask [1 ] = mask [1 ];
76
+ } else if (IsXnu ()) {
77
+ sa -> xnu_in .sa_flags = flags ;
78
+ sa -> xnu_in .sa_handler = handler ;
79
+ sa -> xnu_in .sa_restorer = restorer ;
80
+ sa -> xnu_in .sa_mask [0 ] = mask [0 ];
81
+ } else if (IsFreebsd ()) {
82
+ sa -> freebsd .sa_flags = flags ;
83
+ sa -> freebsd .sa_handler = handler ;
84
+ sa -> freebsd .sa_mask [0 ] = mask [0 ];
85
+ sa -> freebsd .sa_mask [1 ] = mask [1 ];
86
+ sa -> freebsd .sa_mask [2 ] = mask [2 ];
87
+ sa -> freebsd .sa_mask [3 ] = mask [3 ];
88
+ } else if (IsOpenbsd ()) {
89
+ sa -> openbsd .sa_flags = flags ;
90
+ sa -> openbsd .sa_handler = handler ;
91
+ sa -> openbsd .sa_mask [0 ] = mask [0 ];
92
+ } else if (IsNetbsd ()) {
93
+ sa -> netbsd .sa_flags = flags ;
94
+ sa -> netbsd .sa_handler = handler ;
95
+ sa -> netbsd .sa_mask [0 ] = mask [0 ];
96
+ sa -> netbsd .sa_mask [1 ] = mask [1 ];
97
+ sa -> netbsd .sa_mask [2 ] = mask [2 ];
98
+ sa -> netbsd .sa_mask [3 ] = mask [3 ];
119
99
}
120
100
}
121
101
122
102
static void sigaction_native2cosmo (union metasigaction * sa ) {
103
+ void * handler ;
104
+ uint64_t flags ;
105
+ void * restorer = 0 ;
106
+ uint32_t mask [4 ] = {0 };
123
107
if (!sa ) return ;
124
- switch (__hostos ) {
125
- case _HOSTLINUX :
126
- SWITCHEROO (sa -> linux , sa -> cosmo , sa_handler , sa_flags , sa_restorer ,
127
- sa_mask );
128
- break ;
129
- case _HOSTXNU :
130
- SWITCHEROO (sa -> xnu_out , sa -> cosmo , sa_handler , sa_flags , sa_flags ,
131
- sa_mask );
132
- break ;
133
- case _HOSTFREEBSD :
134
- SWITCHEROO (sa -> freebsd , sa -> cosmo , sa_handler , sa_flags , sa_flags ,
135
- sa_mask );
136
- break ;
137
- case _HOSTOPENBSD :
138
- SWITCHEROO (sa -> openbsd , sa -> cosmo , sa_handler , sa_flags , sa_flags ,
139
- sa_mask );
140
- break ;
141
- case _HOSTNETBSD :
142
- SWITCHEROO (sa -> netbsd , sa -> cosmo , sa_handler , sa_flags , sa_flags ,
143
- sa_mask );
144
- break ;
145
- default :
146
- break ;
108
+ if (IsLinux ()) {
109
+ flags = sa -> linux .sa_flags ;
110
+ handler = sa -> linux .sa_handler ;
111
+ restorer = sa -> linux .sa_restorer ;
112
+ mask [0 ] = sa -> linux .sa_mask [0 ];
113
+ mask [1 ] = sa -> linux .sa_mask [1 ];
114
+ } else if (IsXnu ()) {
115
+ flags = sa -> xnu_out .sa_flags ;
116
+ handler = sa -> xnu_out .sa_handler ;
117
+ mask [0 ] = sa -> xnu_out .sa_mask [0 ];
118
+ } else if (IsFreebsd ()) {
119
+ flags = sa -> freebsd .sa_flags ;
120
+ handler = sa -> freebsd .sa_handler ;
121
+ mask [0 ] = sa -> freebsd .sa_mask [0 ];
122
+ mask [1 ] = sa -> freebsd .sa_mask [1 ];
123
+ mask [2 ] = sa -> freebsd .sa_mask [2 ];
124
+ mask [3 ] = sa -> freebsd .sa_mask [3 ];
125
+ } else if (IsOpenbsd ()) {
126
+ flags = sa -> openbsd .sa_flags ;
127
+ handler = sa -> openbsd .sa_handler ;
128
+ mask [0 ] = sa -> openbsd .sa_mask [0 ];
129
+ } else if (IsNetbsd ()) {
130
+ flags = sa -> netbsd .sa_flags ;
131
+ handler = sa -> netbsd .sa_handler ;
132
+ mask [0 ] = sa -> netbsd .sa_mask [0 ];
133
+ mask [1 ] = sa -> netbsd .sa_mask [1 ];
134
+ mask [2 ] = sa -> netbsd .sa_mask [2 ];
135
+ mask [3 ] = sa -> netbsd .sa_mask [3 ];
136
+ } else {
137
+ return ;
147
138
}
139
+ sa -> cosmo .sa_flags = flags ;
140
+ sa -> cosmo .sa_handler = handler ;
141
+ sa -> cosmo .sa_restorer = restorer ;
142
+ sa -> cosmo .sa_mask .__bits [0 ] = mask [0 ] | (uint64_t )mask [1 ] << 32 ;
143
+ sa -> cosmo .sa_mask .__bits [1 ] = mask [2 ] | (uint64_t )mask [3 ] << 32 ;
148
144
}
149
145
150
146
static int __sigaction (int sig , const struct sigaction * act ,
151
147
struct sigaction * oldact ) {
152
- _Static_assert ((sizeof (struct sigaction ) > sizeof (struct sigaction_linux ) &&
153
- sizeof (struct sigaction ) > sizeof (struct sigaction_xnu_in ) &&
154
- sizeof (struct sigaction ) > sizeof (struct sigaction_xnu_out ) &&
155
- sizeof (struct sigaction ) > sizeof (struct sigaction_freebsd ) &&
156
- sizeof (struct sigaction ) > sizeof (struct sigaction_openbsd ) &&
157
- sizeof (struct sigaction ) > sizeof (struct sigaction_netbsd )),
158
- "sigaction cosmo abi needs tuning" );
148
+ _Static_assert (
149
+ (sizeof (struct sigaction ) >= sizeof (struct sigaction_linux ) &&
150
+ sizeof (struct sigaction ) >= sizeof (struct sigaction_xnu_in ) &&
151
+ sizeof (struct sigaction ) >= sizeof (struct sigaction_xnu_out ) &&
152
+ sizeof (struct sigaction ) >= sizeof (struct sigaction_freebsd ) &&
153
+ sizeof (struct sigaction ) >= sizeof (struct sigaction_openbsd ) &&
154
+ sizeof (struct sigaction ) >= sizeof (struct sigaction_netbsd )),
155
+ "sigaction cosmo abi needs tuning" );
159
156
int64_t arg4 , arg5 ;
160
157
int rc , rva , oldrva ;
161
158
sigaction_f sigenter ;
162
159
struct sigaction * ap , copy ;
163
160
if (IsMetal ()) return enosys (); /* TODO: Signals on Metal */
164
- if (!(0 < sig && sig < NSIG )) return einval ();
161
+ if (!(1 <= sig && sig <= _NSIG )) return einval ();
165
162
if (sig == SIGKILL || sig == SIGSTOP ) return einval ();
166
163
if (IsAsan () && ((act && !__asan_is_valid (act , sizeof (* act ))) ||
167
164
(oldact && !__asan_is_valid (oldact , sizeof (* oldact ))))) {
@@ -184,18 +181,23 @@ static int __sigaction(int sig, const struct sigaction *act,
184
181
if (act ) {
185
182
memcpy (& copy , act , sizeof (copy ));
186
183
ap = & copy ;
187
- if (IsXnu ()) {
184
+
185
+ if (IsLinux ()) {
186
+ if (!(ap -> sa_flags & SA_RESTORER )) {
187
+ ap -> sa_flags |= SA_RESTORER ;
188
+ ap -> sa_restorer = & __restore_rt ;
189
+ }
190
+ if (IsWsl1 ()) {
191
+ sigenter = __sigenter_wsl ;
192
+ } else {
193
+ sigenter = ap -> sa_sigaction ;
194
+ }
195
+ } else if (IsXnu ()) {
188
196
ap -> sa_restorer = (void * )& __sigenter_xnu ;
189
197
sigenter = __sigenter_xnu ;
190
198
// mitigate Rosetta signal handling strangeness
191
199
// https://github.com/jart/cosmopolitan/issues/455
192
200
ap -> sa_flags |= SA_SIGINFO ;
193
- } else if (IsLinux ()) {
194
- if (!(ap -> sa_flags & SA_RESTORER )) {
195
- ap -> sa_flags |= SA_RESTORER ;
196
- ap -> sa_restorer = & __restore_rt ;
197
- }
198
- sigenter = __sigenter_linux ;
199
201
} else if (IsNetbsd ()) {
200
202
sigenter = __sigenter_netbsd ;
201
203
} else if (IsFreebsd ()) {
0 commit comments