aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/signal.c')
-rw-r--r--arch/um/os-Linux/signal.c38
1 files changed, 13 insertions, 25 deletions
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 60e4faedf254..6b81739279d1 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -15,7 +15,6 @@
15#include "user.h" 15#include "user.h"
16#include "signal_kern.h" 16#include "signal_kern.h"
17#include "sysdep/sigcontext.h" 17#include "sysdep/sigcontext.h"
18#include "sysdep/signal.h"
19#include "sigcontext.h" 18#include "sigcontext.h"
20#include "mode.h" 19#include "mode.h"
21#include "os.h" 20#include "os.h"
@@ -38,18 +37,10 @@
38static int signals_enabled = 1; 37static int signals_enabled = 1;
39static int pending = 0; 38static int pending = 0;
40 39
41void sig_handler(ARCH_SIGHDLR_PARAM) 40void sig_handler(int sig, struct sigcontext *sc)
42{ 41{
43 struct sigcontext *sc;
44 int enabled; 42 int enabled;
45 43
46 /* Must be the first thing that this handler does - x86_64 stores
47 * the sigcontext in %rdx, and we need to save it before it has a
48 * chance to get trashed.
49 */
50
51 ARCH_GET_SIGCONTEXT(sc, sig);
52
53 enabled = signals_enabled; 44 enabled = signals_enabled;
54 if(!enabled && (sig == SIGIO)){ 45 if(!enabled && (sig == SIGIO)){
55 pending |= SIGIO_MASK; 46 pending |= SIGIO_MASK;
@@ -64,15 +55,8 @@ void sig_handler(ARCH_SIGHDLR_PARAM)
64 set_signals(enabled); 55 set_signals(enabled);
65} 56}
66 57
67extern int timer_irq_inited;
68
69static void real_alarm_handler(int sig, struct sigcontext *sc) 58static void real_alarm_handler(int sig, struct sigcontext *sc)
70{ 59{
71 if(!timer_irq_inited){
72 signals_enabled = 1;
73 return;
74 }
75
76 if(sig == SIGALRM) 60 if(sig == SIGALRM)
77 switch_timers(0); 61 switch_timers(0);
78 62
@@ -84,13 +68,10 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
84 68
85} 69}
86 70
87void alarm_handler(ARCH_SIGHDLR_PARAM) 71void alarm_handler(int sig, struct sigcontext *sc)
88{ 72{
89 struct sigcontext *sc;
90 int enabled; 73 int enabled;
91 74
92 ARCH_GET_SIGCONTEXT(sc, sig);
93
94 enabled = signals_enabled; 75 enabled = signals_enabled;
95 if(!signals_enabled){ 76 if(!signals_enabled){
96 if(sig == SIGVTALRM) 77 if(sig == SIGVTALRM)
@@ -126,6 +107,10 @@ void remove_sigstack(void)
126 panic("disabling signal stack failed, errno = %d\n", errno); 107 panic("disabling signal stack failed, errno = %d\n", errno);
127} 108}
128 109
110void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
111
112extern void hard_handler(int sig);
113
129void set_handler(int sig, void (*handler)(int), int flags, ...) 114void set_handler(int sig, void (*handler)(int), int flags, ...)
130{ 115{
131 struct sigaction action; 116 struct sigaction action;
@@ -133,13 +118,16 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
133 sigset_t sig_mask; 118 sigset_t sig_mask;
134 int mask; 119 int mask;
135 120
136 va_start(ap, flags); 121 handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
137 action.sa_handler = handler; 122 action.sa_handler = hard_handler;
123
138 sigemptyset(&action.sa_mask); 124 sigemptyset(&action.sa_mask);
139 while((mask = va_arg(ap, int)) != -1){ 125
126 va_start(ap, flags);
127 while((mask = va_arg(ap, int)) != -1)
140 sigaddset(&action.sa_mask, mask); 128 sigaddset(&action.sa_mask, mask);
141 }
142 va_end(ap); 129 va_end(ap);
130
143 action.sa_flags = flags; 131 action.sa_flags = flags;
144 action.sa_restorer = NULL; 132 action.sa_restorer = NULL;
145 if(sigaction(sig, &action, NULL) < 0) 133 if(sigaction(sig, &action, NULL) < 0)