sigaction.c 997 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #include <stdlib.h>
  2. #include <signal.h>
  3. #include <errno.h>
  4. #include "syscall.h"
  5. #include "pthread_impl.h"
  6. static void restorer()
  7. {
  8. syscall0(__NR_rt_sigreturn);
  9. }
  10. int __libc_sigaction(int sig, const struct sigaction *sa, struct sigaction *old)
  11. {
  12. struct {
  13. void *handler;
  14. unsigned long flags;
  15. void (*restorer)(void);
  16. sigset_t mask;
  17. } ksa, kold;
  18. long pksa=0, pkold=0;
  19. if (sa) {
  20. ksa.handler = sa->sa_handler;
  21. ksa.flags = sa->sa_flags | SA_RESTORER;
  22. ksa.restorer = restorer;
  23. ksa.mask = sa->sa_mask;
  24. pksa = (long)&ksa;
  25. }
  26. if (old) pkold = (long)&kold;
  27. if (syscall4(__NR_rt_sigaction, sig, pksa, pkold, 8))
  28. return -1;
  29. if (old) {
  30. old->sa_handler = kold.handler;
  31. old->sa_flags = kold.flags;
  32. old->sa_mask = kold.mask;
  33. }
  34. return 0;
  35. }
  36. int __sigaction(int sig, const struct sigaction *sa, struct sigaction *old)
  37. {
  38. if (sig == SIGCANCEL || sig == SIGSYSCALL) {
  39. errno = EINVAL;
  40. return -1;
  41. }
  42. return __libc_sigaction(sig, sa, old);
  43. }
  44. weak_alias(__sigaction, sigaction);