diff options
Diffstat (limited to 'docs/sigaction.txt')
-rw-r--r-- | docs/sigaction.txt | 249 |
1 files changed, 0 insertions, 249 deletions
diff --git a/docs/sigaction.txt b/docs/sigaction.txt deleted file mode 100644 index 667eeba41..000000000 --- a/docs/sigaction.txt +++ /dev/null @@ -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. |