signals.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 GPLv2, see file LICENSE in this source tree.
  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. int FAST_FUNC sigprocmask2(int how, sigset_t *set)
  30. {
  31. // Grr... gcc 8.1.1:
  32. // "passing argument 3 to restrict-qualified parameter aliases with argument 2"
  33. // dance around that...
  34. sigset_t *oset FIX_ALIASING;
  35. oset = set;
  36. return sigprocmask(how, set, oset);
  37. }
  38. void FAST_FUNC bb_signals(int sigs, void (*f)(int))
  39. {
  40. int sig_no = 0;
  41. int bit = 1;
  42. while (sigs) {
  43. if (sigs & bit) {
  44. sigs -= bit;
  45. signal(sig_no, f);
  46. }
  47. sig_no++;
  48. bit <<= 1;
  49. }
  50. }
  51. void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int))
  52. {
  53. int sig_no = 0;
  54. int bit = 1;
  55. struct sigaction sa;
  56. memset(&sa, 0, sizeof(sa));
  57. sa.sa_handler = f;
  58. /*sa.sa_flags = 0;*/
  59. /*sigemptyset(&sa.sa_mask); - hope memset did it*/
  60. while (sigs) {
  61. if (sigs & bit) {
  62. sigs -= bit;
  63. sigaction_set(sig_no, &sa);
  64. }
  65. sig_no++;
  66. bit <<= 1;
  67. }
  68. }
  69. void FAST_FUNC sig_block(int sig)
  70. {
  71. sigset_t ss;
  72. sigemptyset(&ss);
  73. sigaddset(&ss, sig);
  74. sigprocmask(SIG_BLOCK, &ss, NULL);
  75. }
  76. void FAST_FUNC sig_unblock(int sig)
  77. {
  78. sigset_t ss;
  79. sigemptyset(&ss);
  80. sigaddset(&ss, sig);
  81. sigprocmask(SIG_UNBLOCK, &ss, NULL);
  82. }
  83. void FAST_FUNC wait_for_any_sig(void)
  84. {
  85. sigset_t ss;
  86. sigemptyset(&ss);
  87. sigsuspend(&ss);
  88. }
  89. /* Assuming the sig is fatal */
  90. void FAST_FUNC kill_myself_with_sig(int sig)
  91. {
  92. signal(sig, SIG_DFL);
  93. sig_unblock(sig);
  94. raise(sig);
  95. _exit(sig | 128); /* Should not reach it */
  96. }
  97. void FAST_FUNC signal_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 = SA_RESTART;
  103. sa.sa_handler = handler;
  104. sigaction_set(sig, &sa);
  105. }
  106. void FAST_FUNC signal_no_SA_RESTART_empty_mask(int sig, void (*handler)(int))
  107. {
  108. struct sigaction sa;
  109. memset(&sa, 0, sizeof(sa));
  110. /*sigemptyset(&sa.sa_mask);*/
  111. /*sa.sa_flags = 0;*/
  112. sa.sa_handler = handler;
  113. sigaction_set(sig, &sa);
  114. }