signals.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Utility routines.
  4. *
  5. * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  6. * Copyright (C) 2006 Rob Landley
  7. * Copyright (C) 2006 Denys Vlasenko
  8. *
  9. * Licensed under GPL version 2, see file LICENSE in this tarball for details.
  10. */
  11. #include "libbb.h"
  12. /* Saves 2 bytes on x86! Oh my... */
  13. int sigaction_set(int signum, const struct sigaction *act)
  14. {
  15. return sigaction(signum, act, NULL);
  16. }
  17. int sigprocmask_allsigs(int how)
  18. {
  19. sigset_t set;
  20. sigfillset(&set);
  21. return sigprocmask(how, &set, NULL);
  22. }
  23. void bb_signals(int sigs, void (*f)(int))
  24. {
  25. int sig_no = 0;
  26. int bit = 1;
  27. while (sigs) {
  28. if (sigs & bit) {
  29. sigs &= ~bit;
  30. signal(sig_no, f);
  31. }
  32. sig_no++;
  33. bit <<= 1;
  34. }
  35. }
  36. void bb_signals_recursive(int sigs, void (*f)(int))
  37. {
  38. int sig_no = 0;
  39. int bit = 1;
  40. struct sigaction sa;
  41. memset(&sa, 0, sizeof(sa));
  42. sa.sa_handler = f;
  43. /*sa.sa_flags = 0;*/
  44. /*sigemptyset(&sa.sa_mask); - hope memset did it*/
  45. while (sigs) {
  46. if (sigs & bit) {
  47. sigs &= ~bit;
  48. sigaction_set(sig_no, &sa);
  49. }
  50. sig_no++;
  51. bit <<= 1;
  52. }
  53. }
  54. void sig_block(int sig)
  55. {
  56. sigset_t ss;
  57. sigemptyset(&ss);
  58. sigaddset(&ss, sig);
  59. sigprocmask(SIG_BLOCK, &ss, NULL);
  60. }
  61. void sig_unblock(int sig)
  62. {
  63. sigset_t ss;
  64. sigemptyset(&ss);
  65. sigaddset(&ss, sig);
  66. sigprocmask(SIG_UNBLOCK, &ss, NULL);
  67. }
  68. void wait_for_any_sig(void)
  69. {
  70. sigset_t ss;
  71. sigemptyset(&ss);
  72. sigsuspend(&ss);
  73. }
  74. /* Assuming the sig is fatal */
  75. void kill_myself_with_sig(int sig)
  76. {
  77. signal(sig, SIG_DFL);
  78. sig_unblock(sig);
  79. raise(sig);
  80. _exit(EXIT_FAILURE); /* Should not reach it */
  81. }
  82. void signal_SA_RESTART_empty_mask(int sig, void (*handler)(int))
  83. {
  84. struct sigaction sa;
  85. memset(&sa, 0, sizeof(sa));
  86. /*sigemptyset(&sa.sa_mask);*/
  87. sa.sa_flags = SA_RESTART;
  88. sa.sa_handler = handler;
  89. sigaction_set(sig, &sa);
  90. }
  91. void signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int))
  92. {
  93. struct sigaction sa;
  94. memset(&sa, 0, sizeof(sa));
  95. /*sigemptyset(&sa.sa_mask);*/
  96. /*sa.sa_flags = 0;*/
  97. sa.sa_handler = handler;
  98. sigaction_set(sig, &sa);
  99. }