1
0

sigaction.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. #include <signal.h>
  2. #include <errno.h>
  3. #include <string.h>
  4. #include "syscall.h"
  5. #include "pthread_impl.h"
  6. #include "libc.h"
  7. #include "ksigaction.h"
  8. static int unmask_done;
  9. static unsigned long handler_set[_NSIG/(8*sizeof(long))];
  10. void __get_handler_set(sigset_t *set)
  11. {
  12. memcpy(set, handler_set, sizeof handler_set);
  13. }
  14. int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
  15. {
  16. struct k_sigaction ksa, ksa_old;
  17. if (sa) {
  18. if ((uintptr_t)sa->sa_handler > 1UL) {
  19. a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
  20. 1UL<<(sig-1)%(8*sizeof(long)));
  21. /* If pthread_create has not yet been called,
  22. * implementation-internal signals might not
  23. * yet have been unblocked. They must be
  24. * unblocked before any signal handler is
  25. * installed, so that an application cannot
  26. * receive an illegal sigset_t (with them
  27. * blocked) as part of the ucontext_t passed
  28. * to the signal handler. */
  29. if (!libc.threaded && !unmask_done) {
  30. __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
  31. SIGPT_SET, 0, _NSIG/8);
  32. unmask_done = 1;
  33. }
  34. }
  35. ksa.handler = sa->sa_handler;
  36. ksa.flags = sa->sa_flags | SA_RESTORER;
  37. ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
  38. memcpy(&ksa.mask, &sa->sa_mask, sizeof ksa.mask);
  39. }
  40. if (syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, sizeof ksa.mask))
  41. return -1;
  42. if (old) {
  43. old->sa_handler = ksa_old.handler;
  44. old->sa_flags = ksa_old.flags;
  45. memcpy(&old->sa_mask, &ksa_old.mask, sizeof ksa_old.mask);
  46. }
  47. return 0;
  48. }
  49. int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
  50. {
  51. if (sig-32U < 3 || sig-1U >= _NSIG-1) {
  52. errno = EINVAL;
  53. return -1;
  54. }
  55. return __libc_sigaction(sig, sa, old);
  56. }
  57. weak_alias(__sigaction, sigaction);