No empty .Rs/.Re
[netbsd-mini2440.git] / sys / compat / svr4 / svr4_signal.c
blob98fc72b05fc833ad794312e3e2f0399f4f118bc6
1 /* $NetBSD: svr4_signal.c,v 1.63 2008/04/24 18:39:23 ad Exp $ */
3 /*-
4 * Copyright (c) 1994, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas and by Charles M. Hannum.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: svr4_signal.c,v 1.63 2008/04/24 18:39:23 ad Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/namei.h>
38 #include <sys/proc.h>
39 #include <sys/filedesc.h>
40 #include <sys/ioctl.h>
41 #include <sys/mount.h>
42 #include <sys/kernel.h>
43 #include <sys/signal.h>
44 #include <sys/signalvar.h>
45 #include <sys/malloc.h>
46 #include <sys/wait.h>
48 #include <sys/syscallargs.h>
50 #include <uvm/uvm_extern.h>
52 #include <compat/svr4/svr4_types.h>
53 #include <compat/svr4/svr4_signal.h>
54 #include <compat/svr4/svr4_lwp.h>
55 #include <compat/svr4/svr4_ucontext.h>
56 #include <compat/svr4/svr4_syscallargs.h>
57 #include <compat/svr4/svr4_util.h>
59 #include <compat/common/compat_sigaltstack.h>
61 #define svr4_sigmask(n) (1 << (((n) - 1) & 31))
62 #define svr4_sigword(n) (((n) - 1) >> 5)
63 #define svr4_sigemptyset(s) memset((s), 0, sizeof(*(s)))
64 #define svr4_sigismember(s, n) ((s)->bits[svr4_sigword(n)] & svr4_sigmask(n))
65 #define svr4_sigaddset(s, n) ((s)->bits[svr4_sigword(n)] |= svr4_sigmask(n))
67 static inline void svr4_sigfillset(svr4_sigset_t *);
68 void svr4_to_native_sigaction(const struct svr4_sigaction *,
69 struct sigaction *);
70 void native_to_svr4_sigaction(const struct sigaction *,
71 struct svr4_sigaction *);
73 extern const int native_to_svr4_signo[];
74 extern const int svr4_to_native_signo[];
76 static inline void
77 svr4_sigfillset(svr4_sigset_t *s)
79 int i;
81 svr4_sigemptyset(s);
82 for (i = 1; i < SVR4_NSIG; i++)
83 if (svr4_to_native_signo[i] != 0)
84 svr4_sigaddset(s, i);
87 void
88 svr4_to_native_sigset(const svr4_sigset_t *sss, sigset_t *bss)
90 int i, newsig;
92 sigemptyset(bss);
93 for (i = 1; i < SVR4_NSIG; i++) {
94 if (svr4_sigismember(sss, i)) {
95 newsig = svr4_to_native_signo[i];
96 if (newsig)
97 sigaddset(bss, newsig);
103 void
104 native_to_svr4_sigset(const sigset_t *bss, svr4_sigset_t *sss)
106 int i, newsig;
108 svr4_sigemptyset(sss);
109 for (i = 1; i < NSIG; i++) {
110 if (sigismember(bss, i)) {
111 newsig = native_to_svr4_signo[i];
112 if (newsig)
113 svr4_sigaddset(sss, newsig);
119 * XXX: Only a subset of the flags is currently implemented.
121 void
122 svr4_to_native_sigaction(const struct svr4_sigaction *ssa, struct sigaction *bsa)
125 bsa->sa_handler = (sig_t) ssa->svr4_sa_handler;
126 svr4_to_native_sigset(&ssa->svr4_sa_mask, &bsa->sa_mask);
127 bsa->sa_flags = 0;
128 if ((ssa->svr4_sa_flags & SVR4_SA_ONSTACK) != 0)
129 bsa->sa_flags |= SA_ONSTACK;
130 if ((ssa->svr4_sa_flags & SVR4_SA_RESETHAND) != 0)
131 bsa->sa_flags |= SA_RESETHAND;
132 if ((ssa->svr4_sa_flags & SVR4_SA_RESTART) != 0)
133 bsa->sa_flags |= SA_RESTART;
134 if ((ssa->svr4_sa_flags & SVR4_SA_SIGINFO) != 0)
135 bsa->sa_flags |= SA_SIGINFO;
136 if ((ssa->svr4_sa_flags & SVR4_SA_NODEFER) != 0)
137 bsa->sa_flags |= SA_NODEFER;
138 if ((ssa->svr4_sa_flags & SVR4_SA_NOCLDWAIT) != 0)
139 bsa->sa_flags |= SA_NOCLDWAIT;
140 if ((ssa->svr4_sa_flags & SVR4_SA_NOCLDSTOP) != 0)
141 bsa->sa_flags |= SA_NOCLDSTOP;
142 if ((ssa->svr4_sa_flags & ~SVR4_SA_ALLBITS) != 0) {
143 DPRINTF(("svr4_to_native_sigaction: extra bits %x ignored\n",
144 ssa->svr4_sa_flags & ~SVR4_SA_ALLBITS));
148 void
149 native_to_svr4_sigaction(const struct sigaction *bsa, struct svr4_sigaction *ssa)
152 ssa->svr4_sa_handler = (svr4_sig_t) bsa->sa_handler;
153 native_to_svr4_sigset(&bsa->sa_mask, &ssa->svr4_sa_mask);
154 ssa->svr4_sa_flags = 0;
155 if ((bsa->sa_flags & SA_ONSTACK) != 0)
156 ssa->svr4_sa_flags |= SVR4_SA_ONSTACK;
157 if ((bsa->sa_flags & SA_RESETHAND) != 0)
158 ssa->svr4_sa_flags |= SVR4_SA_RESETHAND;
159 if ((bsa->sa_flags & SA_RESTART) != 0)
160 ssa->svr4_sa_flags |= SVR4_SA_RESTART;
161 if ((bsa->sa_flags & SA_NODEFER) != 0)
162 ssa->svr4_sa_flags |= SVR4_SA_NODEFER;
163 if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
164 ssa->svr4_sa_flags |= SVR4_SA_NOCLDSTOP;
168 svr4_sys_sigaction(struct lwp *l, const struct svr4_sys_sigaction_args *uap, register_t *retval)
170 /* {
171 syscallarg(int) signum;
172 syscallarg(const struct svr4_sigaction *) nsa;
173 syscallarg(struct svr4_sigaction *) osa;
174 } */
175 struct svr4_sigaction nssa, ossa;
176 struct sigaction nbsa, obsa;
177 int error;
179 if (SCARG(uap, nsa)) {
180 error = copyin(SCARG(uap, nsa), &nssa, sizeof(nssa));
181 if (error)
182 return (error);
183 svr4_to_native_sigaction(&nssa, &nbsa);
185 error = sigaction1(l, svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))],
186 SCARG(uap, nsa) ? &nbsa : 0, SCARG(uap, osa) ? &obsa : 0,
187 NULL, 0);
188 if (error)
189 return (error);
190 if (SCARG(uap, osa)) {
191 native_to_svr4_sigaction(&obsa, &ossa);
192 error = copyout(&ossa, SCARG(uap, osa), sizeof(ossa));
193 if (error)
194 return (error);
196 return (0);
200 svr4_sys_sigaltstack(struct lwp *l, const struct svr4_sys_sigaltstack_args *uap, register_t *retval)
202 /* {
203 syscallarg(const struct svr4_sigaltstack *) nss;
204 syscallarg(struct svr4_sigaltstack *) oss;
205 } */
206 compat_sigaltstack(uap, svr4_sigaltstack,
207 SVR4_SS_ONSTACK, SVR4_SS_DISABLE);
211 * Stolen from the ibcs2 one
214 svr4_sys_signal(struct lwp *l, const struct svr4_sys_signal_args *uap, register_t *retval)
216 /* {
217 syscallarg(int) signum;
218 syscallarg(svr4_sig_t) handler;
219 } */
220 int signum = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
221 struct proc *p = l->l_proc;
222 struct sigaction nbsa, obsa;
223 sigset_t ss;
224 int error;
226 if (signum <= 0 || signum >= SVR4_NSIG)
227 return (EINVAL);
229 switch (SVR4_SIGCALL(SCARG(uap, signum))) {
230 case SVR4_SIGDEFER_MASK:
231 if (SCARG(uap, handler) == SVR4_SIG_HOLD)
232 goto sighold;
233 /* FALLTHROUGH */
235 case SVR4_SIGNAL_MASK:
236 nbsa.sa_handler = (sig_t)SCARG(uap, handler);
237 sigemptyset(&nbsa.sa_mask);
238 nbsa.sa_flags = 0;
239 error = sigaction1(l, signum, &nbsa, &obsa, NULL, 0);
240 if (error)
241 return (error);
242 *retval = (u_int)(u_long)obsa.sa_handler;
243 return (0);
245 case SVR4_SIGHOLD_MASK:
246 sighold:
247 sigemptyset(&ss);
248 sigaddset(&ss, signum);
249 mutex_enter(p->p_lock);
250 error = sigprocmask1(l, SIG_BLOCK, &ss, 0);
251 mutex_exit(p->p_lock);
252 return error;
254 case SVR4_SIGRELSE_MASK:
255 sigemptyset(&ss);
256 sigaddset(&ss, signum);
257 mutex_enter(p->p_lock);
258 error = sigprocmask1(l, SIG_UNBLOCK, &ss, 0);
259 mutex_exit(p->p_lock);
260 return error;
262 case SVR4_SIGIGNORE_MASK:
263 nbsa.sa_handler = SIG_IGN;
264 sigemptyset(&nbsa.sa_mask);
265 nbsa.sa_flags = 0;
266 return (sigaction1(l, signum, &nbsa, 0, NULL, 0));
268 case SVR4_SIGPAUSE_MASK:
269 ss = l->l_sigmask; /* XXXAD locking */
270 sigdelset(&ss, signum);
271 return (sigsuspend1(l, &ss));
273 default:
274 return (ENOSYS);
279 svr4_sys_sigprocmask(struct lwp *l, const struct svr4_sys_sigprocmask_args *uap, register_t *retval)
281 /* {
282 syscallarg(int) how;
283 syscallarg(const svr4_sigset_t *) set;
284 syscallarg(svr4_sigset_t *) oset;
285 } */
286 struct proc *p = l->l_proc;
287 svr4_sigset_t nsss, osss;
288 sigset_t nbss, obss;
289 int how;
290 int error;
293 * Initialize how to 0 to avoid a compiler warning. Note that
294 * this is safe because of the check in the default: case.
296 how = 0;
298 switch (SCARG(uap, how)) {
299 case SVR4_SIG_BLOCK:
300 how = SIG_BLOCK;
301 break;
302 case SVR4_SIG_UNBLOCK:
303 how = SIG_UNBLOCK;
304 break;
305 case SVR4_SIG_SETMASK:
306 how = SIG_SETMASK;
307 break;
308 default:
309 if (SCARG(uap, set))
310 return EINVAL;
311 break;
314 if (SCARG(uap, set)) {
315 error = copyin(SCARG(uap, set), &nsss, sizeof(nsss));
316 if (error)
317 return error;
318 svr4_to_native_sigset(&nsss, &nbss);
320 mutex_enter(p->p_lock);
321 error = sigprocmask1(l, how,
322 SCARG(uap, set) ? &nbss : NULL, SCARG(uap, oset) ? &obss : NULL);
323 mutex_exit(p->p_lock);
324 if (error)
325 return error;
326 if (SCARG(uap, oset)) {
327 native_to_svr4_sigset(&obss, &osss);
328 error = copyout(&osss, SCARG(uap, oset), sizeof(osss));
329 if (error)
330 return error;
332 return 0;
336 svr4_sys_sigpending(struct lwp *l, const struct svr4_sys_sigpending_args *uap, register_t *retval)
338 /* {
339 syscallarg(int) what;
340 syscallarg(svr4_sigset_t *) set;
341 } */
342 sigset_t bss;
343 svr4_sigset_t sss;
345 switch (SCARG(uap, what)) {
346 case 1: /* sigpending */
347 sigpending1(l, &bss);
348 native_to_svr4_sigset(&bss, &sss);
349 break;
351 case 2: /* sigfillset */
352 svr4_sigfillset(&sss);
353 break;
355 default:
356 return (EINVAL);
358 return (copyout(&sss, SCARG(uap, set), sizeof(sss)));
362 svr4_sys_sigsuspend(struct lwp *l, const struct svr4_sys_sigsuspend_args *uap, register_t *retval)
364 /* {
365 syscallarg(const svr4_sigset_t *) set;
366 } */
367 svr4_sigset_t sss;
368 sigset_t bss;
369 int error;
371 if (SCARG(uap, set)) {
372 error = copyin(SCARG(uap, set), &sss, sizeof(sss));
373 if (error)
374 return (error);
375 svr4_to_native_sigset(&sss, &bss);
378 return (sigsuspend1(l, SCARG(uap, set) ? &bss : 0));
382 svr4_sys_pause(struct lwp *l, const void *v, register_t *retval)
385 return (sigsuspend1(l, 0));
389 svr4_sys_kill(struct lwp *l, const struct svr4_sys_kill_args *uap, register_t *retval)
391 /* {
392 syscallarg(int) pid;
393 syscallarg(int) signum;
394 } */
395 struct sys_kill_args ka;
397 SCARG(&ka, pid) = SCARG(uap, pid);
398 SCARG(&ka, signum) = svr4_to_native_signo[SVR4_SIGNO(SCARG(uap, signum))];
399 return sys_kill(l, &ka, retval);
402 void
403 svr4_getcontext(struct lwp *l, struct svr4_ucontext *uc)
405 sigset_t mask;
406 struct proc *p = l->l_proc;
408 svr4_getmcontext(l, &uc->uc_mcontext, &uc->uc_flags);
409 uc->uc_link = l->l_ctxlink;
412 * The (unsupplied) definition of the `current execution stack'
413 * in the System V Interface Definition appears to allow returning
414 * the main context stack.
416 if ((l->l_sigstk.ss_flags & SS_ONSTACK) == 0) {
417 uc->uc_stack.ss_sp = (void *)USRSTACK;
418 uc->uc_stack.ss_size = ctob(p->p_vmspace->vm_ssize);
419 uc->uc_stack.ss_flags = 0; /* XXX, def. is Very Fishy */
420 } else {
421 /* Simply copy alternate signal execution stack. */
422 uc->uc_stack.ss_sp = l->l_sigstk.ss_sp;
423 uc->uc_stack.ss_size = l->l_sigstk.ss_size;
424 uc->uc_stack.ss_flags = l->l_sigstk.ss_flags;
426 (void)sigprocmask1(l, 0, NULL, &mask);
428 native_to_svr4_sigset(&mask, &uc->uc_sigmask);
429 uc->uc_flags |= _UC_SIGMASK | _UC_STACK;
434 svr4_setcontext(struct lwp *l, struct svr4_ucontext *uc)
436 struct proc *p = l->l_proc;
437 sigset_t mask;
439 if (uc->uc_flags & _UC_SIGMASK) {
440 svr4_to_native_sigset(&uc->uc_sigmask, &mask);
441 mutex_enter(p->p_lock);
442 sigprocmask1(l, SIG_SETMASK, &mask, NULL);
443 mutex_exit(p->p_lock);
446 /* Ignore the stack; see comment in svr4_getcontext. */
448 l->l_ctxlink = uc->uc_link;
449 svr4_setmcontext(l, &uc->uc_mcontext, uc->uc_flags);
451 return EJUSTRETURN;
455 svr4_sys_context(struct lwp *l, const struct svr4_sys_context_args *uap, register_t *retval)
457 /* {
458 syscallarg(int) func;
459 syscallarg(struct svr4_ucontext *) uc;
460 } */
461 int error;
462 svr4_ucontext_t uc;
463 *retval = 0;
465 switch (SCARG(uap, func)) {
466 case SVR4_GETCONTEXT:
467 DPRINTF(("getcontext(%p)\n", SCARG(uap, uc)));
468 svr4_getcontext(l, &uc);
469 return (copyout(&uc, SCARG(uap, uc), sizeof (*SCARG(uap, uc))));
472 case SVR4_SETCONTEXT:
473 DPRINTF(("setcontext(%p)\n", SCARG(uap, uc)));
474 error = copyin(SCARG(uap, uc), &uc, sizeof (uc));
475 if (error)
476 return (error);
477 svr4_setcontext(l, &uc);
478 return EJUSTRETURN;
480 default:
481 DPRINTF(("context(%d, %p)\n", SCARG(uap, func),
482 SCARG(uap, uc)));
483 return ENOSYS;