signals.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. /* All known arches use small ints for signals */
  13. smallint bb_got_signal;
  14. void record_signo(int signo)
  15. {
  16. bb_got_signal = signo;
  17. }
  18. /* Saves 2 bytes on x86! Oh my... */
  19. int FAST_FUNC sigaction_set(int signum, const struct sigaction *act)
  20. {
  21. return sigaction(signum, act, NULL);
  22. }
  23. int FAST_FUNC sigprocmask_allsigs(int how)
  24. {
  25. sigset_t set;
  26. sigfillset(&set);
  27. return sigprocmask(how, &set, NULL);
  28. }
  29. void FAST_FUNC bb_signals(int sigs, void (*f)(int))
  30. {
  31. int sig_no = 0;
  32. int bit = 1;
  33. while (sigs) {
  34. if (sigs & bit) {
  35. sigs &= ~bit;
  36. signal(sig_no, f);
  37. }
  38. sig_no++;
  39. bit <<= 1;
  40. }
  41. }
  42. void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int))
  43. {
  44. int sig_no = 0;
  45. int bit = 1;
  46. struct sigaction sa;
  47. memset(&sa, 0, sizeof(sa));
  48. sa.sa_handler = f;
  49. /*sa.sa_flags = 0;*/
  50. /*sigemptyset(&sa.sa_mask); - hope memset did it*/
  51. while (sigs) {
  52. if (sigs & bit) {
  53. sigs &= ~bit;
  54. sigaction_set(sig_no, &sa);
  55. }
  56. sig_no++;
  57. bit <<= 1;
  58. }
  59. }
  60. void FAST_FUNC sig_block(int sig)
  61. {
  62. sigset_t ss;
  63. sigemptyset(&ss);
  64. sigaddset(&ss, sig);
  65. sigprocmask(SIG_BLOCK, &ss, NULL);
  66. }
  67. void FAST_FUNC sig_unblock(int sig)
  68. {
  69. sigset_t ss;
  70. sigemptyset(&ss);
  71. sigaddset(&ss, sig);
  72. sigprocmask(SIG_UNBLOCK, &ss, NULL);
  73. }
  74. void FAST_FUNC wait_for_any_sig(void)
  75. {
  76. sigset_t ss;
  77. sigemptyset(&ss);
  78. sigsuspend(&ss);
  79. }
  80. /* Assuming the sig is fatal */
  81. void FAST_FUNC kill_myself_with_sig(int sig)
  82. {
  83. signal(sig, SIG_DFL);
  84. sig_unblock(sig);
  85. raise(sig);
  86. _exit(EXIT_FAILURE); /* Should not reach it */
  87. }
  88. void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int))
  89. {
  90. struct sigaction sa;
  91. memset(&sa, 0, sizeof(sa));
  92. /*sigemptyset(&sa.sa_mask);*/
  93. sa.sa_flags = SA_RESTART;
  94. sa.sa_handler = handler;
  95. sigaction_set(sig, &sa);
  96. }
  97. void FAST_FUNC signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int))
  98. {
  99. struct sigaction sa;
  100. memset(&sa, 0, sizeof(sa));
  101. /*sigemptyset(&sa.sa_mask);*/
  102. /*sa.sa_flags = 0;*/
  103. sa.sa_handler = handler;
  104. sigaction_set(sig, &sa);
  105. }