sigaction.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * sigaction() for Xtensa uClibc
  4. *
  5. * Copyright (C) 2007, 2008 Tensilica Inc.
  6. *
  7. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  8. */
  9. #include <errno.h>
  10. #include <signal.h>
  11. #include <sys/syscall.h>
  12. #include <string.h>
  13. #include <bits/kernel_sigaction.h>
  14. #define SA_RESTORER 0x04000000
  15. extern void __default_sa_restorer (void);
  16. /* Experimentally off - libc_hidden_proto(memcpy) */
  17. int __libc_sigaction (int signum, const struct sigaction *act,
  18. struct sigaction *oact)
  19. {
  20. struct kernel_sigaction kact, koact;
  21. int result;
  22. enum {
  23. SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask)
  24. ? sizeof(kact.sa_mask) : sizeof(act->sa_mask)
  25. };
  26. if (act) {
  27. kact.k_sa_handler = act->sa_handler;
  28. memcpy(&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE);
  29. kact.sa_flags = act->sa_flags;
  30. if (kact.sa_flags & SA_RESTORER) {
  31. kact.sa_restorer = act->sa_restorer;
  32. } else {
  33. kact.sa_restorer = __default_sa_restorer;
  34. kact.sa_flags |= SA_RESTORER;
  35. }
  36. }
  37. /* NB: kernel (as of 2.6.25) will return EINVAL
  38. * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
  39. result = __syscall_rt_sigaction(signum,
  40. act ? &kact : NULL,
  41. oact ? &koact : NULL,
  42. sizeof(kact.sa_mask));
  43. if (oact && result >= 0) {
  44. oact->sa_handler = koact.k_sa_handler;
  45. memcpy(&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE);
  46. oact->sa_flags = koact.sa_flags;
  47. oact->sa_restorer = koact.sa_restorer;
  48. }
  49. return result;
  50. }
  51. #ifndef LIBC_SIGACTION
  52. libc_hidden_proto(sigaction)
  53. weak_alias(__libc_sigaction, sigaction)
  54. libc_hidden_weak(sigaction)
  55. #endif