signals.c revision 1.2.4.5 1 1.2.4.4 rmind /* $NetBSD: signals.c,v 1.2.4.5 2011/05/31 03:05:11 rmind Exp $ */
2 1.2.4.2 rmind
3 1.2.4.4 rmind /*-
4 1.2.4.4 rmind * Copyright (c) 2010, 2011 Antti Kantee. All Rights Reserved.
5 1.2.4.2 rmind *
6 1.2.4.2 rmind * Redistribution and use in source and binary forms, with or without
7 1.2.4.2 rmind * modification, are permitted provided that the following conditions
8 1.2.4.2 rmind * are met:
9 1.2.4.2 rmind * 1. Redistributions of source code must retain the above copyright
10 1.2.4.2 rmind * notice, this list of conditions and the following disclaimer.
11 1.2.4.2 rmind * 2. Redistributions in binary form must reproduce the above copyright
12 1.2.4.2 rmind * notice, this list of conditions and the following disclaimer in the
13 1.2.4.2 rmind * documentation and/or other materials provided with the distribution.
14 1.2.4.2 rmind *
15 1.2.4.2 rmind * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 1.2.4.2 rmind * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 1.2.4.2 rmind * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 1.2.4.2 rmind * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.2.4.2 rmind * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.2.4.2 rmind * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 1.2.4.2 rmind * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.2.4.2 rmind * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.2.4.2 rmind * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.2.4.2 rmind * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.2.4.2 rmind * SUCH DAMAGE.
26 1.2.4.2 rmind */
27 1.2.4.2 rmind
28 1.2.4.2 rmind #include <sys/cdefs.h>
29 1.2.4.4 rmind __KERNEL_RCSID(0, "$NetBSD: signals.c,v 1.2.4.5 2011/05/31 03:05:11 rmind Exp $");
30 1.2.4.2 rmind
31 1.2.4.2 rmind #include <sys/param.h>
32 1.2.4.2 rmind #include <sys/atomic.h>
33 1.2.4.2 rmind #include <sys/event.h>
34 1.2.4.2 rmind #include <sys/proc.h>
35 1.2.4.2 rmind #include <sys/signal.h>
36 1.2.4.2 rmind
37 1.2.4.2 rmind #include <rump/rump.h>
38 1.2.4.2 rmind #include <rump/rumpuser.h>
39 1.2.4.2 rmind
40 1.2.4.4 rmind #include "rump_private.h"
41 1.2.4.2 rmind #include "rumpkern_if_priv.h"
42 1.2.4.2 rmind
43 1.2.4.4 rmind const struct filterops sig_filtops = {
44 1.2.4.4 rmind .f_attach = (void *)eopnotsupp,
45 1.2.4.4 rmind };
46 1.2.4.4 rmind
47 1.2.4.2 rmind sigset_t sigcantmask;
48 1.2.4.2 rmind
49 1.2.4.4 rmind static void
50 1.2.4.4 rmind pgrp_apply(struct pgrp *pgrp, int signo, void (*apply)(struct proc *p, int))
51 1.2.4.4 rmind {
52 1.2.4.4 rmind struct proc *p;
53 1.2.4.4 rmind
54 1.2.4.4 rmind KASSERT(mutex_owned(proc_lock));
55 1.2.4.4 rmind
56 1.2.4.4 rmind LIST_FOREACH(p, &pgrp->pg_members, p_pglist) {
57 1.2.4.4 rmind mutex_enter(p->p_lock);
58 1.2.4.4 rmind apply(p, signo);
59 1.2.4.4 rmind mutex_exit(p->p_lock);
60 1.2.4.4 rmind }
61 1.2.4.4 rmind }
62 1.2.4.4 rmind
63 1.2.4.2 rmind /* RUMP_SIGMODEL_PANIC */
64 1.2.4.2 rmind
65 1.2.4.2 rmind static void
66 1.2.4.4 rmind rumpsig_panic(struct proc *p, int signo)
67 1.2.4.2 rmind {
68 1.2.4.2 rmind
69 1.2.4.2 rmind switch (signo) {
70 1.2.4.2 rmind case SIGSYS:
71 1.2.4.4 rmind case SIGPIPE:
72 1.2.4.2 rmind break;
73 1.2.4.2 rmind default:
74 1.2.4.2 rmind panic("unhandled signal %d", signo);
75 1.2.4.2 rmind }
76 1.2.4.2 rmind }
77 1.2.4.2 rmind
78 1.2.4.2 rmind /* RUMP_SIGMODEL_IGNORE */
79 1.2.4.2 rmind
80 1.2.4.2 rmind static void
81 1.2.4.4 rmind rumpsig_ignore(struct proc *p, int signo)
82 1.2.4.2 rmind {
83 1.2.4.2 rmind
84 1.2.4.2 rmind return;
85 1.2.4.2 rmind }
86 1.2.4.2 rmind
87 1.2.4.2 rmind /* RUMP_SIGMODEL_HOST */
88 1.2.4.2 rmind
89 1.2.4.2 rmind static void
90 1.2.4.4 rmind rumpsig_host(struct proc *p, int signo)
91 1.2.4.2 rmind {
92 1.2.4.2 rmind int error;
93 1.2.4.2 rmind
94 1.2.4.4 rmind rumpuser_kill(p->p_pid, signo, &error);
95 1.2.4.2 rmind }
96 1.2.4.2 rmind
97 1.2.4.2 rmind /* RUMP_SIGMODEL_RAISE */
98 1.2.4.2 rmind
99 1.2.4.2 rmind static void
100 1.2.4.4 rmind rumpsig_raise(struct proc *p, int signo)
101 1.2.4.2 rmind {
102 1.2.4.4 rmind int error = 0;
103 1.2.4.2 rmind
104 1.2.4.4 rmind if (RUMP_LOCALPROC_P(p)) {
105 1.2.4.4 rmind rumpuser_kill(RUMPUSER_PID_SELF, signo, &error);
106 1.2.4.4 rmind } else {
107 1.2.4.4 rmind rumpuser_sp_raise(p->p_vmspace->vm_map.pmap, signo);
108 1.2.4.4 rmind }
109 1.2.4.2 rmind }
110 1.2.4.2 rmind
111 1.2.4.4 rmind static void
112 1.2.4.4 rmind rumpsig_record(struct proc *p, int signo)
113 1.2.4.4 rmind {
114 1.2.4.2 rmind
115 1.2.4.4 rmind if (!sigismember(&p->p_sigctx.ps_sigignore, signo)) {
116 1.2.4.4 rmind sigaddset(&p->p_sigpend.sp_set, signo);
117 1.2.4.4 rmind }
118 1.2.4.4 rmind }
119 1.2.4.4 rmind
120 1.2.4.4 rmind typedef void (*rumpsig_fn)(struct proc *, int);
121 1.2.4.4 rmind
122 1.2.4.4 rmind static rumpsig_fn rumpsig = rumpsig_raise;
123 1.2.4.2 rmind
124 1.2.4.2 rmind /*
125 1.2.4.2 rmind * Set signal delivery model. It would be nice if we could
126 1.2.4.2 rmind * take a functional argument. But then we'd need some
127 1.2.4.2 rmind * OS independent way to represent a signal number and also
128 1.2.4.2 rmind * a method for easy processing (parsing is boring).
129 1.2.4.2 rmind *
130 1.2.4.2 rmind * Plus, upcalls from the rump kernel into process space except
131 1.2.4.2 rmind * via rumpuser is a somewhat gray area now.
132 1.2.4.2 rmind */
133 1.2.4.2 rmind void
134 1.2.4.2 rmind rump_boot_setsigmodel(enum rump_sigmodel model)
135 1.2.4.2 rmind {
136 1.2.4.2 rmind
137 1.2.4.2 rmind switch (model) {
138 1.2.4.2 rmind case RUMP_SIGMODEL_PANIC:
139 1.2.4.4 rmind rumpsig = rumpsig_panic;
140 1.2.4.2 rmind break;
141 1.2.4.2 rmind case RUMP_SIGMODEL_IGNORE:
142 1.2.4.4 rmind rumpsig = rumpsig_ignore;
143 1.2.4.2 rmind break;
144 1.2.4.2 rmind case RUMP_SIGMODEL_HOST:
145 1.2.4.4 rmind rumpsig = rumpsig_host;
146 1.2.4.2 rmind break;
147 1.2.4.2 rmind case RUMP_SIGMODEL_RAISE:
148 1.2.4.4 rmind rumpsig = rumpsig_raise;
149 1.2.4.4 rmind break;
150 1.2.4.4 rmind case RUMP_SIGMODEL_RECORD:
151 1.2.4.4 rmind rumpsig = rumpsig_record;
152 1.2.4.2 rmind break;
153 1.2.4.2 rmind }
154 1.2.4.2 rmind }
155 1.2.4.2 rmind
156 1.2.4.2 rmind void
157 1.2.4.2 rmind psignal(struct proc *p, int sig)
158 1.2.4.2 rmind {
159 1.2.4.2 rmind
160 1.2.4.4 rmind rumpsig(p, sig);
161 1.2.4.2 rmind }
162 1.2.4.2 rmind
163 1.2.4.2 rmind void
164 1.2.4.2 rmind pgsignal(struct pgrp *pgrp, int sig, int checktty)
165 1.2.4.2 rmind {
166 1.2.4.2 rmind
167 1.2.4.4 rmind pgrp_apply(pgrp, sig, rumpsig);
168 1.2.4.2 rmind }
169 1.2.4.2 rmind
170 1.2.4.2 rmind void
171 1.2.4.2 rmind kpsignal(struct proc *p, ksiginfo_t *ksi, void *data)
172 1.2.4.2 rmind {
173 1.2.4.2 rmind
174 1.2.4.4 rmind rumpsig(p, ksi->ksi_signo);
175 1.2.4.2 rmind }
176 1.2.4.2 rmind
177 1.2.4.2 rmind void
178 1.2.4.2 rmind kpgsignal(struct pgrp *pgrp, ksiginfo_t *ksi, void *data, int checkctty)
179 1.2.4.2 rmind {
180 1.2.4.2 rmind
181 1.2.4.4 rmind pgrp_apply(pgrp, ksi->ksi_signo, rumpsig);
182 1.2.4.2 rmind }
183 1.2.4.2 rmind
184 1.2.4.2 rmind int
185 1.2.4.2 rmind sigispending(struct lwp *l, int signo)
186 1.2.4.2 rmind {
187 1.2.4.4 rmind struct proc *p = l->l_proc;
188 1.2.4.4 rmind sigset_t tset;
189 1.2.4.2 rmind
190 1.2.4.4 rmind tset = p->p_sigpend.sp_set;
191 1.2.4.4 rmind
192 1.2.4.4 rmind if (signo == 0) {
193 1.2.4.4 rmind if (firstsig(&tset) != 0)
194 1.2.4.4 rmind return EINTR;
195 1.2.4.4 rmind } else if (sigismember(&tset, signo))
196 1.2.4.4 rmind return EINTR;
197 1.2.4.2 rmind return 0;
198 1.2.4.2 rmind }
199 1.2.4.2 rmind
200 1.2.4.2 rmind void
201 1.2.4.2 rmind sigpending1(struct lwp *l, sigset_t *ss)
202 1.2.4.2 rmind {
203 1.2.4.4 rmind struct proc *p = l->l_proc;
204 1.2.4.2 rmind
205 1.2.4.4 rmind mutex_enter(p->p_lock);
206 1.2.4.4 rmind *ss = l->l_proc->p_sigpend.sp_set;
207 1.2.4.4 rmind mutex_exit(p->p_lock);
208 1.2.4.2 rmind }
209 1.2.4.2 rmind
210 1.2.4.2 rmind int
211 1.2.4.2 rmind sigismasked(struct lwp *l, int sig)
212 1.2.4.2 rmind {
213 1.2.4.2 rmind
214 1.2.4.4 rmind return sigismember(&l->l_proc->p_sigctx.ps_sigignore, sig);
215 1.2.4.4 rmind }
216 1.2.4.4 rmind
217 1.2.4.4 rmind void
218 1.2.4.4 rmind sigclear(sigpend_t *sp, const sigset_t *mask, ksiginfoq_t *kq)
219 1.2.4.4 rmind {
220 1.2.4.4 rmind
221 1.2.4.4 rmind if (mask == NULL)
222 1.2.4.4 rmind sigemptyset(&sp->sp_set);
223 1.2.4.4 rmind else
224 1.2.4.4 rmind sigminusset(mask, &sp->sp_set);
225 1.2.4.2 rmind }
226 1.2.4.2 rmind
227 1.2.4.2 rmind void
228 1.2.4.2 rmind sigclearall(struct proc *p, const sigset_t *mask, ksiginfoq_t *kq)
229 1.2.4.2 rmind {
230 1.2.4.2 rmind
231 1.2.4.4 rmind /* don't assert proc lock, hence callable from user context */
232 1.2.4.4 rmind sigclear(&p->p_sigpend, mask, kq);
233 1.2.4.2 rmind }
234 1.2.4.2 rmind
235 1.2.4.2 rmind void
236 1.2.4.2 rmind ksiginfo_queue_drain0(ksiginfoq_t *kq)
237 1.2.4.2 rmind {
238 1.2.4.2 rmind
239 1.2.4.2 rmind if (!(CIRCLEQ_EMPTY(kq)))
240 1.2.4.2 rmind panic("how did that get there?");
241 1.2.4.2 rmind }
242 1.2.4.3 rmind
243 1.2.4.4 rmind int
244 1.2.4.4 rmind sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
245 1.2.4.4 rmind {
246 1.2.4.4 rmind sigset_t *mask = &l->l_proc->p_sigctx.ps_sigignore;
247 1.2.4.4 rmind
248 1.2.4.4 rmind KASSERT(mutex_owned(l->l_proc->p_lock));
249 1.2.4.4 rmind
250 1.2.4.4 rmind if (oss)
251 1.2.4.4 rmind *oss = *mask;
252 1.2.4.4 rmind
253 1.2.4.4 rmind if (nss) {
254 1.2.4.4 rmind switch (how) {
255 1.2.4.4 rmind case SIG_BLOCK:
256 1.2.4.4 rmind sigplusset(nss, mask);
257 1.2.4.4 rmind break;
258 1.2.4.4 rmind case SIG_UNBLOCK:
259 1.2.4.4 rmind sigminusset(nss, mask);
260 1.2.4.4 rmind break;
261 1.2.4.4 rmind case SIG_SETMASK:
262 1.2.4.4 rmind *mask = *nss;
263 1.2.4.4 rmind break;
264 1.2.4.4 rmind default:
265 1.2.4.4 rmind return EINVAL;
266 1.2.4.4 rmind }
267 1.2.4.4 rmind }
268 1.2.4.4 rmind
269 1.2.4.4 rmind return 0;
270 1.2.4.4 rmind }
271 1.2.4.4 rmind
272 1.2.4.3 rmind void
273 1.2.4.3 rmind siginit(struct proc *p)
274 1.2.4.3 rmind {
275 1.2.4.3 rmind
276 1.2.4.4 rmind sigemptyset(&p->p_sigctx.ps_sigignore);
277 1.2.4.4 rmind sigemptyset(&p->p_sigpend.sp_set);
278 1.2.4.3 rmind }
279 1.2.4.5 rmind
280 1.2.4.5 rmind void
281 1.2.4.5 rmind sigsuspendsetup(struct lwp *l, const sigset_t *ss)
282 1.2.4.5 rmind {
283 1.2.4.5 rmind /* XXX: Partial copy of kernel code, remove and use the kernel code. */
284 1.2.4.5 rmind struct proc *p = l->l_proc;
285 1.2.4.5 rmind
286 1.2.4.5 rmind mutex_enter(p->p_lock);
287 1.2.4.5 rmind l->l_sigrestore = 1;
288 1.2.4.5 rmind l->l_sigoldmask = l->l_sigmask;
289 1.2.4.5 rmind l->l_sigmask = *ss;
290 1.2.4.5 rmind sigminusset(&sigcantmask, &l->l_sigmask);
291 1.2.4.5 rmind mutex_exit(p->p_lock);
292 1.2.4.5 rmind }
293 1.2.4.5 rmind
294 1.2.4.5 rmind void
295 1.2.4.5 rmind sigsuspendteardown(struct lwp *l)
296 1.2.4.5 rmind {
297 1.2.4.5 rmind /* XXX: Copy of kernel code, remove and use the kernel code. */
298 1.2.4.5 rmind struct proc *p = l->l_proc;
299 1.2.4.5 rmind
300 1.2.4.5 rmind mutex_enter(p->p_lock);
301 1.2.4.5 rmind if (l->l_sigrestore) {
302 1.2.4.5 rmind l->l_sigrestore = 0;
303 1.2.4.5 rmind l->l_sigmask = l->l_sigoldmask;
304 1.2.4.5 rmind }
305 1.2.4.5 rmind mutex_exit(p->p_lock);
306 1.2.4.5 rmind }
307