2 * Copyright (C) 2004 PathScale, Inc
3 * Licensed under the GPL
14 #include "user_util.h"
15 #include "kern_util.h"
17 #include "signal_kern.h"
18 #include "sysdep/sigcontext.h"
19 #include "sysdep/signal.h"
20 #include "sigcontext.h"
21 #include "time_user.h"
24 void sig_handler(ARCH_SIGHDLR_PARAM)
26 struct sigcontext *sc;
28 ARCH_GET_SIGCONTEXT(sc, sig);
29 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
33 extern int timer_irq_inited;
35 void alarm_handler(ARCH_SIGHDLR_PARAM)
37 struct sigcontext *sc;
39 ARCH_GET_SIGCONTEXT(sc, sig);
40 if(!timer_irq_inited) return;
45 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
52 void set_sigstack(void *sig_stack, int size)
54 stack_t stack = ((stack_t) { .ss_flags = 0,
55 .ss_sp = (__ptr_t) sig_stack,
56 .ss_size = size - sizeof(void *) });
58 if(sigaltstack(&stack, NULL) != 0)
59 panic("enabling signal stack failed, errno = %d\n", errno);
62 void remove_sigstack(void)
64 stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
68 if(sigaltstack(&stack, NULL) != 0)
69 panic("disabling signal stack failed, errno = %d\n", errno);
72 void set_handler(int sig, void (*handler)(int), int flags, ...)
74 struct sigaction action;
79 action.sa_handler = handler;
80 sigemptyset(&action.sa_mask);
81 while((mask = va_arg(ap, int)) != -1){
82 sigaddset(&action.sa_mask, mask);
85 action.sa_flags = flags;
86 action.sa_restorer = NULL;
87 if(sigaction(sig, &action, NULL) < 0)
88 panic("sigaction failed");
91 int change_sig(int signal, int on)
96 sigaddset(&sigset, signal);
97 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
98 return(!sigismember(&old, signal));
101 /* Both here and in set/get_signal we don't touch SIGPROF, because we must not
102 * disable profiling; it's safe because the profiling code does not interact
103 * with the kernel code at all.*/
105 static void change_signals(int type)
110 sigaddset(&mask, SIGVTALRM);
111 sigaddset(&mask, SIGALRM);
112 sigaddset(&mask, SIGIO);
113 if(sigprocmask(type, &mask, NULL) < 0)
114 panic("Failed to change signal mask - errno = %d", errno);
117 void block_signals(void)
119 change_signals(SIG_BLOCK);
122 void unblock_signals(void)
124 change_signals(SIG_UNBLOCK);
127 /* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
128 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
129 * be able to profile all of UML, not just the non-critical sections. If
130 * profiling is not thread-safe, then that is not my problem. We can disable
131 * profiling when SMP is enabled in that case.
134 #define SIGVTALRM_BIT 1
136 static int enable_mask(sigset_t *mask)
140 sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
141 sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
142 sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
146 int get_signals(void)
150 if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
151 panic("Failed to get signal mask");
152 return(enable_mask(&mask));
155 int set_signals(int enable)
161 if(enable & (1 << SIGIO_BIT))
162 sigaddset(&mask, SIGIO);
163 if(enable & (1 << SIGVTALRM_BIT)){
164 sigaddset(&mask, SIGVTALRM);
165 sigaddset(&mask, SIGALRM);
168 /* This is safe - sigprocmask is guaranteed to copy locally the
169 * value of new_set, do his work and then, at the end, write to
172 if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
173 panic("Failed to enable signals");
174 ret = enable_mask(&mask);
176 if((enable & (1 << SIGIO_BIT)) == 0)
177 sigaddset(&mask, SIGIO);
178 if((enable & (1 << SIGVTALRM_BIT)) == 0){
179 sigaddset(&mask, SIGVTALRM);
180 sigaddset(&mask, SIGALRM);
182 if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
183 panic("Failed to block signals");