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");