Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
422 | giacomo | 1 | #ifndef _LINUX_SIGNAL_H |
2 | #define _LINUX_SIGNAL_H |
||
3 | |||
4 | #include <linux/list.h> |
||
5 | #include <linux/spinlock.h> |
||
6 | #include <asm/signal.h> |
||
7 | #include <asm/siginfo.h> |
||
8 | |||
9 | #ifdef __KERNEL__ |
||
10 | /* |
||
11 | * Real Time signals may be queued. |
||
12 | */ |
||
13 | |||
14 | struct sigqueue { |
||
15 | struct list_head list; |
||
16 | spinlock_t *lock; |
||
17 | int flags; |
||
18 | siginfo_t info; |
||
19 | }; |
||
20 | |||
21 | /* flags values. */ |
||
22 | #define SIGQUEUE_PREALLOC 1 |
||
23 | |||
24 | struct sigpending { |
||
25 | struct list_head list; |
||
26 | sigset_t signal; |
||
27 | }; |
||
28 | |||
29 | /* |
||
30 | * Define some primitives to manipulate sigset_t. |
||
31 | */ |
||
32 | |||
33 | #ifndef __HAVE_ARCH_SIG_BITOPS |
||
34 | #include <linux/bitops.h> |
||
35 | |||
36 | /* We don't use <linux/bitops.h> for these because there is no need to |
||
37 | be atomic. */ |
||
38 | static inline void sigaddset(sigset_t *set, int _sig) |
||
39 | { |
||
40 | unsigned long sig = _sig - 1; |
||
41 | if (_NSIG_WORDS == 1) |
||
42 | set->sig[0] |= 1UL << sig; |
||
43 | else |
||
44 | set->sig[sig / _NSIG_BPW] |= 1UL << (sig % _NSIG_BPW); |
||
45 | } |
||
46 | |||
47 | static inline void sigdelset(sigset_t *set, int _sig) |
||
48 | { |
||
49 | unsigned long sig = _sig - 1; |
||
50 | if (_NSIG_WORDS == 1) |
||
51 | set->sig[0] &= ~(1UL << sig); |
||
52 | else |
||
53 | set->sig[sig / _NSIG_BPW] &= ~(1UL << (sig % _NSIG_BPW)); |
||
54 | } |
||
55 | |||
56 | static inline int sigismember(sigset_t *set, int _sig) |
||
57 | { |
||
58 | unsigned long sig = _sig - 1; |
||
59 | if (_NSIG_WORDS == 1) |
||
60 | return 1 & (set->sig[0] >> sig); |
||
61 | else |
||
62 | return 1 & (set->sig[sig / _NSIG_BPW] >> (sig % _NSIG_BPW)); |
||
63 | } |
||
64 | |||
65 | static inline int sigfindinword(unsigned long word) |
||
66 | { |
||
67 | return ffz(~word); |
||
68 | } |
||
69 | |||
70 | #endif /* __HAVE_ARCH_SIG_BITOPS */ |
||
71 | |||
72 | #define sigmask(sig) (1UL << ((sig) - 1)) |
||
73 | |||
74 | #ifndef __HAVE_ARCH_SIG_SETOPS |
||
75 | #include <linux/string.h> |
||
76 | |||
77 | #define _SIG_SET_BINOP(name, op) \ |
||
78 | static inline void name(sigset_t *r, const sigset_t *a, const sigset_t *b) \ |
||
79 | { \ |
||
80 | extern void _NSIG_WORDS_is_unsupported_size(void); \ |
||
81 | unsigned long a0, a1, a2, a3, b0, b1, b2, b3; \ |
||
82 | \ |
||
83 | switch (_NSIG_WORDS) { \ |
||
84 | case 4: \ |
||
85 | a3 = a->sig[3]; a2 = a->sig[2]; \ |
||
86 | b3 = b->sig[3]; b2 = b->sig[2]; \ |
||
87 | r->sig[3] = op(a3, b3); \ |
||
88 | r->sig[2] = op(a2, b2); \ |
||
89 | case 2: \ |
||
90 | a1 = a->sig[1]; b1 = b->sig[1]; \ |
||
91 | r->sig[1] = op(a1, b1); \ |
||
92 | case 1: \ |
||
93 | a0 = a->sig[0]; b0 = b->sig[0]; \ |
||
94 | r->sig[0] = op(a0, b0); \ |
||
95 | break; \ |
||
96 | default: \ |
||
97 | _NSIG_WORDS_is_unsupported_size(); \ |
||
98 | } \ |
||
99 | } |
||
100 | |||
101 | #define _sig_or(x,y) ((x) | (y)) |
||
102 | _SIG_SET_BINOP(sigorsets, _sig_or) |
||
103 | |||
104 | #define _sig_and(x,y) ((x) & (y)) |
||
105 | _SIG_SET_BINOP(sigandsets, _sig_and) |
||
106 | |||
107 | #define _sig_nand(x,y) ((x) & ~(y)) |
||
108 | _SIG_SET_BINOP(signandsets, _sig_nand) |
||
109 | |||
110 | #undef _SIG_SET_BINOP |
||
111 | #undef _sig_or |
||
112 | #undef _sig_and |
||
113 | #undef _sig_nand |
||
114 | |||
115 | #define _SIG_SET_OP(name, op) \ |
||
116 | static inline void name(sigset_t *set) \ |
||
117 | { \ |
||
118 | extern void _NSIG_WORDS_is_unsupported_size(void); \ |
||
119 | \ |
||
120 | switch (_NSIG_WORDS) { \ |
||
121 | case 4: set->sig[3] = op(set->sig[3]); \ |
||
122 | set->sig[2] = op(set->sig[2]); \ |
||
123 | case 2: set->sig[1] = op(set->sig[1]); \ |
||
124 | case 1: set->sig[0] = op(set->sig[0]); \ |
||
125 | break; \ |
||
126 | default: \ |
||
127 | _NSIG_WORDS_is_unsupported_size(); \ |
||
128 | } \ |
||
129 | } |
||
130 | |||
131 | #define _sig_not(x) (~(x)) |
||
132 | _SIG_SET_OP(signotset, _sig_not) |
||
133 | |||
134 | #undef _SIG_SET_OP |
||
135 | #undef _sig_not |
||
136 | |||
137 | static inline void sigemptyset(sigset_t *set) |
||
138 | { |
||
139 | switch (_NSIG_WORDS) { |
||
140 | default: |
||
141 | memset(set, 0, sizeof(sigset_t)); |
||
142 | break; |
||
143 | case 2: set->sig[1] = 0; |
||
144 | case 1: set->sig[0] = 0; |
||
145 | break; |
||
146 | } |
||
147 | } |
||
148 | |||
149 | static inline void sigfillset(sigset_t *set) |
||
150 | { |
||
151 | switch (_NSIG_WORDS) { |
||
152 | default: |
||
153 | memset(set, -1, sizeof(sigset_t)); |
||
154 | break; |
||
155 | case 2: set->sig[1] = -1; |
||
156 | case 1: set->sig[0] = -1; |
||
157 | break; |
||
158 | } |
||
159 | } |
||
160 | |||
161 | /* Some extensions for manipulating the low 32 signals in particular. */ |
||
162 | |||
163 | static inline void sigaddsetmask(sigset_t *set, unsigned long mask) |
||
164 | { |
||
165 | set->sig[0] |= mask; |
||
166 | } |
||
167 | |||
168 | static inline void sigdelsetmask(sigset_t *set, unsigned long mask) |
||
169 | { |
||
170 | set->sig[0] &= ~mask; |
||
171 | } |
||
172 | |||
173 | static inline int sigtestsetmask(sigset_t *set, unsigned long mask) |
||
174 | { |
||
175 | return (set->sig[0] & mask) != 0; |
||
176 | } |
||
177 | |||
178 | static inline void siginitset(sigset_t *set, unsigned long mask) |
||
179 | { |
||
180 | set->sig[0] = mask; |
||
181 | switch (_NSIG_WORDS) { |
||
182 | default: |
||
183 | memset(&set->sig[1], 0, sizeof(long)*(_NSIG_WORDS-1)); |
||
184 | break; |
||
185 | case 2: set->sig[1] = 0; |
||
186 | case 1: ; |
||
187 | } |
||
188 | } |
||
189 | |||
190 | static inline void siginitsetinv(sigset_t *set, unsigned long mask) |
||
191 | { |
||
192 | set->sig[0] = ~mask; |
||
193 | switch (_NSIG_WORDS) { |
||
194 | default: |
||
195 | memset(&set->sig[1], -1, sizeof(long)*(_NSIG_WORDS-1)); |
||
196 | break; |
||
197 | case 2: set->sig[1] = -1; |
||
198 | case 1: ; |
||
199 | } |
||
200 | } |
||
201 | |||
202 | #endif /* __HAVE_ARCH_SIG_SETOPS */ |
||
203 | |||
204 | static inline void init_sigpending(struct sigpending *sig) |
||
205 | { |
||
206 | sigemptyset(&sig->signal); |
||
207 | INIT_LIST_HEAD(&sig->list); |
||
208 | } |
||
209 | |||
210 | extern long do_sigpending(void __user *, unsigned long); |
||
211 | extern int sigprocmask(int, sigset_t *, sigset_t *); |
||
212 | |||
213 | #ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER |
||
214 | struct pt_regs; |
||
215 | extern int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs, void *cookie); |
||
216 | #endif |
||
217 | |||
218 | #endif /* __KERNEL__ */ |
||
219 | |||
220 | #endif /* _LINUX_SIGNAL_H */ |