sigchain.c 1.0 KB

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