sigaction.txt 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. All what you never wanted to know about sigaction(),
  2. struct sigaction, and sigset_t.
  3. Before vda started messing with sigset_t, struct sigaction
  4. and sigaction() functions, things looked this way:
  5. Structures
  6. MIPS:
  7. Ignoring bogus "#if defined(__mips__) ..." block in
  8. libc/sysdeps/linux/common/bits/kernel_sigaction.h
  9. and using
  10. libc/sysdeps/linux/mips/bits/kernel_sigaction.h
  11. as an authoritative source:
  12. HAVE_SA_RESTORER is #defined
  13. struct old_kernel_sigaction {
  14. unsigned sa_flags;
  15. sighandler_t k_sa_handler;
  16. unsigned long sa_mask;
  17. unsigned pad0[3]; /* reserved, keep size constant */
  18. /* Abi says here follows reserved int[2] */
  19. void (*sa_restorer)(void);
  20. #if (_MIPS_SZPTR < 64)
  21. /* For 32 bit code we have to pad struct sigaction to get
  22. * constant size for the ABI */
  23. int pad1[1]; /* reserved */
  24. #endif
  25. };
  26. struct kernel_sigaction {
  27. unsigned int sa_flags;
  28. sighandler_t k_sa_handler;
  29. kernel_sigset_t sa_mask;
  30. void (*sa_restorer)(void);
  31. int s_resv[1]; /* reserved */
  32. };
  33. struct sigaction {
  34. unsigned sa_flags;
  35. sighandler_t sa_handler;
  36. sigset_t sa_mask;
  37. /* The ABI says here are two unused ints following. */
  38. /* Restore handler. */
  39. void (*sa_restorer)(void);
  40. #if _MIPS_SZPTR < 64
  41. int sa_resv[1];
  42. #endif
  43. };
  44. IA64:
  45. Has no old_sigaction. What a relief.
  46. struct kernel_sigaction {
  47. sighandler_t k_sa_handler;
  48. unsigned long sa_flags;
  49. sigset_t sa_mask;
  50. };
  51. struct sigaction {
  52. sighandler_t sa_handler;
  53. unsigned long sa_flags;
  54. sigset_t sa_mask;
  55. };
  56. Alpha:
  57. struct old_kernel_sigaction {
  58. sighandler_t k_sa_handler;
  59. unsigned long sa_mask;
  60. unsigned sa_flags;
  61. };
  62. struct kernel_sigaction {
  63. sighandler_t k_sa_handler;
  64. unsigned sa_flags;
  65. sigset_t sa_mask;
  66. };
  67. struct sigaction {
  68. sighandler_t sa_handler;
  69. sigset_t sa_mask;
  70. unsigned sa_flags;
  71. };
  72. HPPA:
  73. struct kernel_sigaction {
  74. sighandler_t k_sa_handler;
  75. unsigned long sa_flags;
  76. sigset_t sa_mask;
  77. };
  78. struct sigaction {
  79. sighandler_t sa_handler;
  80. unsigned long sa_flags;
  81. sigset_t sa_mask;
  82. };
  83. The rest, kernel side:
  84. HAVE_SA_RESTORER #defined
  85. struct old_kernel_sigaction {
  86. sighandler_t k_sa_handler;
  87. unsigned long sa_mask;
  88. unsigned long sa_flags;
  89. void (*sa_restorer)(void);
  90. };
  91. struct kernel_sigaction {
  92. sighandler_t k_sa_handler;
  93. unsigned long sa_flags;
  94. void (*sa_restorer)(void);
  95. sigset_t sa_mask;
  96. };
  97. On userspace side, Sparc has special struct sigaction:
  98. struct sigaction {
  99. sighandler_t sa_handler;
  100. sigset_t sa_mask;
  101. unsigned long sa_flags;
  102. void (*sa_restorer)(void); /* Not used by Linux/Sparc */
  103. };
  104. And finally the rest has:
  105. struct sigaction {
  106. sighandler_t sa_handler;
  107. sigset_t sa_mask;
  108. int sa_flags;
  109. void (*sa_restorer)(void);
  110. };
  111. Userspace sigset_t was uniformly defined as vector of longs
  112. big enough to hold 1024 (!) bits - carried over from glibc.
  113. Since the only arch whose struct kernel_sigaction contains sa_mask
  114. not as a last member is MIPS, MIPS has special kernel_sigset_t,
  115. which is an array of longs long enough for 128 bits.
  116. Other arches still used userspace sigset_t in struct kernel_sigaction,
  117. but it did not really matter because overlong kernel_sigaction
  118. does not hurt in sigaction() [explained below].
  119. On kernel side, all arches define _NSIG to 65 (meaning
  120. there are 64 signals, 1..64) except MIPS, which define it to 129.
  121. Functions
  122. sigaction() [libc function] usually has two kernel_sigaction's
  123. on stack and copy (userspace) struct sigaction members into
  124. first one, executes syscall, then pulls out the result from
  125. second one. This accomodates differences in layouts of structs.
  126. The only typically present quirk is what to do with sa_restorer.
  127. libc/sysdeps/linux/arm/sigaction.c
  128. if HAVE_SA_RESTORER and (sa_flags & SA_RESTORER) is not set,
  129. sets sa_restorer to
  130. (flags & SA_SIGINFO) ? __default_rt_sa_restorer : __default_sa_restorer,
  131. and sets SA_RESTORER,
  132. otherwise passes it as-is. Which is kinda strange, because AFAICS
  133. HAVE_SA_RESTORER is *not* defined for ARM.
  134. libc/sysdeps/linux/i386/sigaction.c
  135. Forcibly sets SA_RESTORER and sa_restorer:
  136. kact.sa_flags = act->sa_flags | SA_RESTORER;
  137. kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore);
  138. libc/sysdeps/linux/x86_64/sigaction.c
  139. Forcibly sets SA_RESTORER and sa_restorer:
  140. kact.sa_flags = act->sa_flags | SA_RESTORER;
  141. kact.sa_restorer = &restore_rt;
  142. libc/sysdeps/linux/mips/sigaction.c
  143. # ifdef HAVE_SA_RESTORER
  144. # if _MIPS_SIM == _ABIO32
  145. kact.sa_restorer = act->sa_restorer;
  146. # else
  147. kact.sa_restorer = &restore_rt;
  148. # endif
  149. # endif
  150. No confusion here, HAVE_SA_RESTORER is #defined for MIPS
  151. libc/sysdeps/linux/avr32/sigaction.c
  152. if (kact.sa_flags & SA_RESTORER) {
  153. kact.sa_restorer = act->sa_restorer;
  154. } else {
  155. kact.sa_restorer = __default_rt_sa_restorer;
  156. kact.sa_flags |= SA_RESTORER;
  157. }
  158. Does not check HAVE_SA_RESTORER, but avr32 falls
  159. in "completely ordinary" category on both kernel and
  160. userspace sides, and those have it defined.
  161. libc/sysdeps/linux/xtensa/sigaction.c
  162. if (kact.sa_flags & SA_RESTORER) {
  163. kact.sa_restorer = act->sa_restorer;
  164. } else {
  165. kact.sa_restorer = __default_sa_restorer;
  166. kact.sa_flags |= SA_RESTORER;
  167. }
  168. Thus, similar to avr32.
  169. libc/signal/sigaction.c (i.e. the all other arches)
  170. # ifdef HAVE_SA_RESTORER
  171. kact.sa_restorer = act->sa_restorer;
  172. # endif
  173. Plain translation, just sa_restorer copy is protected
  174. by HAVE_SA_RESTORER #define check. Looks like here
  175. HAVE_SA_RESTORER will be undef'ed only for IA64,
  176. Alpha an HPPA.
  177. Proposed overhaul past 0.9.30
  178. Since we can define libc-side structures at will:
  179. make sigset_t and struct sigaction identical on kernel side and libc side
  180. within each arch. If arches do not need special handling of sa_restorer,
  181. then sigaction() can directly use passed struct sigaction as-is.
  182. Otherwise, a copy is still needed, although sigaction() might have
  183. just one struct kernel_sigaction on stack and use it both for passing
  184. data to kernel and for receiving it back. Might save a few bytes.
  185. To this effect:
  186. * Make sigset_t size match kernel side on all arches.
  187. This is easy since all arches have 64 signals and only MIPS has 128.
  188. * Modify libc/sysdeps/linux/$ARCH/bits/sigaction.h
  189. so that its struct sigaction matches kernel's. If sa_restorer
  190. field is present in libc but is missing in kernel_sigaction,
  191. add it at the bottom in order to not mess up kernel_sigaction layout.
  192. * Modify libc/sysdeps/linux/$ARCH/sigaction.c
  193. to implement the logic above. In "common" pseudo-arch
  194. (libc/signal/sigaction.c file),
  195. we would not even need to do any copying, as described above.
  196. * Document discovered arch quirks while debugging this mess.
  197. * struct old_kernel_sigaction can't be disposed of in a similar way,
  198. we need to have userspace struct sigaction unchanged regardless
  199. whether we use "old" or "new" kernel sigaction() syscall.
  200. It's moot anyway because "old" one is long unused, it's from
  201. pre-2.2 kernels.