2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
14 #include "user_util.h"
15 #include "kern_util.h"
17 #include "signal_user.h"
18 #include "signal_kern.h"
19 #include "sysdep/sigcontext.h"
20 #include "sigcontext.h"
22 void set_sigstack(void *sig_stack
, int size
)
24 stack_t stack
= ((stack_t
) { .ss_flags
= 0,
25 .ss_sp
= (__ptr_t
) sig_stack
,
26 .ss_size
= size
- sizeof(void *) });
28 if(sigaltstack(&stack
, NULL
) != 0)
29 panic("enabling signal stack failed, errno = %d\n", errno
);
32 void set_handler(int sig
, void (*handler
)(int), int flags
, ...)
34 struct sigaction action
;
39 action
.sa_handler
= handler
;
40 sigemptyset(&action
.sa_mask
);
41 while((mask
= va_arg(ap
, int)) != -1){
42 sigaddset(&action
.sa_mask
, mask
);
44 action
.sa_flags
= flags
;
45 action
.sa_restorer
= NULL
;
46 if(sigaction(sig
, &action
, NULL
) < 0)
47 panic("sigaction failed");
50 int change_sig(int signal
, int on
)
55 sigaddset(&sigset
, signal
);
56 sigprocmask(on
? SIG_UNBLOCK
: SIG_BLOCK
, &sigset
, &old
);
57 return(!sigismember(&old
, signal
));
60 static void change_signals(int type
)
65 sigaddset(&mask
, SIGVTALRM
);
66 sigaddset(&mask
, SIGALRM
);
67 sigaddset(&mask
, SIGIO
);
68 sigaddset(&mask
, SIGPROF
);
69 if(sigprocmask(type
, &mask
, NULL
) < 0)
70 panic("Failed to change signal mask - errno = %d", errno
);
73 void block_signals(void)
75 change_signals(SIG_BLOCK
);
78 void unblock_signals(void)
80 change_signals(SIG_UNBLOCK
);
83 /* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
84 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
85 * be able to profile all of UML, not just the non-critical sections. If
86 * profiling is not thread-safe, then that is not my problem. We can disable
87 * profiling when SMP is enabled in that case.
90 #define SIGVTALRM_BIT 1
92 static int enable_mask(sigset_t
*mask
)
96 sigs
= sigismember(mask
, SIGIO
) ? 0 : 1 << SIGIO_BIT
;
97 sigs
|= sigismember(mask
, SIGVTALRM
) ? 0 : 1 << SIGVTALRM_BIT
;
98 sigs
|= sigismember(mask
, SIGALRM
) ? 0 : 1 << SIGVTALRM_BIT
;
102 int get_signals(void)
106 if(sigprocmask(SIG_SETMASK
, NULL
, &mask
) < 0)
107 panic("Failed to get signal mask");
108 return(enable_mask(&mask
));
111 int set_signals(int enable
)
117 if(enable
& (1 << SIGIO_BIT
))
118 sigaddset(&mask
, SIGIO
);
119 if(enable
& (1 << SIGVTALRM_BIT
)){
120 sigaddset(&mask
, SIGVTALRM
);
121 sigaddset(&mask
, SIGALRM
);
124 /* This is safe - sigprocmask is guaranteed to copy locally the
125 * value of new_set, do his work and then, at the end, write to
128 if(sigprocmask(SIG_UNBLOCK
, &mask
, &mask
) < 0)
129 panic("Failed to enable signals");
130 ret
= enable_mask(&mask
);
132 if((enable
& (1 << SIGIO_BIT
)) == 0)
133 sigaddset(&mask
, SIGIO
);
134 if((enable
& (1 << SIGVTALRM_BIT
)) == 0){
135 sigaddset(&mask
, SIGVTALRM
);
136 sigaddset(&mask
, SIGALRM
);
138 if(sigprocmask(SIG_BLOCK
, &mask
, NULL
) < 0)
139 panic("Failed to block signals");
145 * Overrides for Emacs so that we follow Linus's tabbing style.
146 * Emacs will notice this stuff at the end of the file and automatically
147 * adjust the settings for this buffer only. This must remain at the end
149 * ---------------------------------------------------------------------------
151 * c-file-style: "linux"