1 All what you never wanted to know about sigaction(),
2 struct sigaction, and sigset_t.
5 Before vda started messing with sigset_t, struct sigaction
6 and sigaction() functions, things looked this way:
13 Ignoring bogus "#if defined(__mips__) ..." block in
14 libc/sysdeps/linux/common/bits/kernel_sigaction.h
16 libc/sysdeps/linux/mips/bits/kernel_sigaction.h
17 as an authoritative source:
19 HAVE_SA_RESTORER is #defined
20 struct old_kernel_sigaction {
22 sighandler_t k_sa_handler;
23 unsigned long sa_mask;
24 unsigned pad0[3]; /* reserved, keep size constant */
25 /* Abi says here follows reserved int[2] */
26 void (*sa_restorer)(void);
27 #if (_MIPS_SZPTR < 64)
28 /* For 32 bit code we have to pad struct sigaction to get
29 * constant size for the ABI */
30 int pad1[1]; /* reserved */
33 struct kernel_sigaction {
34 unsigned int sa_flags;
35 sighandler_t k_sa_handler;
36 kernel_sigset_t sa_mask;
37 void (*sa_restorer)(void);
38 int s_resv[1]; /* reserved */
42 sighandler_t sa_handler;
44 /* The ABI says here are two unused ints following. */
45 /* Restore handler. */
46 void (*sa_restorer)(void);
54 Has no old_sigaction. What a relief.
56 struct kernel_sigaction {
57 sighandler_t k_sa_handler;
58 unsigned long sa_flags;
62 sighandler_t sa_handler;
63 unsigned long sa_flags;
69 struct old_kernel_sigaction {
70 sighandler_t k_sa_handler;
71 unsigned long sa_mask;
74 struct kernel_sigaction {
75 sighandler_t k_sa_handler;
80 sighandler_t sa_handler;
87 struct kernel_sigaction {
88 sighandler_t k_sa_handler;
89 unsigned long sa_flags;
93 sighandler_t sa_handler;
94 unsigned long sa_flags;
98 The rest, kernel side:
100 HAVE_SA_RESTORER #defined
101 struct old_kernel_sigaction {
102 sighandler_t k_sa_handler;
103 unsigned long sa_mask;
104 unsigned long sa_flags;
105 void (*sa_restorer)(void);
107 struct kernel_sigaction {
108 sighandler_t k_sa_handler;
109 unsigned long sa_flags;
110 void (*sa_restorer)(void);
114 On userspace side, Sparc has special struct sigaction:
117 sighandler_t sa_handler;
119 unsigned long sa_flags;
120 void (*sa_restorer)(void); /* Not used by Linux/Sparc */
123 And finally the rest has:
126 sighandler_t sa_handler;
129 void (*sa_restorer)(void);
132 Userspace sigset_t was uniformly defined as vector of longs
133 big enough to hold 1024 (!) bits - carried over from glibc.
134 Since the only arch whose struct kernel_sigaction contains sa_mask
135 not as a last member is MIPS, MIPS has special kernel_sigset_t,
136 which is an array of longs long enough for 128 bits.
137 Other arches still used userspace sigset_t in struct kernel_sigaction,
138 but it did not really matter because overlong kernel_sigaction
139 does not hurt in sigaction() [explained below].
140 On kernel side, all arches define _NSIG to 65 (meaning
141 there are 64 signals, 1..64) except MIPS, which define it to 129.
146 sigaction() [libc function] usually has two kernel_sigaction's
147 on stack and copy (userspace) struct sigaction members into
148 first one, executes syscall, then pulls out the result from
149 second one. This accomodates differences in layouts of structs.
151 The only typically present quirk is what to do with sa_restorer.
153 libc/sysdeps/linux/arm/sigaction.c
155 if HAVE_SA_RESTORER and (sa_flags & SA_RESTORER) is not set,
157 (flags & SA_SIGINFO) ? __default_rt_sa_restorer : __default_sa_restorer,
158 and sets SA_RESTORER,
159 otherwise passes it as-is. Which is kinda strange, because AFAICS
160 HAVE_SA_RESTORER is *not* defined for ARM.
162 libc/sysdeps/linux/i386/sigaction.c
164 Forcibly sets SA_RESTORER and sa_restorer:
165 kact.sa_flags = act->sa_flags | SA_RESTORER;
166 kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore);
168 libc/sysdeps/linux/x86_64/sigaction.c
170 Forcibly sets SA_RESTORER and sa_restorer:
171 kact.sa_flags = act->sa_flags | SA_RESTORER;
172 kact.sa_restorer = &restore_rt;
174 libc/sysdeps/linux/mips/sigaction.c
176 # ifdef HAVE_SA_RESTORER
177 # if _MIPS_SIM == _ABIO32
178 kact.sa_restorer = act->sa_restorer;
180 kact.sa_restorer = &restore_rt;
183 No confusion here, HAVE_SA_RESTORER is #defined for MIPS
185 libc/sysdeps/linux/avr32/sigaction.c
187 if (kact.sa_flags & SA_RESTORER) {
188 kact.sa_restorer = act->sa_restorer;
190 kact.sa_restorer = __default_rt_sa_restorer;
191 kact.sa_flags |= SA_RESTORER;
193 Does not check HAVE_SA_RESTORER, but avr32 falls
194 in "completely ordinary" category on both kernel and
195 userspace sides, and those have it defined.
197 libc/sysdeps/linux/xtensa/sigaction.c
199 if (kact.sa_flags & SA_RESTORER) {
200 kact.sa_restorer = act->sa_restorer;
202 kact.sa_restorer = __default_sa_restorer;
203 kact.sa_flags |= SA_RESTORER;
205 Thus, similar to avr32.
207 libc/signal/sigaction.c (i.e. the all other arches)
209 # ifdef HAVE_SA_RESTORER
210 kact.sa_restorer = act->sa_restorer;
212 Plain translation, just sa_restorer copy is protected
213 by HAVE_SA_RESTORER #define check. Looks like here
214 HAVE_SA_RESTORER will be undef'ed only for IA64,
218 Proposed overhaul past 0.9.30
220 Since we can define libc-side structures at will:
221 make sigset_t and struct sigaction identical on kernel side and libc side
222 within each arch. If arches do not need special handling of sa_restorer,
223 then sigaction() can directly use passed struct sigaction as-is.
224 Otherwise, a copy is still needed, although sigaction() might have
225 just one struct kernel_sigaction on stack and use it both for passing
226 data to kernel and for receiving it back. Might save a few bytes.
230 * Make sigset_t size match kernel side on all arches.
231 This is easy since all arches have 64 signals and only MIPS has 128.
233 * Modify libc/sysdeps/linux/$ARCH/bits/sigaction.h
234 so that its struct sigaction matches kernel's. If sa_restorer
235 field is present in libc but is missing in kernel_sigaction,
236 add it at the bottom in order to not mess up kernel_sigaction layout.
238 * Modify libc/sysdeps/linux/$ARCH/sigaction.c
239 to implement the logic above. In "common" pseudo-arch
240 (libc/signal/sigaction.c file),
241 we would not even need to do any copying, as described above.
243 * Document discovered arch quirks while debugging this mess.
245 * struct old_kernel_sigaction can't be disposed of in a similar way,
246 we need to have userspace struct sigaction unchanged regardless
247 whether we use "old" or "new" kernel sigaction() syscall.
248 It's moot anyway because "old" one is long unused, it's from