|
@@ -1,249 +0,0 @@
|
|
|
- All what you never wanted to know about sigaction(),
|
|
|
- struct sigaction, and sigset_t.
|
|
|
-
|
|
|
-
|
|
|
-Before vda started messing with sigset_t, struct sigaction
|
|
|
-and sigaction() functions, things looked this way:
|
|
|
-
|
|
|
-
|
|
|
- Structures
|
|
|
-
|
|
|
-MIPS:
|
|
|
-
|
|
|
-Ignoring bogus "#if defined(__mips__) ..." block in
|
|
|
-libc/sysdeps/linux/common/bits/kernel_sigaction.h
|
|
|
-and using
|
|
|
-libc/sysdeps/linux/mips/bits/kernel_sigaction.h
|
|
|
-as an authoritative source:
|
|
|
-
|
|
|
-HAVE_SA_RESTORER is #defined
|
|
|
-struct old_kernel_sigaction {
|
|
|
- unsigned sa_flags;
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- unsigned long sa_mask;
|
|
|
- unsigned pad0[3]; /* reserved, keep size constant */
|
|
|
- /* Abi says here follows reserved int[2] */
|
|
|
- void (*sa_restorer)(void);
|
|
|
-#if (_MIPS_SZPTR < 64)
|
|
|
- /* For 32 bit code we have to pad struct sigaction to get
|
|
|
- * constant size for the ABI */
|
|
|
- int pad1[1]; /* reserved */
|
|
|
-#endif
|
|
|
-};
|
|
|
-struct kernel_sigaction {
|
|
|
- unsigned int sa_flags;
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- kernel_sigset_t sa_mask;
|
|
|
- void (*sa_restorer)(void);
|
|
|
- int s_resv[1]; /* reserved */
|
|
|
-};
|
|
|
-struct sigaction {
|
|
|
- unsigned sa_flags;
|
|
|
- sighandler_t sa_handler;
|
|
|
- sigset_t sa_mask;
|
|
|
- /* The ABI says here are two unused ints following. */
|
|
|
- /* Restore handler. */
|
|
|
- void (*sa_restorer)(void);
|
|
|
-#if _MIPS_SZPTR < 64
|
|
|
- int sa_resv[1];
|
|
|
-#endif
|
|
|
-};
|
|
|
-
|
|
|
-IA64:
|
|
|
-
|
|
|
-Has no old_sigaction. What a relief.
|
|
|
-
|
|
|
-struct kernel_sigaction {
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- unsigned long sa_flags;
|
|
|
- sigset_t sa_mask;
|
|
|
-};
|
|
|
-struct sigaction {
|
|
|
- sighandler_t sa_handler;
|
|
|
- unsigned long sa_flags;
|
|
|
- sigset_t sa_mask;
|
|
|
-};
|
|
|
-
|
|
|
-Alpha:
|
|
|
-
|
|
|
-struct old_kernel_sigaction {
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- unsigned long sa_mask;
|
|
|
- unsigned sa_flags;
|
|
|
-};
|
|
|
-struct kernel_sigaction {
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- unsigned sa_flags;
|
|
|
- sigset_t sa_mask;
|
|
|
-};
|
|
|
-struct sigaction {
|
|
|
- sighandler_t sa_handler;
|
|
|
- sigset_t sa_mask;
|
|
|
- unsigned sa_flags;
|
|
|
-};
|
|
|
-
|
|
|
-HPPA:
|
|
|
-
|
|
|
-struct kernel_sigaction {
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- unsigned long sa_flags;
|
|
|
- sigset_t sa_mask;
|
|
|
-};
|
|
|
-struct sigaction {
|
|
|
- sighandler_t sa_handler;
|
|
|
- unsigned long sa_flags;
|
|
|
- sigset_t sa_mask;
|
|
|
-};
|
|
|
-
|
|
|
-The rest, kernel side:
|
|
|
-
|
|
|
-HAVE_SA_RESTORER #defined
|
|
|
-struct old_kernel_sigaction {
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- unsigned long sa_mask;
|
|
|
- unsigned long sa_flags;
|
|
|
- void (*sa_restorer)(void);
|
|
|
-};
|
|
|
-struct kernel_sigaction {
|
|
|
- sighandler_t k_sa_handler;
|
|
|
- unsigned long sa_flags;
|
|
|
- void (*sa_restorer)(void);
|
|
|
- sigset_t sa_mask;
|
|
|
-};
|
|
|
-
|
|
|
-On userspace side, Sparc has special struct sigaction:
|
|
|
-
|
|
|
-struct sigaction {
|
|
|
- sighandler_t sa_handler;
|
|
|
- sigset_t sa_mask;
|
|
|
- unsigned long sa_flags;
|
|
|
- void (*sa_restorer)(void); /* Not used by Linux/Sparc */
|
|
|
-};
|
|
|
-
|
|
|
-And finally the rest has:
|
|
|
-
|
|
|
-struct sigaction {
|
|
|
- sighandler_t sa_handler;
|
|
|
- sigset_t sa_mask;
|
|
|
- int sa_flags;
|
|
|
- void (*sa_restorer)(void);
|
|
|
-};
|
|
|
-
|
|
|
-Userspace sigset_t was uniformly defined as vector of longs
|
|
|
-big enough to hold 1024 (!) bits - carried over from glibc.
|
|
|
-Since the only arch whose struct kernel_sigaction contains sa_mask
|
|
|
-not as a last member is MIPS, MIPS has special kernel_sigset_t,
|
|
|
-which is an array of longs long enough for 128 bits.
|
|
|
-Other arches still used userspace sigset_t in struct kernel_sigaction,
|
|
|
-but it did not really matter because overlong kernel_sigaction
|
|
|
-does not hurt in sigaction() [explained below].
|
|
|
-On kernel side, all arches define _NSIG to 65 (meaning
|
|
|
-there are 64 signals, 1..64) except MIPS, which define it to 129.
|
|
|
-
|
|
|
-
|
|
|
- Functions
|
|
|
-
|
|
|
-sigaction() [libc function] usually has two kernel_sigaction's
|
|
|
-on stack and copy (userspace) struct sigaction members into
|
|
|
-first one, executes syscall, then pulls out the result from
|
|
|
-second one. This accomodates differences in layouts of structs.
|
|
|
-
|
|
|
-The only typically present quirk is what to do with sa_restorer.
|
|
|
-
|
|
|
- libc/sysdeps/linux/arm/sigaction.c
|
|
|
-
|
|
|
-if HAVE_SA_RESTORER and (sa_flags & SA_RESTORER) is not set,
|
|
|
-sets sa_restorer to
|
|
|
-(flags & SA_SIGINFO) ? __default_rt_sa_restorer : __default_sa_restorer,
|
|
|
-and sets SA_RESTORER,
|
|
|
-otherwise passes it as-is. Which is kinda strange, because AFAICS
|
|
|
-HAVE_SA_RESTORER is *not* defined for ARM.
|
|
|
-
|
|
|
- libc/sysdeps/linux/i386/sigaction.c
|
|
|
-
|
|
|
-Forcibly sets SA_RESTORER and sa_restorer:
|
|
|
-kact.sa_flags = act->sa_flags | SA_RESTORER;
|
|
|
-kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore);
|
|
|
-
|
|
|
- libc/sysdeps/linux/x86_64/sigaction.c
|
|
|
-
|
|
|
-Forcibly sets SA_RESTORER and sa_restorer:
|
|
|
-kact.sa_flags = act->sa_flags | SA_RESTORER;
|
|
|
-kact.sa_restorer = &restore_rt;
|
|
|
-
|
|
|
- libc/sysdeps/linux/mips/sigaction.c
|
|
|
-
|
|
|
-# ifdef HAVE_SA_RESTORER
|
|
|
-# if _MIPS_SIM == _ABIO32
|
|
|
- kact.sa_restorer = act->sa_restorer;
|
|
|
-# else
|
|
|
- kact.sa_restorer = &restore_rt;
|
|
|
-# endif
|
|
|
-# endif
|
|
|
-No confusion here, HAVE_SA_RESTORER is #defined for MIPS
|
|
|
-
|
|
|
- libc/sysdeps/linux/avr32/sigaction.c
|
|
|
-
|
|
|
-if (kact.sa_flags & SA_RESTORER) {
|
|
|
- kact.sa_restorer = act->sa_restorer;
|
|
|
-} else {
|
|
|
- kact.sa_restorer = __default_rt_sa_restorer;
|
|
|
- kact.sa_flags |= SA_RESTORER;
|
|
|
-}
|
|
|
-Does not check HAVE_SA_RESTORER, but avr32 falls
|
|
|
-in "completely ordinary" category on both kernel and
|
|
|
-userspace sides, and those have it defined.
|
|
|
-
|
|
|
- libc/sysdeps/linux/xtensa/sigaction.c
|
|
|
-
|
|
|
-if (kact.sa_flags & SA_RESTORER) {
|
|
|
- kact.sa_restorer = act->sa_restorer;
|
|
|
-} else {
|
|
|
- kact.sa_restorer = __default_sa_restorer;
|
|
|
- kact.sa_flags |= SA_RESTORER;
|
|
|
-}
|
|
|
-Thus, similar to avr32.
|
|
|
-
|
|
|
- libc/signal/sigaction.c (i.e. the all other arches)
|
|
|
-
|
|
|
-# ifdef HAVE_SA_RESTORER
|
|
|
- kact.sa_restorer = act->sa_restorer;
|
|
|
-# endif
|
|
|
-Plain translation, just sa_restorer copy is protected
|
|
|
-by HAVE_SA_RESTORER #define check. Looks like here
|
|
|
-HAVE_SA_RESTORER will be undef'ed only for IA64,
|
|
|
-Alpha an HPPA.
|
|
|
-
|
|
|
-
|
|
|
- Proposed overhaul past 0.9.30
|
|
|
-
|
|
|
-Since we can define libc-side structures at will:
|
|
|
-make sigset_t and struct sigaction identical on kernel side and libc side
|
|
|
-within each arch. If arches do not need special handling of sa_restorer,
|
|
|
-then sigaction() can directly use passed struct sigaction as-is.
|
|
|
-Otherwise, a copy is still needed, although sigaction() might have
|
|
|
-just one struct kernel_sigaction on stack and use it both for passing
|
|
|
-data to kernel and for receiving it back. Might save a few bytes.
|
|
|
-
|
|
|
-To this effect:
|
|
|
-
|
|
|
-* Make sigset_t size match kernel side on all arches.
|
|
|
- This is easy since all arches have 64 signals and only MIPS has 128.
|
|
|
-
|
|
|
-* Modify libc/sysdeps/linux/$ARCH/bits/sigaction.h
|
|
|
- so that its struct sigaction matches kernel's. If sa_restorer
|
|
|
- field is present in libc but is missing in kernel_sigaction,
|
|
|
- add it at the bottom in order to not mess up kernel_sigaction layout.
|
|
|
-
|
|
|
-* Modify libc/sysdeps/linux/$ARCH/sigaction.c
|
|
|
- to implement the logic above. In "common" pseudo-arch
|
|
|
- (libc/signal/sigaction.c file),
|
|
|
- we would not even need to do any copying, as described above.
|
|
|
-
|
|
|
-* Document discovered arch quirks while debugging this mess.
|
|
|
-
|
|
|
-* struct old_kernel_sigaction can't be disposed of in a similar way,
|
|
|
- we need to have userspace struct sigaction unchanged regardless
|
|
|
- whether we use "old" or "new" kernel sigaction() syscall.
|
|
|
- It's moot anyway because "old" one is long unused, it's from
|
|
|
- pre-2.2 kernels.
|