initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / um / kernel / signal_user.c
blob74a69e491e000cf7400ccdc6d65534188afe968d
1 /*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
6 #include <stdio.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <signal.h>
10 #include <errno.h>
11 #include <stdarg.h>
12 #include <string.h>
13 #include <sys/mman.h>
14 #include "user_util.h"
15 #include "kern_util.h"
16 #include "user.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;
35 va_list ap;
36 int mask;
38 va_start(ap, flags);
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)
52 sigset_t sigset, old;
54 sigemptyset(&sigset);
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)
62 sigset_t mask;
64 sigemptyset(&mask);
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.
89 #define SIGIO_BIT 0
90 #define SIGVTALRM_BIT 1
92 static int enable_mask(sigset_t *mask)
94 int sigs;
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;
99 return(sigs);
102 int get_signals(void)
104 sigset_t mask;
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)
113 sigset_t mask;
114 int ret;
116 sigemptyset(&mask);
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
126 * old_set.
128 if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
129 panic("Failed to enable signals");
130 ret = enable_mask(&mask);
131 sigemptyset(&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");
141 return(ret);
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
148 * of the file.
149 * ---------------------------------------------------------------------------
150 * Local variables:
151 * c-file-style: "linux"
152 * End: