signal.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (C) 2004 PathScale, Inc
  3. * Licensed under the GPL
  4. */
  5. #include <signal.h>
  6. #include <stdio.h>
  7. #include <unistd.h>
  8. #include <stdlib.h>
  9. #include <errno.h>
  10. #include <stdarg.h>
  11. #include <string.h>
  12. #include <sys/mman.h>
  13. #include "user_util.h"
  14. #include "kern_util.h"
  15. #include "user.h"
  16. #include "signal_kern.h"
  17. #include "sysdep/sigcontext.h"
  18. #include "sysdep/signal.h"
  19. #include "sigcontext.h"
  20. #include "time_user.h"
  21. #include "mode.h"
  22. void sig_handler(ARCH_SIGHDLR_PARAM)
  23. {
  24. struct sigcontext *sc;
  25. ARCH_GET_SIGCONTEXT(sc, sig);
  26. CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
  27. sig, sc);
  28. }
  29. extern int timer_irq_inited;
  30. void alarm_handler(ARCH_SIGHDLR_PARAM)
  31. {
  32. struct sigcontext *sc;
  33. ARCH_GET_SIGCONTEXT(sc, sig);
  34. if(!timer_irq_inited) return;
  35. if(sig == SIGALRM)
  36. switch_timers(0);
  37. CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
  38. sig, sc);
  39. if(sig == SIGALRM)
  40. switch_timers(1);
  41. }
  42. void set_sigstack(void *sig_stack, int size)
  43. {
  44. stack_t stack = ((stack_t) { .ss_flags = 0,
  45. .ss_sp = (__ptr_t) sig_stack,
  46. .ss_size = size - sizeof(void *) });
  47. if(sigaltstack(&stack, NULL) != 0)
  48. panic("enabling signal stack failed, errno = %d\n", errno);
  49. }
  50. void remove_sigstack(void)
  51. {
  52. stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
  53. .ss_sp = NULL,
  54. .ss_size = 0 });
  55. if(sigaltstack(&stack, NULL) != 0)
  56. panic("disabling signal stack failed, errno = %d\n", errno);
  57. }
  58. void set_handler(int sig, void (*handler)(int), int flags, ...)
  59. {
  60. struct sigaction action;
  61. va_list ap;
  62. int mask;
  63. va_start(ap, flags);
  64. action.sa_handler = handler;
  65. sigemptyset(&action.sa_mask);
  66. while((mask = va_arg(ap, int)) != -1){
  67. sigaddset(&action.sa_mask, mask);
  68. }
  69. va_end(ap);
  70. action.sa_flags = flags;
  71. action.sa_restorer = NULL;
  72. if(sigaction(sig, &action, NULL) < 0)
  73. panic("sigaction failed");
  74. }
  75. int change_sig(int signal, int on)
  76. {
  77. sigset_t sigset, old;
  78. sigemptyset(&sigset);
  79. sigaddset(&sigset, signal);
  80. sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
  81. return(!sigismember(&old, signal));
  82. }
  83. /* Both here and in set/get_signal we don't touch SIGPROF, because we must not
  84. * disable profiling; it's safe because the profiling code does not interact
  85. * with the kernel code at all.*/
  86. static void change_signals(int type)
  87. {
  88. sigset_t mask;
  89. sigemptyset(&mask);
  90. sigaddset(&mask, SIGVTALRM);
  91. sigaddset(&mask, SIGALRM);
  92. sigaddset(&mask, SIGIO);
  93. if(sigprocmask(type, &mask, NULL) < 0)
  94. panic("Failed to change signal mask - errno = %d", errno);
  95. }
  96. void block_signals(void)
  97. {
  98. change_signals(SIG_BLOCK);
  99. }
  100. void unblock_signals(void)
  101. {
  102. change_signals(SIG_UNBLOCK);
  103. }
  104. /* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
  105. * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
  106. * be able to profile all of UML, not just the non-critical sections. If
  107. * profiling is not thread-safe, then that is not my problem. We can disable
  108. * profiling when SMP is enabled in that case.
  109. */
  110. #define SIGIO_BIT 0
  111. #define SIGVTALRM_BIT 1
  112. static int enable_mask(sigset_t *mask)
  113. {
  114. int sigs;
  115. sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
  116. sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
  117. sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
  118. return(sigs);
  119. }
  120. int get_signals(void)
  121. {
  122. sigset_t mask;
  123. if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
  124. panic("Failed to get signal mask");
  125. return(enable_mask(&mask));
  126. }
  127. int set_signals(int enable)
  128. {
  129. sigset_t mask;
  130. int ret;
  131. sigemptyset(&mask);
  132. if(enable & (1 << SIGIO_BIT))
  133. sigaddset(&mask, SIGIO);
  134. if(enable & (1 << SIGVTALRM_BIT)){
  135. sigaddset(&mask, SIGVTALRM);
  136. sigaddset(&mask, SIGALRM);
  137. }
  138. /* This is safe - sigprocmask is guaranteed to copy locally the
  139. * value of new_set, do his work and then, at the end, write to
  140. * old_set.
  141. */
  142. if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
  143. panic("Failed to enable signals");
  144. ret = enable_mask(&mask);
  145. sigemptyset(&mask);
  146. if((enable & (1 << SIGIO_BIT)) == 0)
  147. sigaddset(&mask, SIGIO);
  148. if((enable & (1 << SIGVTALRM_BIT)) == 0){
  149. sigaddset(&mask, SIGVTALRM);
  150. sigaddset(&mask, SIGALRM);
  151. }
  152. if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
  153. panic("Failed to block signals");
  154. return(ret);
  155. }