sigvec.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /* ABI compatibility for obsolete sigvec function from 4.2BSD.
  2. Copyright (C) 1991-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <shlib-compat.h>
  16. #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_21)
  17. # include <signal.h>
  18. # include <errno.h>
  19. # include <stddef.h>
  20. /* These are the struct sigvec and SV_* bit definitions that
  21. used to be in <signal.h>. The whole interface now exists
  22. solely for ABI compatibility, so it can just be here. */
  23. struct sigvec
  24. {
  25. __sighandler_t sv_handler; /* Signal handler. */
  26. int sv_mask; /* Mask of signals to be blocked. */
  27. int sv_flags; /* Flags (see below). */
  28. };
  29. # define SV_ONSTACK (1 << 0)/* Take the signal on the signal stack. */
  30. # define SV_INTERRUPT (1 << 1)/* Do not restart system calls. */
  31. # define SV_RESETHAND (1 << 2)/* Reset handler to SIG_DFL on receipt. */
  32. /* Include macros to convert between `sigset_t' and old-style mask. */
  33. # include <sigset-cvt-mask.h>
  34. # ifndef SA_RESETHAND
  35. /* When sigaction lacks the extension bit for it,
  36. we use a wrapper handler to support SV_RESETHAND. */
  37. struct sigvec_wrapper_data
  38. {
  39. __sighandler_t sw_handler;
  40. unsigned int sw_mask;
  41. };
  42. static void sigvec_wrapper_handler (int sig) __THROW;
  43. static struct sigvec_wrapper_data sigvec_wrapper_data[NSIG];
  44. # endif
  45. /* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member
  46. of VEC. The signals in `sv_mask' will be blocked while the handler runs.
  47. If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be
  48. reset to SIG_DFL before `sv_handler' is entered. If OVEC is non-NULL,
  49. it is filled in with the old information for SIG. */
  50. int
  51. __sigvec (int sig,
  52. const struct sigvec *vec,
  53. struct sigvec *ovec)
  54. {
  55. struct sigaction old;
  56. # ifndef SA_RESETHAND
  57. if (vec == NULL || !(vec->sv_flags & SV_RESETHAND))
  58. # endif
  59. {
  60. struct sigaction new, *n;
  61. if (vec == NULL)
  62. n = NULL;
  63. else
  64. {
  65. __sighandler_t handler;
  66. unsigned int mask;
  67. unsigned int sv_flags;
  68. unsigned int sa_flags;
  69. handler = vec->sv_handler;
  70. mask = vec->sv_mask;
  71. sv_flags = vec->sv_flags;
  72. sa_flags = 0;
  73. if (sv_flags & SV_ONSTACK)
  74. {
  75. # ifdef SA_ONSTACK
  76. sa_flags |= SA_ONSTACK;
  77. # else
  78. __set_errno (ENOSYS);
  79. return -1;
  80. # endif
  81. }
  82. # ifdef SA_RESTART
  83. if (!(sv_flags & SV_INTERRUPT))
  84. sa_flags |= SA_RESTART;
  85. # endif
  86. # ifdef SA_RESETHAND
  87. if (sv_flags & SV_RESETHAND)
  88. sa_flags |= SA_RESETHAND;
  89. # endif
  90. n = &new;
  91. new.sa_handler = handler;
  92. if (sigset_set_old_mask (&new.sa_mask, mask) < 0)
  93. return -1;
  94. new.sa_flags = sa_flags;
  95. }
  96. if (__sigaction (sig, n, &old) < 0)
  97. return -1;
  98. }
  99. # ifndef SA_RESETHAND
  100. else
  101. {
  102. __sighandler_t handler;
  103. unsigned int mask;
  104. struct sigvec_wrapper_data *data;
  105. struct sigaction wrapper;
  106. handler = vec->sv_handler;
  107. mask = (unsigned int)vec->sv_mask;
  108. data = &sigvec_wrapper_data[sig];
  109. wrapper.sa_handler = sigvec_wrapper_handler;
  110. /* FIXME: should we set wrapper.sa_mask, wrapper.sa_flags?? */
  111. data->sw_handler = handler;
  112. data->sw_mask = mask;
  113. if (__sigaction (sig, &wrapper, &old) < 0)
  114. return -1;
  115. }
  116. # endif
  117. if (ovec != NULL)
  118. {
  119. __sighandler_t handler;
  120. unsigned int sv_flags;
  121. unsigned int sa_flags;
  122. unsigned int mask;
  123. handler = old.sa_handler;
  124. sv_flags = 0;
  125. sa_flags = old.sa_flags;
  126. # ifndef SA_RESETHAND
  127. if (handler == sigvec_wrapper_handler)
  128. {
  129. handler = sigvec_wrapper_data[sig].sw_handler;
  130. /* should we use data->sw_mask?? */
  131. sv_flags |= SV_RESETHAND;
  132. }
  133. # else
  134. if (sa_flags & SA_RESETHAND)
  135. sv_flags |= SV_RESETHAND;
  136. # endif
  137. mask = sigset_get_old_mask (&old.sa_mask);
  138. # ifdef SA_ONSTACK
  139. if (sa_flags & SA_ONSTACK)
  140. sv_flags |= SV_ONSTACK;
  141. # endif
  142. # ifdef SA_RESTART
  143. if (!(sa_flags & SA_RESTART))
  144. # endif
  145. sv_flags |= SV_INTERRUPT;
  146. ovec->sv_handler = handler;
  147. ovec->sv_mask = (int)mask;
  148. ovec->sv_flags = (int)sv_flags;
  149. }
  150. return 0;
  151. }
  152. compat_symbol (libc, __sigvec, sigvec, GLIBC_2_0);
  153. # ifndef SA_RESETHAND
  154. static void
  155. sigvec_wrapper_handler (int sig)
  156. {
  157. struct sigvec_wrapper_data *data;
  158. struct sigaction act;
  159. int save;
  160. __sighandler_t handler;
  161. data = &sigvec_wrapper_data[sig];
  162. act.sa_handler = SIG_DFL;
  163. act.sa_flags = 0;
  164. sigset_set_old_mask (&act.sa_mask, data->sw_mask);
  165. handler = data->sw_handler;
  166. save = errno;
  167. (void) __sigaction (sig, &act, (struct sigaction *) NULL);
  168. __set_errno (save);
  169. (*handler) (sig);
  170. }
  171. # endif /* No SA_RESETHAND. */
  172. #endif /* SHLIB_COMPAT */