sigchain.c 1002 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #include <signal.h>
  2. #include "subcmd-util.h"
  3. #include "sigchain.h"
  4. #define SIGCHAIN_MAX_SIGNALS 32
  5. struct sigchain_signal {
  6. sigchain_fun *old;
  7. int n;
  8. int alloc;
  9. };
  10. static struct sigchain_signal signals[SIGCHAIN_MAX_SIGNALS];
  11. static void check_signum(int sig)
  12. {
  13. if (sig < 1 || sig >= SIGCHAIN_MAX_SIGNALS)
  14. die("BUG: signal out of range: %d", sig);
  15. }
  16. static int sigchain_push(int sig, sigchain_fun f)
  17. {
  18. struct sigchain_signal *s = signals + sig;
  19. check_signum(sig);
  20. ALLOC_GROW(s->old, s->n + 1, s->alloc);
  21. s->old[s->n] = signal(sig, f);
  22. if (s->old[s->n] == SIG_ERR)
  23. return -1;
  24. s->n++;
  25. return 0;
  26. }
  27. int sigchain_pop(int sig)
  28. {
  29. struct sigchain_signal *s = signals + sig;
  30. check_signum(sig);
  31. if (s->n < 1)
  32. return 0;
  33. if (signal(sig, s->old[s->n - 1]) == SIG_ERR)
  34. return -1;
  35. s->n--;
  36. return 0;
  37. }
  38. void sigchain_push_common(sigchain_fun f)
  39. {
  40. sigchain_push(SIGINT, f);
  41. sigchain_push(SIGHUP, f);
  42. sigchain_push(SIGTERM, f);
  43. sigchain_push(SIGQUIT, f);
  44. sigchain_push(SIGPIPE, f);
  45. }