Commit 2c332a251302873cf8301c2aad27737b6df70255

Authored by Bodo Stroesser
Committed by Linus Torvalds
1 parent cff65c4f0e

[PATCH] uml: change interface to boot_timer_handler

Current implementation of boot_timer_handler isn't usable for s390.  So I
changed its name to do_boot_timer_handler, taking (struct sigcontext *)sc as
argument.  do_boot_timer_handler is called from new boot_timer_handler() in
arch/um/os-Linux/signal.c, which uses the same mechanisms as other signal
handler to find out sigcontext pointer.

Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 2 changed files with 13 additions and 4 deletions Inline Diff

arch/um/kernel/time_kern.c
1 /* 1 /*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6 #include "linux/kernel.h" 6 #include "linux/kernel.h"
7 #include "linux/module.h" 7 #include "linux/module.h"
8 #include "linux/unistd.h" 8 #include "linux/unistd.h"
9 #include "linux/stddef.h" 9 #include "linux/stddef.h"
10 #include "linux/spinlock.h" 10 #include "linux/spinlock.h"
11 #include "linux/time.h" 11 #include "linux/time.h"
12 #include "linux/sched.h" 12 #include "linux/sched.h"
13 #include "linux/interrupt.h" 13 #include "linux/interrupt.h"
14 #include "linux/init.h" 14 #include "linux/init.h"
15 #include "linux/delay.h" 15 #include "linux/delay.h"
16 #include "linux/hrtimer.h" 16 #include "linux/hrtimer.h"
17 #include "asm/irq.h" 17 #include "asm/irq.h"
18 #include "asm/param.h" 18 #include "asm/param.h"
19 #include "asm/current.h" 19 #include "asm/current.h"
20 #include "kern_util.h" 20 #include "kern_util.h"
21 #include "user_util.h" 21 #include "user_util.h"
22 #include "mode.h" 22 #include "mode.h"
23 #include "os.h" 23 #include "os.h"
24 24
25 int hz(void) 25 int hz(void)
26 { 26 {
27 return(HZ); 27 return(HZ);
28 } 28 }
29 29
30 /* 30 /*
31 * Scheduler clock - returns current time in nanosec units. 31 * Scheduler clock - returns current time in nanosec units.
32 */ 32 */
33 unsigned long long sched_clock(void) 33 unsigned long long sched_clock(void)
34 { 34 {
35 return (unsigned long long)jiffies_64 * (1000000000 / HZ); 35 return (unsigned long long)jiffies_64 * (1000000000 / HZ);
36 } 36 }
37 37
38 /* Changed at early boot */ 38 /* Changed at early boot */
39 int timer_irq_inited = 0; 39 int timer_irq_inited = 0;
40 40
41 static int first_tick; 41 static int first_tick;
42 static unsigned long long prev_nsecs; 42 static unsigned long long prev_nsecs;
43 #ifdef CONFIG_UML_REAL_TIME_CLOCK 43 #ifdef CONFIG_UML_REAL_TIME_CLOCK
44 static long long delta; /* Deviation per interval */ 44 static long long delta; /* Deviation per interval */
45 #endif 45 #endif
46 46
47 void timer_irq(union uml_pt_regs *regs) 47 void timer_irq(union uml_pt_regs *regs)
48 { 48 {
49 unsigned long long ticks = 0; 49 unsigned long long ticks = 0;
50 50
51 if(!timer_irq_inited){ 51 if(!timer_irq_inited){
52 /* This is to ensure that ticks don't pile up when 52 /* This is to ensure that ticks don't pile up when
53 * the timer handler is suspended */ 53 * the timer handler is suspended */
54 first_tick = 0; 54 first_tick = 0;
55 return; 55 return;
56 } 56 }
57 57
58 if(first_tick){ 58 if(first_tick){
59 #ifdef CONFIG_UML_REAL_TIME_CLOCK 59 #ifdef CONFIG_UML_REAL_TIME_CLOCK
60 /* We've had 1 tick */ 60 /* We've had 1 tick */
61 unsigned long long nsecs = os_nsecs(); 61 unsigned long long nsecs = os_nsecs();
62 62
63 delta += nsecs - prev_nsecs; 63 delta += nsecs - prev_nsecs;
64 prev_nsecs = nsecs; 64 prev_nsecs = nsecs;
65 65
66 /* Protect against the host clock being set backwards */ 66 /* Protect against the host clock being set backwards */
67 if(delta < 0) 67 if(delta < 0)
68 delta = 0; 68 delta = 0;
69 69
70 ticks += (delta * HZ) / BILLION; 70 ticks += (delta * HZ) / BILLION;
71 delta -= (ticks * BILLION) / HZ; 71 delta -= (ticks * BILLION) / HZ;
72 #else 72 #else
73 ticks = 1; 73 ticks = 1;
74 #endif 74 #endif
75 } 75 }
76 else { 76 else {
77 prev_nsecs = os_nsecs(); 77 prev_nsecs = os_nsecs();
78 first_tick = 1; 78 first_tick = 1;
79 } 79 }
80 80
81 while(ticks > 0){ 81 while(ticks > 0){
82 do_IRQ(TIMER_IRQ, regs); 82 do_IRQ(TIMER_IRQ, regs);
83 ticks--; 83 ticks--;
84 } 84 }
85 } 85 }
86 86
87 void boot_timer_handler(int sig) 87 void do_boot_timer_handler(struct sigcontext * sc)
88 { 88 {
89 struct pt_regs regs; 89 struct pt_regs regs;
90 90
91 CHOOSE_MODE((void) 91 CHOOSE_MODE((void) (UPT_SC(&regs.regs) = sc),
92 (UPT_SC(&regs.regs) = (struct sigcontext *) (&sig + 1)),
93 (void) (regs.regs.skas.is_user = 0)); 92 (void) (regs.regs.skas.is_user = 0));
94 do_timer(&regs); 93 do_timer(&regs);
95 } 94 }
96 95
97 static DEFINE_SPINLOCK(timer_spinlock); 96 static DEFINE_SPINLOCK(timer_spinlock);
98 97
99 static unsigned long long local_offset = 0; 98 static unsigned long long local_offset = 0;
100 99
101 static inline unsigned long long get_time(void) 100 static inline unsigned long long get_time(void)
102 { 101 {
103 unsigned long long nsecs; 102 unsigned long long nsecs;
104 unsigned long flags; 103 unsigned long flags;
105 104
106 spin_lock_irqsave(&timer_spinlock, flags); 105 spin_lock_irqsave(&timer_spinlock, flags);
107 nsecs = os_nsecs(); 106 nsecs = os_nsecs();
108 nsecs += local_offset; 107 nsecs += local_offset;
109 spin_unlock_irqrestore(&timer_spinlock, flags); 108 spin_unlock_irqrestore(&timer_spinlock, flags);
110 109
111 return nsecs; 110 return nsecs;
112 } 111 }
113 112
114 irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) 113 irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
115 { 114 {
116 unsigned long long nsecs; 115 unsigned long long nsecs;
117 unsigned long flags; 116 unsigned long flags;
118 117
119 do_timer(regs); 118 do_timer(regs);
120 119
121 write_seqlock_irqsave(&xtime_lock, flags); 120 write_seqlock_irqsave(&xtime_lock, flags);
122 nsecs = get_time() + local_offset; 121 nsecs = get_time() + local_offset;
123 xtime.tv_sec = nsecs / NSEC_PER_SEC; 122 xtime.tv_sec = nsecs / NSEC_PER_SEC;
124 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; 123 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
125 write_sequnlock_irqrestore(&xtime_lock, flags); 124 write_sequnlock_irqrestore(&xtime_lock, flags);
126 125
127 return(IRQ_HANDLED); 126 return(IRQ_HANDLED);
128 } 127 }
129 128
130 long um_time(int __user *tloc) 129 long um_time(int __user *tloc)
131 { 130 {
132 long ret = get_time() / NSEC_PER_SEC; 131 long ret = get_time() / NSEC_PER_SEC;
133 132
134 if((tloc != NULL) && put_user(ret, tloc)) 133 if((tloc != NULL) && put_user(ret, tloc))
135 return -EFAULT; 134 return -EFAULT;
136 135
137 return ret; 136 return ret;
138 } 137 }
139 138
140 void do_gettimeofday(struct timeval *tv) 139 void do_gettimeofday(struct timeval *tv)
141 { 140 {
142 unsigned long long nsecs = get_time(); 141 unsigned long long nsecs = get_time();
143 142
144 tv->tv_sec = nsecs / NSEC_PER_SEC; 143 tv->tv_sec = nsecs / NSEC_PER_SEC;
145 /* Careful about calculations here - this was originally done as 144 /* Careful about calculations here - this was originally done as
146 * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC 145 * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
147 * which gave bogus (> 1000000) values. Dunno why, suspect gcc 146 * which gave bogus (> 1000000) values. Dunno why, suspect gcc
148 * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion 147 * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion
149 * problem that I missed. 148 * problem that I missed.
150 */ 149 */
151 nsecs -= tv->tv_sec * NSEC_PER_SEC; 150 nsecs -= tv->tv_sec * NSEC_PER_SEC;
152 tv->tv_usec = (unsigned long) nsecs / NSEC_PER_USEC; 151 tv->tv_usec = (unsigned long) nsecs / NSEC_PER_USEC;
153 } 152 }
154 153
155 static inline void set_time(unsigned long long nsecs) 154 static inline void set_time(unsigned long long nsecs)
156 { 155 {
157 unsigned long long now; 156 unsigned long long now;
158 unsigned long flags; 157 unsigned long flags;
159 158
160 spin_lock_irqsave(&timer_spinlock, flags); 159 spin_lock_irqsave(&timer_spinlock, flags);
161 now = os_nsecs(); 160 now = os_nsecs();
162 local_offset = nsecs - now; 161 local_offset = nsecs - now;
163 spin_unlock_irqrestore(&timer_spinlock, flags); 162 spin_unlock_irqrestore(&timer_spinlock, flags);
164 163
165 clock_was_set(); 164 clock_was_set();
166 } 165 }
167 166
168 long um_stime(int __user *tptr) 167 long um_stime(int __user *tptr)
169 { 168 {
170 int value; 169 int value;
171 170
172 if (get_user(value, tptr)) 171 if (get_user(value, tptr))
173 return -EFAULT; 172 return -EFAULT;
174 173
175 set_time((unsigned long long) value * NSEC_PER_SEC); 174 set_time((unsigned long long) value * NSEC_PER_SEC);
176 175
177 return 0; 176 return 0;
178 } 177 }
179 178
180 int do_settimeofday(struct timespec *tv) 179 int do_settimeofday(struct timespec *tv)
181 { 180 {
182 set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec); 181 set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec);
183 182
184 return 0; 183 return 0;
185 } 184 }
186 185
187 void timer_handler(int sig, union uml_pt_regs *regs) 186 void timer_handler(int sig, union uml_pt_regs *regs)
188 { 187 {
189 local_irq_disable(); 188 local_irq_disable();
190 irq_enter(); 189 irq_enter();
191 update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)), 190 update_process_times(CHOOSE_MODE(user_context(UPT_SP(regs)),
192 (regs)->skas.is_user)); 191 (regs)->skas.is_user));
193 irq_exit(); 192 irq_exit();
194 local_irq_enable(); 193 local_irq_enable();
195 if(current_thread->cpu == 0) 194 if(current_thread->cpu == 0)
196 timer_irq(regs); 195 timer_irq(regs);
197 } 196 }
198 197
199 int __init timer_init(void) 198 int __init timer_init(void)
200 { 199 {
201 int err; 200 int err;
202 201
203 user_time_init(); 202 user_time_init();
204 err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); 203 err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
205 if(err != 0) 204 if(err != 0)
206 printk(KERN_ERR "timer_init : request_irq failed - " 205 printk(KERN_ERR "timer_init : request_irq failed - "
207 "errno = %d\n", -err); 206 "errno = %d\n", -err);
208 timer_irq_inited = 1; 207 timer_irq_inited = 1;
209 return(0); 208 return(0);
210 } 209 }
211 210
212 __initcall(timer_init); 211 __initcall(timer_init);
213 212
arch/um/os-Linux/signal.c
1 /* 1 /*
2 * Copyright (C) 2004 PathScale, Inc 2 * Copyright (C) 2004 PathScale, Inc
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6 #include <signal.h> 6 #include <signal.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <unistd.h> 8 #include <unistd.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <errno.h> 10 #include <errno.h>
11 #include <stdarg.h> 11 #include <stdarg.h>
12 #include <string.h> 12 #include <string.h>
13 #include <sys/mman.h> 13 #include <sys/mman.h>
14 #include "user_util.h" 14 #include "user_util.h"
15 #include "kern_util.h"
16 #include "user.h" 15 #include "user.h"
17 #include "signal_kern.h" 16 #include "signal_kern.h"
18 #include "sysdep/sigcontext.h" 17 #include "sysdep/sigcontext.h"
19 #include "sysdep/signal.h" 18 #include "sysdep/signal.h"
20 #include "sigcontext.h" 19 #include "sigcontext.h"
21 #include "mode.h" 20 #include "mode.h"
22 #include "os.h" 21 #include "os.h"
23 22
24 void sig_handler(ARCH_SIGHDLR_PARAM) 23 void sig_handler(ARCH_SIGHDLR_PARAM)
25 { 24 {
26 struct sigcontext *sc; 25 struct sigcontext *sc;
27 26
28 ARCH_GET_SIGCONTEXT(sc, sig); 27 ARCH_GET_SIGCONTEXT(sc, sig);
29 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, 28 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
30 sig, sc); 29 sig, sc);
31 } 30 }
32 31
33 extern int timer_irq_inited; 32 extern int timer_irq_inited;
34 33
35 void alarm_handler(ARCH_SIGHDLR_PARAM) 34 void alarm_handler(ARCH_SIGHDLR_PARAM)
36 { 35 {
37 struct sigcontext *sc; 36 struct sigcontext *sc;
38 37
39 ARCH_GET_SIGCONTEXT(sc, sig); 38 ARCH_GET_SIGCONTEXT(sc, sig);
40 if(!timer_irq_inited) return; 39 if(!timer_irq_inited) return;
41 40
42 if(sig == SIGALRM) 41 if(sig == SIGALRM)
43 switch_timers(0); 42 switch_timers(0);
44 43
45 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, 44 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
46 sig, sc); 45 sig, sc);
47 46
48 if(sig == SIGALRM) 47 if(sig == SIGALRM)
49 switch_timers(1); 48 switch_timers(1);
49 }
50
51 extern void do_boot_timer_handler(struct sigcontext * sc);
52
53 void boot_timer_handler(ARCH_SIGHDLR_PARAM)
54 {
55 struct sigcontext *sc;
56
57 ARCH_GET_SIGCONTEXT(sc, sig);
58
59 do_boot_timer_handler(sc);
50 } 60 }
51 61
52 void set_sigstack(void *sig_stack, int size) 62 void set_sigstack(void *sig_stack, int size)
53 { 63 {
54 stack_t stack = ((stack_t) { .ss_flags = 0, 64 stack_t stack = ((stack_t) { .ss_flags = 0,
55 .ss_sp = (__ptr_t) sig_stack, 65 .ss_sp = (__ptr_t) sig_stack,
56 .ss_size = size - sizeof(void *) }); 66 .ss_size = size - sizeof(void *) });
57 67
58 if(sigaltstack(&stack, NULL) != 0) 68 if(sigaltstack(&stack, NULL) != 0)
59 panic("enabling signal stack failed, errno = %d\n", errno); 69 panic("enabling signal stack failed, errno = %d\n", errno);
60 } 70 }
61 71
62 void remove_sigstack(void) 72 void remove_sigstack(void)
63 { 73 {
64 stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE, 74 stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE,
65 .ss_sp = NULL, 75 .ss_sp = NULL,
66 .ss_size = 0 }); 76 .ss_size = 0 });
67 77
68 if(sigaltstack(&stack, NULL) != 0) 78 if(sigaltstack(&stack, NULL) != 0)
69 panic("disabling signal stack failed, errno = %d\n", errno); 79 panic("disabling signal stack failed, errno = %d\n", errno);
70 } 80 }
71 81
72 void set_handler(int sig, void (*handler)(int), int flags, ...) 82 void set_handler(int sig, void (*handler)(int), int flags, ...)
73 { 83 {
74 struct sigaction action; 84 struct sigaction action;
75 va_list ap; 85 va_list ap;
76 int mask; 86 int mask;
77 87
78 va_start(ap, flags); 88 va_start(ap, flags);
79 action.sa_handler = handler; 89 action.sa_handler = handler;
80 sigemptyset(&action.sa_mask); 90 sigemptyset(&action.sa_mask);
81 while((mask = va_arg(ap, int)) != -1){ 91 while((mask = va_arg(ap, int)) != -1){
82 sigaddset(&action.sa_mask, mask); 92 sigaddset(&action.sa_mask, mask);
83 } 93 }
84 va_end(ap); 94 va_end(ap);
85 action.sa_flags = flags; 95 action.sa_flags = flags;
86 action.sa_restorer = NULL; 96 action.sa_restorer = NULL;
87 if(sigaction(sig, &action, NULL) < 0) 97 if(sigaction(sig, &action, NULL) < 0)
88 panic("sigaction failed"); 98 panic("sigaction failed");
89 } 99 }
90 100
91 int change_sig(int signal, int on) 101 int change_sig(int signal, int on)
92 { 102 {
93 sigset_t sigset, old; 103 sigset_t sigset, old;
94 104
95 sigemptyset(&sigset); 105 sigemptyset(&sigset);
96 sigaddset(&sigset, signal); 106 sigaddset(&sigset, signal);
97 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); 107 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
98 return(!sigismember(&old, signal)); 108 return(!sigismember(&old, signal));
99 } 109 }
100 110
101 /* Both here and in set/get_signal we don't touch SIGPROF, because we must not 111 /* 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 112 * disable profiling; it's safe because the profiling code does not interact
103 * with the kernel code at all.*/ 113 * with the kernel code at all.*/
104 114
105 static void change_signals(int type) 115 static void change_signals(int type)
106 { 116 {
107 sigset_t mask; 117 sigset_t mask;
108 118
109 sigemptyset(&mask); 119 sigemptyset(&mask);
110 sigaddset(&mask, SIGVTALRM); 120 sigaddset(&mask, SIGVTALRM);
111 sigaddset(&mask, SIGALRM); 121 sigaddset(&mask, SIGALRM);
112 sigaddset(&mask, SIGIO); 122 sigaddset(&mask, SIGIO);
113 if(sigprocmask(type, &mask, NULL) < 0) 123 if(sigprocmask(type, &mask, NULL) < 0)
114 panic("Failed to change signal mask - errno = %d", errno); 124 panic("Failed to change signal mask - errno = %d", errno);
115 } 125 }
116 126
117 void block_signals(void) 127 void block_signals(void)
118 { 128 {
119 change_signals(SIG_BLOCK); 129 change_signals(SIG_BLOCK);
120 } 130 }
121 131
122 void unblock_signals(void) 132 void unblock_signals(void)
123 { 133 {
124 change_signals(SIG_UNBLOCK); 134 change_signals(SIG_UNBLOCK);
125 } 135 }
126 136
127 /* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled 137 /* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
128 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to 138 * 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 139 * 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 140 * profiling is not thread-safe, then that is not my problem. We can disable
131 * profiling when SMP is enabled in that case. 141 * profiling when SMP is enabled in that case.
132 */ 142 */
133 #define SIGIO_BIT 0 143 #define SIGIO_BIT 0
134 #define SIGVTALRM_BIT 1 144 #define SIGVTALRM_BIT 1
135 145
136 static int enable_mask(sigset_t *mask) 146 static int enable_mask(sigset_t *mask)
137 { 147 {
138 int sigs; 148 int sigs;
139 149
140 sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT; 150 sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
141 sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT; 151 sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
142 sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT; 152 sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
143 return(sigs); 153 return(sigs);
144 } 154 }
145 155
146 int get_signals(void) 156 int get_signals(void)
147 { 157 {
148 sigset_t mask; 158 sigset_t mask;
149 159
150 if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0) 160 if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
151 panic("Failed to get signal mask"); 161 panic("Failed to get signal mask");
152 return(enable_mask(&mask)); 162 return(enable_mask(&mask));
153 } 163 }
154 164
155 int set_signals(int enable) 165 int set_signals(int enable)
156 { 166 {
157 sigset_t mask; 167 sigset_t mask;
158 int ret; 168 int ret;
159 169
160 sigemptyset(&mask); 170 sigemptyset(&mask);
161 if(enable & (1 << SIGIO_BIT)) 171 if(enable & (1 << SIGIO_BIT))
162 sigaddset(&mask, SIGIO); 172 sigaddset(&mask, SIGIO);
163 if(enable & (1 << SIGVTALRM_BIT)){ 173 if(enable & (1 << SIGVTALRM_BIT)){
164 sigaddset(&mask, SIGVTALRM); 174 sigaddset(&mask, SIGVTALRM);
165 sigaddset(&mask, SIGALRM); 175 sigaddset(&mask, SIGALRM);
166 } 176 }
167 177
168 /* This is safe - sigprocmask is guaranteed to copy locally the 178 /* 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 179 * value of new_set, do his work and then, at the end, write to
170 * old_set. 180 * old_set.
171 */ 181 */
172 if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0) 182 if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
173 panic("Failed to enable signals"); 183 panic("Failed to enable signals");
174 ret = enable_mask(&mask); 184 ret = enable_mask(&mask);
175 sigemptyset(&mask); 185 sigemptyset(&mask);
176 if((enable & (1 << SIGIO_BIT)) == 0) 186 if((enable & (1 << SIGIO_BIT)) == 0)
177 sigaddset(&mask, SIGIO); 187 sigaddset(&mask, SIGIO);
178 if((enable & (1 << SIGVTALRM_BIT)) == 0){ 188 if((enable & (1 << SIGVTALRM_BIT)) == 0){
179 sigaddset(&mask, SIGVTALRM); 189 sigaddset(&mask, SIGVTALRM);
180 sigaddset(&mask, SIGALRM); 190 sigaddset(&mask, SIGALRM);
181 } 191 }
182 if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0) 192 if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
183 panic("Failed to block signals"); 193 panic("Failed to block signals");
184 194
185 return(ret); 195 return(ret);
186 } 196 }