Annotation of src/sys/kern/sys_sig.c, Revision 1.42.10.1
1.42.10.1! martin 1: /* $NetBSD: sys_sig.c,v 1.42 2014/02/14 16:35:11 christos Exp $ */
1.2 ad 2:
3: /*-
1.14 ad 4: * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
1.2 ad 5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Andrew Doran.
9: *
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.
18: *
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.
30: */
31:
32: /*
33: * Copyright (c) 1982, 1986, 1989, 1991, 1993
34: * The Regents of the University of California. All rights reserved.
35: * (c) UNIX System Laboratories, Inc.
36: * All or some portions of this file are derived from material licensed
37: * to the University of California by American Telephone and Telegraph
38: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
39: * the permission of UNIX System Laboratories, Inc.
40: *
41: * Redistribution and use in source and binary forms, with or without
42: * modification, are permitted provided that the following conditions
43: * are met:
44: * 1. Redistributions of source code must retain the above copyright
45: * notice, this list of conditions and the following disclaimer.
46: * 2. Redistributions in binary form must reproduce the above copyright
47: * notice, this list of conditions and the following disclaimer in the
48: * documentation and/or other materials provided with the distribution.
49: * 3. Neither the name of the University nor the names of its contributors
50: * may be used to endorse or promote products derived from this software
51: * without specific prior written permission.
52: *
53: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63: * SUCH DAMAGE.
64: *
65: * @(#)kern_sig.c 8.14 (Berkeley) 5/14/95
66: */
67:
68: #include <sys/cdefs.h>
1.42.10.1! martin 69: __KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.42 2014/02/14 16:35:11 christos Exp $");
1.2 ad 70:
71: #include <sys/param.h>
72: #include <sys/kernel.h>
73: #include <sys/signalvar.h>
74: #include <sys/proc.h>
75: #include <sys/pool.h>
76: #include <sys/syscallargs.h>
77: #include <sys/kauth.h>
78: #include <sys/wait.h>
79: #include <sys/kmem.h>
1.19 ad 80: #include <sys/module.h>
1.2 ad 81:
82: int
1.25 rmind 83: sys___sigaction_sigtramp(struct lwp *l,
84: const struct sys___sigaction_sigtramp_args *uap, register_t *retval)
1.2 ad 85: {
1.9 dsl 86: /* {
1.2 ad 87: syscallarg(int) signum;
88: syscallarg(const struct sigaction *) nsa;
89: syscallarg(struct sigaction *) osa;
90: syscallarg(void *) tramp;
91: syscallarg(int) vers;
1.9 dsl 92: } */
1.2 ad 93: struct sigaction nsa, osa;
94: int error;
95:
96: if (SCARG(uap, nsa)) {
97: error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa));
98: if (error)
99: return (error);
100: }
101: error = sigaction1(l, SCARG(uap, signum),
102: SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0,
103: SCARG(uap, tramp), SCARG(uap, vers));
104: if (error)
105: return (error);
106: if (SCARG(uap, osa)) {
107: error = copyout(&osa, SCARG(uap, osa), sizeof(osa));
108: if (error)
109: return (error);
110: }
1.25 rmind 111: return 0;
1.2 ad 112: }
113:
114: /*
115: * Manipulate signal mask. Note that we receive new mask, not pointer, and
116: * return old mask as return value; the library stub does the rest.
117: */
118: int
1.25 rmind 119: sys___sigprocmask14(struct lwp *l, const struct sys___sigprocmask14_args *uap,
120: register_t *retval)
1.2 ad 121: {
1.9 dsl 122: /* {
1.2 ad 123: syscallarg(int) how;
124: syscallarg(const sigset_t *) set;
125: syscallarg(sigset_t *) oset;
1.9 dsl 126: } */
1.2 ad 127: struct proc *p = l->l_proc;
128: sigset_t nss, oss;
129: int error;
130:
131: if (SCARG(uap, set)) {
132: error = copyin(SCARG(uap, set), &nss, sizeof(nss));
133: if (error)
1.25 rmind 134: return error;
1.2 ad 135: }
1.14 ad 136: mutex_enter(p->p_lock);
1.2 ad 137: error = sigprocmask1(l, SCARG(uap, how),
138: SCARG(uap, set) ? &nss : 0, SCARG(uap, oset) ? &oss : 0);
1.14 ad 139: mutex_exit(p->p_lock);
1.2 ad 140: if (error)
1.25 rmind 141: return error;
1.2 ad 142: if (SCARG(uap, oset)) {
143: error = copyout(&oss, SCARG(uap, oset), sizeof(oss));
144: if (error)
1.25 rmind 145: return error;
1.2 ad 146: }
1.25 rmind 147: return 0;
1.2 ad 148: }
149:
150: int
1.25 rmind 151: sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap,
152: register_t *retval)
1.2 ad 153: {
1.9 dsl 154: /* {
1.2 ad 155: syscallarg(sigset_t *) set;
1.9 dsl 156: } */
1.2 ad 157: sigset_t ss;
158:
159: sigpending1(l, &ss);
1.25 rmind 160: return copyout(&ss, SCARG(uap, set), sizeof(ss));
1.2 ad 161: }
162:
163: /*
164: * Suspend process until signal, providing mask to be set in the meantime.
165: * Note nonstandard calling convention: libc stub passes mask, not pointer,
166: * to save a copyin.
167: */
168: int
1.25 rmind 169: sys___sigsuspend14(struct lwp *l, const struct sys___sigsuspend14_args *uap,
170: register_t *retval)
1.2 ad 171: {
1.9 dsl 172: /* {
1.2 ad 173: syscallarg(const sigset_t *) set;
1.9 dsl 174: } */
1.2 ad 175: sigset_t ss;
176: int error;
177:
178: if (SCARG(uap, set)) {
179: error = copyin(SCARG(uap, set), &ss, sizeof(ss));
180: if (error)
1.25 rmind 181: return error;
1.2 ad 182: }
1.25 rmind 183: return sigsuspend1(l, SCARG(uap, set) ? &ss : 0);
1.2 ad 184: }
185:
186: int
1.25 rmind 187: sys___sigaltstack14(struct lwp *l, const struct sys___sigaltstack14_args *uap,
188: register_t *retval)
1.2 ad 189: {
1.9 dsl 190: /* {
1.2 ad 191: syscallarg(const struct sigaltstack *) nss;
192: syscallarg(struct sigaltstack *) oss;
1.9 dsl 193: } */
1.2 ad 194: struct sigaltstack nss, oss;
195: int error;
196:
197: if (SCARG(uap, nss)) {
198: error = copyin(SCARG(uap, nss), &nss, sizeof(nss));
199: if (error)
1.25 rmind 200: return error;
1.2 ad 201: }
202: error = sigaltstack1(l,
203: SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
204: if (error)
1.25 rmind 205: return error;
1.2 ad 206: if (SCARG(uap, oss)) {
207: error = copyout(&oss, SCARG(uap, oss), sizeof(oss));
208: if (error)
1.25 rmind 209: return error;
1.2 ad 210: }
1.25 rmind 211: return 0;
1.2 ad 212: }
213:
1.30 christos 214:
215: static int
216: kill1(struct lwp *l, pid_t pid, ksiginfo_t *ksi, register_t *retval)
1.2 ad 217: {
218: int error;
1.30 christos 219: struct proc *p;
1.2 ad 220:
1.30 christos 221: if ((u_int)ksi->ksi_signo >= NSIG)
1.25 rmind 222: return EINVAL;
1.30 christos 223:
1.32 martin 224: if (pid != l->l_proc->p_pid) {
225: if (ksi->ksi_pid != l->l_proc->p_pid)
226: return EPERM;
227:
228: if (ksi->ksi_uid != kauth_cred_geteuid(l->l_cred))
229: return EPERM;
230:
231: switch (ksi->ksi_code) {
232: case SI_USER:
233: case SI_QUEUE:
234: break;
235: default:
236: return EPERM;
237: }
238: }
1.30 christos 239:
240: if (pid > 0) {
1.2 ad 241: /* kill single process */
1.13 ad 242: mutex_enter(proc_lock);
1.38 christos 243: p = proc_find_raw(pid);
244: if (p == NULL || (p->p_stat != SACTIVE && p->p_stat != SSTOP)) {
1.13 ad 245: mutex_exit(proc_lock);
1.38 christos 246: /* IEEE Std 1003.1-2001: return success for zombies */
247: return p ? 0 : ESRCH;
1.13 ad 248: }
1.14 ad 249: mutex_enter(p->p_lock);
1.2 ad 250: error = kauth_authorize_process(l->l_cred,
1.30 christos 251: KAUTH_PROCESS_SIGNAL, p, KAUTH_ARG(ksi->ksi_signo),
1.2 ad 252: NULL, NULL);
1.30 christos 253: if (!error && ksi->ksi_signo) {
254: kpsignal2(p, ksi);
1.2 ad 255: }
1.14 ad 256: mutex_exit(p->p_lock);
1.13 ad 257: mutex_exit(proc_lock);
1.25 rmind 258: return error;
1.2 ad 259: }
1.30 christos 260:
261: switch (pid) {
1.2 ad 262: case -1: /* broadcast signal */
1.30 christos 263: return killpg1(l, ksi, 0, 1);
1.2 ad 264: case 0: /* signal own process group */
1.30 christos 265: return killpg1(l, ksi, 0, 0);
1.2 ad 266: default: /* negative explicit process group */
1.30 christos 267: return killpg1(l, ksi, -pid, 0);
1.2 ad 268: }
269: /* NOTREACHED */
270: }
271:
272: int
1.30 christos 273: sys_sigqueueinfo(struct lwp *l, const struct sys_sigqueueinfo_args *uap,
274: register_t *retval)
275: {
276: /* {
277: syscallarg(pid_t int) pid;
278: syscallarg(const siginfo_t *) info;
279: } */
280: ksiginfo_t ksi;
281: int error;
282:
283: KSI_INIT(&ksi);
284:
285: if ((error = copyin(&SCARG(uap, info)->_info, &ksi.ksi_info,
286: sizeof(ksi.ksi_info))) != 0)
287: return error;
288:
289: return kill1(l, SCARG(uap, pid), &ksi, retval);
290: }
291:
292: int
293: sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval)
294: {
295: /* {
296: syscallarg(pid_t) pid;
297: syscallarg(int) signum;
298: } */
299: ksiginfo_t ksi;
300:
301: KSI_INIT(&ksi);
302:
303: ksi.ksi_signo = SCARG(uap, signum);
304: ksi.ksi_code = SI_USER;
305: ksi.ksi_pid = l->l_proc->p_pid;
306: ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
307:
308: return kill1(l, SCARG(uap, pid), &ksi, retval);
309: }
310:
311: int
1.25 rmind 312: sys_getcontext(struct lwp *l, const struct sys_getcontext_args *uap,
313: register_t *retval)
1.2 ad 314: {
1.9 dsl 315: /* {
1.2 ad 316: syscallarg(struct __ucontext *) ucp;
1.9 dsl 317: } */
1.2 ad 318: struct proc *p = l->l_proc;
319: ucontext_t uc;
320:
1.31 joerg 321: memset(&uc, 0, sizeof(uc));
322:
1.14 ad 323: mutex_enter(p->p_lock);
1.2 ad 324: getucontext(l, &uc);
1.14 ad 325: mutex_exit(p->p_lock);
1.2 ad 326:
1.25 rmind 327: return copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp)));
1.2 ad 328: }
329:
330: int
1.25 rmind 331: sys_setcontext(struct lwp *l, const struct sys_setcontext_args *uap,
332: register_t *retval)
1.2 ad 333: {
1.9 dsl 334: /* {
1.2 ad 335: syscallarg(const ucontext_t *) ucp;
1.9 dsl 336: } */
1.2 ad 337: struct proc *p = l->l_proc;
338: ucontext_t uc;
339: int error;
340:
341: error = copyin(SCARG(uap, ucp), &uc, sizeof (uc));
342: if (error)
1.25 rmind 343: return error;
344: if ((uc.uc_flags & _UC_CPU) == 0)
345: return EINVAL;
1.14 ad 346: mutex_enter(p->p_lock);
1.2 ad 347: error = setucontext(l, &uc);
1.14 ad 348: mutex_exit(p->p_lock);
1.2 ad 349: if (error)
1.25 rmind 350: return error;
1.2 ad 351:
1.25 rmind 352: return EJUSTRETURN;
1.2 ad 353: }
354:
355: /*
356: * sigtimedwait(2) system call, used also for implementation
357: * of sigwaitinfo() and sigwait().
358: *
359: * This only handles single LWP in signal wait. libpthread provides
360: * it's own sigtimedwait() wrapper to DTRT WRT individual threads.
361: */
362: int
1.21 christos 363: sys_____sigtimedwait50(struct lwp *l,
364: const struct sys_____sigtimedwait50_args *uap, register_t *retval)
1.2 ad 365: {
366:
1.36 christos 367: return sigtimedwait1(l, uap, retval, copyin, copyout, copyin, copyout);
1.2 ad 368: }
369:
370: int
371: sigaction1(struct lwp *l, int signum, const struct sigaction *nsa,
372: struct sigaction *osa, const void *tramp, int vers)
373: {
374: struct proc *p;
375: struct sigacts *ps;
376: sigset_t tset;
377: int prop, error;
378: ksiginfoq_t kq;
1.20 ad 379: static bool v0v1valid;
1.2 ad 380:
381: if (signum <= 0 || signum >= NSIG)
1.25 rmind 382: return EINVAL;
1.2 ad 383:
384: p = l->l_proc;
385: error = 0;
386: ksiginfo_queue_init(&kq);
387:
388: /*
389: * Trampoline ABI version 0 is reserved for the legacy kernel
390: * provided on-stack trampoline. Conversely, if we are using a
391: * non-0 ABI version, we must have a trampoline. Only validate the
1.42 christos 392: * vers if a new sigaction was supplied and there was an actual
393: * handler specified (not SIG_IGN or SIG_DFL), which don't require
394: * a trampoline. Emulations use legacy kernel trampolines with
395: * version 0, alternatively check for that too.
1.19 ad 396: *
397: * If version < 2, we try to autoload the compat module. Note
398: * that we interlock with the unload check in compat_modcmd()
1.29 pgoyette 399: * using kernconfig_lock. If the autoload fails, we don't try it
1.19 ad 400: * again for this process.
401: */
1.42 christos 402: if (nsa != NULL && nsa->sa_handler != SIG_IGN
403: && nsa->sa_handler != SIG_DFL) {
1.39 christos 404: if (__predict_false(vers < 2)) {
405: if (p->p_flag & PK_32)
406: v0v1valid = true;
407: else if ((p->p_lflag & PL_SIGCOMPAT) == 0) {
408: kernconfig_lock();
409: if (sendsig_sigcontext_vec == NULL) {
410: (void)module_autoload("compat",
411: MODULE_CLASS_ANY);
412: }
413: if (sendsig_sigcontext_vec != NULL) {
414: /*
415: * We need to remember if the
416: * sigcontext method may be useable,
417: * because libc may use it even
418: * if siginfo is available.
419: */
420: v0v1valid = true;
421: }
422: mutex_enter(proc_lock);
1.20 ad 423: /*
1.39 christos 424: * Prevent unload of compat module while
425: * this process remains.
1.20 ad 426: */
1.39 christos 427: p->p_lflag |= PL_SIGCOMPAT;
428: mutex_exit(proc_lock);
429: kernconfig_unlock();
1.20 ad 430: }
1.19 ad 431: }
432:
1.20 ad 433: switch (vers) {
434: case 0:
435: /* sigcontext, kernel supplied trampoline. */
436: if (tramp != NULL || !v0v1valid) {
437: return EINVAL;
438: }
439: break;
440: case 1:
441: /* sigcontext, user supplied trampoline. */
442: if (tramp == NULL || !v0v1valid) {
443: return EINVAL;
444: }
445: break;
446: case 2:
447: case 3:
448: /* siginfo, user supplied trampoline. */
449: if (tramp == NULL) {
450: return EINVAL;
451: }
452: break;
453: default:
454: return EINVAL;
455: }
1.2 ad 456: }
457:
1.14 ad 458: mutex_enter(p->p_lock);
1.2 ad 459:
460: ps = p->p_sigacts;
461: if (osa)
462: *osa = SIGACTION_PS(ps, signum);
463: if (!nsa)
464: goto out;
465:
466: prop = sigprop[signum];
467: if ((nsa->sa_flags & ~SA_ALLBITS) || (prop & SA_CANTMASK)) {
468: error = EINVAL;
469: goto out;
470: }
471:
472: SIGACTION_PS(ps, signum) = *nsa;
473: ps->sa_sigdesc[signum].sd_tramp = tramp;
474: ps->sa_sigdesc[signum].sd_vers = vers;
475: sigminusset(&sigcantmask, &SIGACTION_PS(ps, signum).sa_mask);
476:
477: if ((prop & SA_NORESET) != 0)
478: SIGACTION_PS(ps, signum).sa_flags &= ~SA_RESETHAND;
479:
480: if (signum == SIGCHLD) {
481: if (nsa->sa_flags & SA_NOCLDSTOP)
482: p->p_sflag |= PS_NOCLDSTOP;
483: else
484: p->p_sflag &= ~PS_NOCLDSTOP;
485: if (nsa->sa_flags & SA_NOCLDWAIT) {
486: /*
487: * Paranoia: since SA_NOCLDWAIT is implemented by
488: * reparenting the dying child to PID 1 (and trust
489: * it to reap the zombie), PID 1 itself is forbidden
490: * to set SA_NOCLDWAIT.
491: */
492: if (p->p_pid == 1)
1.4 pavel 493: p->p_flag &= ~PK_NOCLDWAIT;
1.2 ad 494: else
1.4 pavel 495: p->p_flag |= PK_NOCLDWAIT;
1.2 ad 496: } else
1.4 pavel 497: p->p_flag &= ~PK_NOCLDWAIT;
1.2 ad 498:
499: if (nsa->sa_handler == SIG_IGN) {
500: /*
501: * Paranoia: same as above.
502: */
503: if (p->p_pid == 1)
1.4 pavel 504: p->p_flag &= ~PK_CLDSIGIGN;
1.2 ad 505: else
1.4 pavel 506: p->p_flag |= PK_CLDSIGIGN;
1.2 ad 507: } else
1.4 pavel 508: p->p_flag &= ~PK_CLDSIGIGN;
1.2 ad 509: }
510:
511: if ((nsa->sa_flags & SA_NODEFER) == 0)
512: sigaddset(&SIGACTION_PS(ps, signum).sa_mask, signum);
513: else
514: sigdelset(&SIGACTION_PS(ps, signum).sa_mask, signum);
515:
516: /*
517: * Set bit in p_sigctx.ps_sigignore for signals that are set to
518: * SIG_IGN, and for signals set to SIG_DFL where the default is to
519: * ignore. However, don't put SIGCONT in p_sigctx.ps_sigignore, as
520: * we have to restart the process.
521: */
522: if (nsa->sa_handler == SIG_IGN ||
523: (nsa->sa_handler == SIG_DFL && (prop & SA_IGNORE) != 0)) {
524: /* Never to be seen again. */
525: sigemptyset(&tset);
526: sigaddset(&tset, signum);
527: sigclearall(p, &tset, &kq);
528: if (signum != SIGCONT) {
529: /* Easier in psignal */
530: sigaddset(&p->p_sigctx.ps_sigignore, signum);
531: }
532: sigdelset(&p->p_sigctx.ps_sigcatch, signum);
533: } else {
534: sigdelset(&p->p_sigctx.ps_sigignore, signum);
535: if (nsa->sa_handler == SIG_DFL)
536: sigdelset(&p->p_sigctx.ps_sigcatch, signum);
537: else
538: sigaddset(&p->p_sigctx.ps_sigcatch, signum);
539: }
540:
541: /*
542: * Previously held signals may now have become visible. Ensure that
543: * we check for them before returning to userspace.
544: */
1.6 ad 545: if (sigispending(l, 0)) {
546: lwp_lock(l);
547: l->l_flag |= LW_PENDSIG;
548: lwp_unlock(l);
549: }
1.25 rmind 550: out:
1.14 ad 551: mutex_exit(p->p_lock);
1.2 ad 552: ksiginfo_queue_drain(&kq);
553:
1.25 rmind 554: return error;
1.2 ad 555: }
556:
557: int
558: sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
559: {
1.37 rmind 560: sigset_t *mask = &l->l_sigmask;
561: bool more;
1.2 ad 562:
1.37 rmind 563: KASSERT(mutex_owned(l->l_proc->p_lock));
1.2 ad 564:
1.37 rmind 565: if (oss) {
1.17 wrstuden 566: *oss = *mask;
1.2 ad 567: }
568:
1.37 rmind 569: if (nss == NULL) {
570: return 0;
571: }
572:
573: switch (how) {
574: case SIG_BLOCK:
575: sigplusset(nss, mask);
576: more = false;
577: break;
578: case SIG_UNBLOCK:
579: sigminusset(nss, mask);
580: more = true;
581: break;
582: case SIG_SETMASK:
583: *mask = *nss;
584: more = true;
585: break;
586: default:
587: return EINVAL;
588: }
589: sigminusset(&sigcantmask, mask);
590: if (more && sigispending(l, 0)) {
591: /*
592: * Check for pending signals on return to user.
593: */
594: lwp_lock(l);
595: l->l_flag |= LW_PENDSIG;
596: lwp_unlock(l);
597: }
1.25 rmind 598: return 0;
1.2 ad 599: }
600:
601: void
602: sigpending1(struct lwp *l, sigset_t *ss)
603: {
604: struct proc *p = l->l_proc;
605:
1.14 ad 606: mutex_enter(p->p_lock);
1.2 ad 607: *ss = l->l_sigpend.sp_set;
608: sigplusset(&p->p_sigpend.sp_set, ss);
1.14 ad 609: mutex_exit(p->p_lock);
1.2 ad 610: }
611:
1.33 christos 612: void
613: sigsuspendsetup(struct lwp *l, const sigset_t *ss)
1.2 ad 614: {
1.25 rmind 615: struct proc *p = l->l_proc;
1.2 ad 616:
1.33 christos 617: /*
618: * When returning from sigsuspend/pselect/pollts, we want
619: * the old mask to be restored after the
620: * signal handler has finished. Thus, we
621: * save it here and mark the sigctx structure
622: * to indicate this.
623: */
624: mutex_enter(p->p_lock);
625: l->l_sigrestore = 1;
626: l->l_sigoldmask = l->l_sigmask;
627: l->l_sigmask = *ss;
628: sigminusset(&sigcantmask, &l->l_sigmask);
1.2 ad 629:
1.33 christos 630: /* Check for pending signals when sleeping. */
631: if (sigispending(l, 0)) {
632: lwp_lock(l);
633: l->l_flag |= LW_PENDSIG;
634: lwp_unlock(l);
1.2 ad 635: }
1.33 christos 636: mutex_exit(p->p_lock);
637: }
638:
1.34 christos 639: void
640: sigsuspendteardown(struct lwp *l)
641: {
642: struct proc *p = l->l_proc;
643:
644: mutex_enter(p->p_lock);
1.35 christos 645: /* Check for pending signals when sleeping. */
1.34 christos 646: if (l->l_sigrestore) {
1.35 christos 647: if (sigispending(l, 0)) {
648: lwp_lock(l);
649: l->l_flag |= LW_PENDSIG;
650: lwp_unlock(l);
651: } else {
652: l->l_sigrestore = 0;
653: l->l_sigmask = l->l_sigoldmask;
654: }
1.34 christos 655: }
656: mutex_exit(p->p_lock);
657: }
658:
1.33 christos 659: int
660: sigsuspend1(struct lwp *l, const sigset_t *ss)
661: {
662:
663: if (ss)
664: sigsuspendsetup(l, ss);
1.2 ad 665:
1.5 thorpej 666: while (kpause("pause", true, 0, NULL) == 0)
1.2 ad 667: ;
668:
669: /* always return EINTR rather than ERESTART... */
1.25 rmind 670: return EINTR;
1.2 ad 671: }
672:
673: int
674: sigaltstack1(struct lwp *l, const struct sigaltstack *nss,
1.25 rmind 675: struct sigaltstack *oss)
1.2 ad 676: {
677: struct proc *p = l->l_proc;
678: int error = 0;
679:
1.14 ad 680: mutex_enter(p->p_lock);
1.2 ad 681:
682: if (oss)
683: *oss = l->l_sigstk;
684:
685: if (nss) {
686: if (nss->ss_flags & ~SS_ALLBITS)
687: error = EINVAL;
688: else if (nss->ss_flags & SS_DISABLE) {
689: if (l->l_sigstk.ss_flags & SS_ONSTACK)
690: error = EINVAL;
691: } else if (nss->ss_size < MINSIGSTKSZ)
692: error = ENOMEM;
693:
694: if (!error)
695: l->l_sigstk = *nss;
696: }
697:
1.14 ad 698: mutex_exit(p->p_lock);
1.2 ad 699:
1.25 rmind 700: return error;
1.2 ad 701: }
702:
703: int
1.26 pooka 704: sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
1.36 christos 705: register_t *retval, copyin_t fetchss, copyout_t storeinf, copyin_t fetchts,
706: copyout_t storets)
1.2 ad 707: {
1.9 dsl 708: /* {
1.2 ad 709: syscallarg(const sigset_t *) set;
710: syscallarg(siginfo_t *) info;
711: syscallarg(struct timespec *) timeout;
1.9 dsl 712: } */
1.2 ad 713: struct proc *p = l->l_proc;
1.25 rmind 714: int error, signum, timo;
1.2 ad 715: struct timespec ts, tsstart, tsnow;
1.24 rmind 716: ksiginfo_t ksi;
1.2 ad 717:
718: /*
719: * Calculate timeout, if it was specified.
1.40 apb 720: *
721: * NULL pointer means an infinite timeout.
722: * {.tv_sec = 0, .tv_nsec = 0} means do not block.
1.2 ad 723: */
724: if (SCARG(uap, timeout)) {
1.25 rmind 725: error = (*fetchts)(SCARG(uap, timeout), &ts, sizeof(ts));
1.23 christos 726: if (error)
727: return error;
1.2 ad 728:
1.23 christos 729: if ((error = itimespecfix(&ts)) != 0)
730: return error;
1.2 ad 731:
1.23 christos 732: timo = tstohz(&ts);
1.41 apb 733: if (timo == 0) {
734: if (ts.tv_sec == 0 && ts.tv_nsec == 0)
735: timo = -1; /* do not block */
736: else
737: timo = 1; /* the shortest possible timeout */
738: }
1.2 ad 739:
740: /*
741: * Remember current uptime, it would be used in
742: * ECANCELED/ERESTART case.
743: */
744: getnanouptime(&tsstart);
1.25 rmind 745: } else {
746: memset(&tsstart, 0, sizeof(tsstart)); /* XXXgcc */
1.41 apb 747: timo = 0; /* infinite timeout */
1.2 ad 748: }
749:
1.36 christos 750: error = (*fetchss)(SCARG(uap, set), &l->l_sigwaitset,
1.2 ad 751: sizeof(l->l_sigwaitset));
1.25 rmind 752: if (error)
753: return error;
1.2 ad 754:
755: /*
756: * Silently ignore SA_CANTMASK signals. psignal1() would ignore
757: * SA_CANTMASK signals in waitset, we do this only for the below
758: * siglist check.
759: */
760: sigminusset(&sigcantmask, &l->l_sigwaitset);
761:
1.42.10.1! martin 762: memset(&ksi.ksi_info, 0, sizeof(ksi.ksi_info));
! 763:
1.14 ad 764: mutex_enter(p->p_lock);
1.2 ad 765:
1.25 rmind 766: /* Check for pending signals in the process, if no - then in LWP. */
1.24 rmind 767: if ((signum = sigget(&p->p_sigpend, &ksi, 0, &l->l_sigwaitset)) == 0)
768: signum = sigget(&l->l_sigpend, &ksi, 0, &l->l_sigwaitset);
1.2 ad 769:
770: if (signum != 0) {
1.25 rmind 771: /* If found a pending signal, just copy it out to the user. */
1.14 ad 772: mutex_exit(p->p_lock);
1.2 ad 773: goto out;
774: }
775:
1.41 apb 776: if (timo < 0) {
777: /* If not allowed to block, return an error */
778: mutex_exit(p->p_lock);
779: return EAGAIN;
780: }
781:
1.2 ad 782: /*
1.25 rmind 783: * Set up the sigwait list and wait for signal to arrive.
784: * We can either be woken up or time out.
1.2 ad 785: */
1.24 rmind 786: l->l_sigwaited = &ksi;
1.2 ad 787: LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter);
1.14 ad 788: error = cv_timedwait_sig(&l->l_sigcv, p->p_lock, timo);
1.2 ad 789:
790: /*
1.25 rmind 791: * Need to find out if we woke as a result of _lwp_wakeup() or a
1.2 ad 792: * signal outside our wait set.
793: */
794: if (l->l_sigwaited != NULL) {
795: if (error == EINTR) {
1.25 rmind 796: /* Wakeup via _lwp_wakeup(). */
1.2 ad 797: error = ECANCELED;
798: } else if (!error) {
1.25 rmind 799: /* Spurious wakeup - arrange for syscall restart. */
1.2 ad 800: error = ERESTART;
801: }
802: l->l_sigwaited = NULL;
803: LIST_REMOVE(l, l_sigwaiter);
804: }
1.14 ad 805: mutex_exit(p->p_lock);
1.2 ad 806:
807: /*
808: * If the sleep was interrupted (either by signal or wakeup), update
809: * the timeout and copyout new value back. It would be used when
810: * the syscall would be restarted or called again.
811: */
812: if (timo && (error == ERESTART || error == ECANCELED)) {
813: getnanouptime(&tsnow);
814:
1.25 rmind 815: /* Compute how much time has passed since start. */
1.2 ad 816: timespecsub(&tsnow, &tsstart, &tsnow);
1.25 rmind 817:
818: /* Substract passed time from timeout. */
1.2 ad 819: timespecsub(&ts, &tsnow, &ts);
820:
821: if (ts.tv_sec < 0)
822: error = EAGAIN;
823: else {
1.25 rmind 824: /* Copy updated timeout to userland. */
825: error = (*storets)(&ts, SCARG(uap, timeout),
1.2 ad 826: sizeof(ts));
827: }
828: }
1.25 rmind 829: out:
1.2 ad 830: /*
831: * If a signal from the wait set arrived, copy it to userland.
832: * Copy only the used part of siginfo, the padding part is
833: * left unchanged (userland is not supposed to touch it anyway).
834: */
1.27 drochner 835: if (error == 0 && SCARG(uap, info)) {
1.25 rmind 836: error = (*storeinf)(&ksi.ksi_info, SCARG(uap, info),
1.24 rmind 837: sizeof(ksi.ksi_info));
1.25 rmind 838: }
1.27 drochner 839: if (error == 0)
840: *retval = ksi.ksi_info._signo;
1.2 ad 841: return error;
842: }
CVSweb <webmaster@jp.NetBSD.org>