[BACK]Return to sys_sig.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Annotation of src/sys/kern/sys_sig.c, Revision 1.28

1.28    ! rmind       1: /*     $NetBSD: sys_sig.c,v 1.27 2010/05/20 17:10:42 drochner 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.28    ! rmind      69: __KERNEL_RCSID(0, "$NetBSD: sys_sig.c,v 1.27 2010/05/20 17:10:42 drochner 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>
1.17      wrstuden   76: #include <sys/sa.h>
                     77: #include <sys/savar.h>
1.2       ad         78: #include <sys/syscallargs.h>
                     79: #include <sys/kauth.h>
                     80: #include <sys/wait.h>
                     81: #include <sys/kmem.h>
1.19      ad         82: #include <sys/module.h>
1.2       ad         83:
                     84: int
1.25      rmind      85: sys___sigaction_sigtramp(struct lwp *l,
                     86:     const struct sys___sigaction_sigtramp_args *uap, register_t *retval)
1.2       ad         87: {
1.9       dsl        88:        /* {
1.2       ad         89:                syscallarg(int)                         signum;
                     90:                syscallarg(const struct sigaction *)    nsa;
                     91:                syscallarg(struct sigaction *)          osa;
                     92:                syscallarg(void *)                      tramp;
                     93:                syscallarg(int)                         vers;
1.9       dsl        94:        } */
1.2       ad         95:        struct sigaction nsa, osa;
                     96:        int error;
                     97:
                     98:        if (SCARG(uap, nsa)) {
                     99:                error = copyin(SCARG(uap, nsa), &nsa, sizeof(nsa));
                    100:                if (error)
                    101:                        return (error);
                    102:        }
                    103:        error = sigaction1(l, SCARG(uap, signum),
                    104:            SCARG(uap, nsa) ? &nsa : 0, SCARG(uap, osa) ? &osa : 0,
                    105:            SCARG(uap, tramp), SCARG(uap, vers));
                    106:        if (error)
                    107:                return (error);
                    108:        if (SCARG(uap, osa)) {
                    109:                error = copyout(&osa, SCARG(uap, osa), sizeof(osa));
                    110:                if (error)
                    111:                        return (error);
                    112:        }
1.25      rmind     113:        return 0;
1.2       ad        114: }
                    115:
                    116: /*
                    117:  * Manipulate signal mask.  Note that we receive new mask, not pointer, and
                    118:  * return old mask as return value; the library stub does the rest.
                    119:  */
                    120: int
1.25      rmind     121: sys___sigprocmask14(struct lwp *l, const struct sys___sigprocmask14_args *uap,
                    122:     register_t *retval)
1.2       ad        123: {
1.9       dsl       124:        /* {
1.2       ad        125:                syscallarg(int)                 how;
                    126:                syscallarg(const sigset_t *)    set;
                    127:                syscallarg(sigset_t *)          oset;
1.9       dsl       128:        } */
1.2       ad        129:        struct proc     *p = l->l_proc;
                    130:        sigset_t        nss, oss;
                    131:        int             error;
                    132:
                    133:        if (SCARG(uap, set)) {
                    134:                error = copyin(SCARG(uap, set), &nss, sizeof(nss));
                    135:                if (error)
1.25      rmind     136:                        return error;
1.2       ad        137:        }
1.14      ad        138:        mutex_enter(p->p_lock);
1.2       ad        139:        error = sigprocmask1(l, SCARG(uap, how),
                    140:            SCARG(uap, set) ? &nss : 0, SCARG(uap, oset) ? &oss : 0);
1.14      ad        141:        mutex_exit(p->p_lock);
1.2       ad        142:        if (error)
1.25      rmind     143:                return error;
1.2       ad        144:        if (SCARG(uap, oset)) {
                    145:                error = copyout(&oss, SCARG(uap, oset), sizeof(oss));
                    146:                if (error)
1.25      rmind     147:                        return error;
1.2       ad        148:        }
1.25      rmind     149:        return 0;
1.2       ad        150: }
                    151:
                    152: int
1.25      rmind     153: sys___sigpending14(struct lwp *l, const struct sys___sigpending14_args *uap,
                    154:     register_t *retval)
1.2       ad        155: {
1.9       dsl       156:        /* {
1.2       ad        157:                syscallarg(sigset_t *)  set;
1.9       dsl       158:        } */
1.2       ad        159:        sigset_t ss;
                    160:
                    161:        sigpending1(l, &ss);
1.25      rmind     162:        return copyout(&ss, SCARG(uap, set), sizeof(ss));
1.2       ad        163: }
                    164:
                    165: /*
                    166:  * Suspend process until signal, providing mask to be set in the meantime.
                    167:  * Note nonstandard calling convention: libc stub passes mask, not pointer,
                    168:  * to save a copyin.
                    169:  */
                    170: int
1.25      rmind     171: sys___sigsuspend14(struct lwp *l, const struct sys___sigsuspend14_args *uap,
                    172:     register_t *retval)
1.2       ad        173: {
1.9       dsl       174:        /* {
1.2       ad        175:                syscallarg(const sigset_t *)    set;
1.9       dsl       176:        } */
1.2       ad        177:        sigset_t        ss;
                    178:        int             error;
                    179:
                    180:        if (SCARG(uap, set)) {
                    181:                error = copyin(SCARG(uap, set), &ss, sizeof(ss));
                    182:                if (error)
1.25      rmind     183:                        return error;
1.2       ad        184:        }
1.25      rmind     185:        return sigsuspend1(l, SCARG(uap, set) ? &ss : 0);
1.2       ad        186: }
                    187:
                    188: int
1.25      rmind     189: sys___sigaltstack14(struct lwp *l, const struct sys___sigaltstack14_args *uap,
                    190:     register_t *retval)
1.2       ad        191: {
1.9       dsl       192:        /* {
1.2       ad        193:                syscallarg(const struct sigaltstack *)  nss;
                    194:                syscallarg(struct sigaltstack *)        oss;
1.9       dsl       195:        } */
1.2       ad        196:        struct sigaltstack      nss, oss;
                    197:        int                     error;
                    198:
                    199:        if (SCARG(uap, nss)) {
                    200:                error = copyin(SCARG(uap, nss), &nss, sizeof(nss));
                    201:                if (error)
1.25      rmind     202:                        return error;
1.2       ad        203:        }
                    204:        error = sigaltstack1(l,
                    205:            SCARG(uap, nss) ? &nss : 0, SCARG(uap, oss) ? &oss : 0);
                    206:        if (error)
1.25      rmind     207:                return error;
1.2       ad        208:        if (SCARG(uap, oss)) {
                    209:                error = copyout(&oss, SCARG(uap, oss), sizeof(oss));
                    210:                if (error)
1.25      rmind     211:                        return error;
1.2       ad        212:        }
1.25      rmind     213:        return 0;
1.2       ad        214: }
                    215:
                    216: int
1.9       dsl       217: sys_kill(struct lwp *l, const struct sys_kill_args *uap, register_t *retval)
1.2       ad        218: {
1.9       dsl       219:        /* {
1.2       ad        220:                syscallarg(int) pid;
                    221:                syscallarg(int) signum;
1.9       dsl       222:        } */
1.2       ad        223:        struct proc     *p;
                    224:        ksiginfo_t      ksi;
                    225:        int signum = SCARG(uap, signum);
                    226:        int error;
                    227:
                    228:        if ((u_int)signum >= NSIG)
1.25      rmind     229:                return EINVAL;
1.2       ad        230:        KSI_INIT(&ksi);
                    231:        ksi.ksi_signo = signum;
                    232:        ksi.ksi_code = SI_USER;
                    233:        ksi.ksi_pid = l->l_proc->p_pid;
                    234:        ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
                    235:        if (SCARG(uap, pid) > 0) {
                    236:                /* kill single process */
1.13      ad        237:                mutex_enter(proc_lock);
1.28    ! rmind     238:                p = proc_find(SCARG(uap, pid));
        !           239:                if (p == NULL) {
1.13      ad        240:                        mutex_exit(proc_lock);
1.25      rmind     241:                        return ESRCH;
1.13      ad        242:                }
1.14      ad        243:                mutex_enter(p->p_lock);
1.2       ad        244:                error = kauth_authorize_process(l->l_cred,
1.11      elad      245:                    KAUTH_PROCESS_SIGNAL, p, KAUTH_ARG(signum),
1.2       ad        246:                    NULL, NULL);
                    247:                if (!error && signum) {
                    248:                        kpsignal2(p, &ksi);
                    249:                }
1.14      ad        250:                mutex_exit(p->p_lock);
1.13      ad        251:                mutex_exit(proc_lock);
1.25      rmind     252:                return error;
1.2       ad        253:        }
                    254:        switch (SCARG(uap, pid)) {
                    255:        case -1:                /* broadcast signal */
1.25      rmind     256:                return killpg1(l, &ksi, 0, 1);
1.2       ad        257:        case 0:                 /* signal own process group */
1.25      rmind     258:                return killpg1(l, &ksi, 0, 0);
1.2       ad        259:        default:                /* negative explicit process group */
1.25      rmind     260:                return killpg1(l, &ksi, -SCARG(uap, pid), 0);
1.2       ad        261:        }
                    262:        /* NOTREACHED */
                    263: }
                    264:
                    265: int
1.25      rmind     266: sys_getcontext(struct lwp *l, const struct sys_getcontext_args *uap,
                    267:     register_t *retval)
1.2       ad        268: {
1.9       dsl       269:        /* {
1.2       ad        270:                syscallarg(struct __ucontext *) ucp;
1.9       dsl       271:        } */
1.2       ad        272:        struct proc *p = l->l_proc;
                    273:        ucontext_t uc;
                    274:
1.14      ad        275:        mutex_enter(p->p_lock);
1.2       ad        276:        getucontext(l, &uc);
1.14      ad        277:        mutex_exit(p->p_lock);
1.2       ad        278:
1.25      rmind     279:        return copyout(&uc, SCARG(uap, ucp), sizeof (*SCARG(uap, ucp)));
1.2       ad        280: }
                    281:
                    282: int
1.25      rmind     283: sys_setcontext(struct lwp *l, const struct sys_setcontext_args *uap,
                    284:     register_t *retval)
1.2       ad        285: {
1.9       dsl       286:        /* {
1.2       ad        287:                syscallarg(const ucontext_t *) ucp;
1.9       dsl       288:        } */
1.2       ad        289:        struct proc *p = l->l_proc;
                    290:        ucontext_t uc;
                    291:        int error;
                    292:
                    293:        error = copyin(SCARG(uap, ucp), &uc, sizeof (uc));
                    294:        if (error)
1.25      rmind     295:                return error;
                    296:        if ((uc.uc_flags & _UC_CPU) == 0)
                    297:                return EINVAL;
1.14      ad        298:        mutex_enter(p->p_lock);
1.2       ad        299:        error = setucontext(l, &uc);
1.14      ad        300:        mutex_exit(p->p_lock);
1.2       ad        301:        if (error)
1.25      rmind     302:                return error;
1.2       ad        303:
1.25      rmind     304:        return EJUSTRETURN;
1.2       ad        305: }
                    306:
                    307: /*
                    308:  * sigtimedwait(2) system call, used also for implementation
                    309:  * of sigwaitinfo() and sigwait().
                    310:  *
                    311:  * This only handles single LWP in signal wait. libpthread provides
                    312:  * it's own sigtimedwait() wrapper to DTRT WRT individual threads.
                    313:  */
                    314: int
1.21      christos  315: sys_____sigtimedwait50(struct lwp *l,
                    316:     const struct sys_____sigtimedwait50_args *uap, register_t *retval)
1.2       ad        317: {
                    318:
1.26      pooka     319:        return sigtimedwait1(l, uap, retval, copyout, copyin, copyout);
1.2       ad        320: }
                    321:
                    322: int
                    323: sigaction1(struct lwp *l, int signum, const struct sigaction *nsa,
                    324:        struct sigaction *osa, const void *tramp, int vers)
                    325: {
                    326:        struct proc *p;
                    327:        struct sigacts *ps;
                    328:        sigset_t tset;
                    329:        int prop, error;
                    330:        ksiginfoq_t kq;
1.20      ad        331:        static bool v0v1valid;
1.2       ad        332:
                    333:        if (signum <= 0 || signum >= NSIG)
1.25      rmind     334:                return EINVAL;
1.2       ad        335:
                    336:        p = l->l_proc;
                    337:        error = 0;
                    338:        ksiginfo_queue_init(&kq);
                    339:
                    340:        /*
                    341:         * Trampoline ABI version 0 is reserved for the legacy kernel
                    342:         * provided on-stack trampoline.  Conversely, if we are using a
                    343:         * non-0 ABI version, we must have a trampoline.  Only validate the
                    344:         * vers if a new sigaction was supplied. Emulations use legacy
                    345:         * kernel trampolines with version 0, alternatively check for that
                    346:         * too.
1.19      ad        347:         *
                    348:         * If version < 2, we try to autoload the compat module.  Note
                    349:         * that we interlock with the unload check in compat_modcmd()
                    350:         * using module_lock.  If the autoload fails, we don't try it
                    351:         * again for this process.
                    352:         */
1.20      ad        353:        if (nsa != NULL) {
                    354:                if (__predict_false(vers < 2) &&
                    355:                    (p->p_lflag & PL_SIGCOMPAT) == 0) {
                    356:                        mutex_enter(&module_lock);
                    357:                        if (sendsig_sigcontext_vec == NULL) {
                    358:                                (void)module_autoload("compat",
                    359:                                    MODULE_CLASS_ANY);
                    360:                        }
                    361:                        if (sendsig_sigcontext_vec != NULL) {
                    362:                                /*
                    363:                                 * We need to remember if the
                    364:                                 * sigcontext method may be useable,
                    365:                                 * because libc may use it even
                    366:                                 * if siginfo is available.
                    367:                                 */
                    368:                                v0v1valid = true;
                    369:                        }
                    370:                        mutex_enter(proc_lock);
                    371:                        /*
                    372:                         * Prevent unload of compat module while
                    373:                         * this process remains.
                    374:                         */
                    375:                        p->p_lflag |= PL_SIGCOMPAT;
                    376:                        mutex_exit(proc_lock);
                    377:                        mutex_exit(&module_lock);
1.19      ad        378:                }
                    379:
1.20      ad        380:                switch (vers) {
                    381:                case 0:
                    382:                        /* sigcontext, kernel supplied trampoline. */
                    383:                        if (tramp != NULL || !v0v1valid) {
                    384:                                return EINVAL;
                    385:                        }
                    386:                        break;
                    387:                case 1:
                    388:                        /* sigcontext, user supplied trampoline. */
                    389:                        if (tramp == NULL || !v0v1valid) {
                    390:                                return EINVAL;
                    391:                        }
                    392:                        break;
                    393:                case 2:
                    394:                case 3:
                    395:                        /* siginfo, user supplied trampoline. */
                    396:                        if (tramp == NULL) {
                    397:                                return EINVAL;
                    398:                        }
                    399:                        break;
                    400:                default:
                    401:                        return EINVAL;
                    402:                }
1.2       ad        403:        }
                    404:
1.14      ad        405:        mutex_enter(p->p_lock);
1.2       ad        406:
                    407:        ps = p->p_sigacts;
                    408:        if (osa)
                    409:                *osa = SIGACTION_PS(ps, signum);
                    410:        if (!nsa)
                    411:                goto out;
                    412:
                    413:        prop = sigprop[signum];
                    414:        if ((nsa->sa_flags & ~SA_ALLBITS) || (prop & SA_CANTMASK)) {
                    415:                error = EINVAL;
                    416:                goto out;
                    417:        }
                    418:
                    419:        SIGACTION_PS(ps, signum) = *nsa;
                    420:        ps->sa_sigdesc[signum].sd_tramp = tramp;
                    421:        ps->sa_sigdesc[signum].sd_vers = vers;
                    422:        sigminusset(&sigcantmask, &SIGACTION_PS(ps, signum).sa_mask);
                    423:
                    424:        if ((prop & SA_NORESET) != 0)
                    425:                SIGACTION_PS(ps, signum).sa_flags &= ~SA_RESETHAND;
                    426:
                    427:        if (signum == SIGCHLD) {
                    428:                if (nsa->sa_flags & SA_NOCLDSTOP)
                    429:                        p->p_sflag |= PS_NOCLDSTOP;
                    430:                else
                    431:                        p->p_sflag &= ~PS_NOCLDSTOP;
                    432:                if (nsa->sa_flags & SA_NOCLDWAIT) {
                    433:                        /*
                    434:                         * Paranoia: since SA_NOCLDWAIT is implemented by
                    435:                         * reparenting the dying child to PID 1 (and trust
                    436:                         * it to reap the zombie), PID 1 itself is forbidden
                    437:                         * to set SA_NOCLDWAIT.
                    438:                         */
                    439:                        if (p->p_pid == 1)
1.4       pavel     440:                                p->p_flag &= ~PK_NOCLDWAIT;
1.2       ad        441:                        else
1.4       pavel     442:                                p->p_flag |= PK_NOCLDWAIT;
1.2       ad        443:                } else
1.4       pavel     444:                        p->p_flag &= ~PK_NOCLDWAIT;
1.2       ad        445:
                    446:                if (nsa->sa_handler == SIG_IGN) {
                    447:                        /*
                    448:                         * Paranoia: same as above.
                    449:                         */
                    450:                        if (p->p_pid == 1)
1.4       pavel     451:                                p->p_flag &= ~PK_CLDSIGIGN;
1.2       ad        452:                        else
1.4       pavel     453:                                p->p_flag |= PK_CLDSIGIGN;
1.2       ad        454:                } else
1.4       pavel     455:                        p->p_flag &= ~PK_CLDSIGIGN;
1.2       ad        456:        }
                    457:
                    458:        if ((nsa->sa_flags & SA_NODEFER) == 0)
                    459:                sigaddset(&SIGACTION_PS(ps, signum).sa_mask, signum);
                    460:        else
                    461:                sigdelset(&SIGACTION_PS(ps, signum).sa_mask, signum);
                    462:
                    463:        /*
                    464:         * Set bit in p_sigctx.ps_sigignore for signals that are set to
                    465:         * SIG_IGN, and for signals set to SIG_DFL where the default is to
                    466:         * ignore. However, don't put SIGCONT in p_sigctx.ps_sigignore, as
                    467:         * we have to restart the process.
                    468:         */
                    469:        if (nsa->sa_handler == SIG_IGN ||
                    470:            (nsa->sa_handler == SIG_DFL && (prop & SA_IGNORE) != 0)) {
                    471:                /* Never to be seen again. */
                    472:                sigemptyset(&tset);
                    473:                sigaddset(&tset, signum);
                    474:                sigclearall(p, &tset, &kq);
                    475:                if (signum != SIGCONT) {
                    476:                        /* Easier in psignal */
                    477:                        sigaddset(&p->p_sigctx.ps_sigignore, signum);
                    478:                }
                    479:                sigdelset(&p->p_sigctx.ps_sigcatch, signum);
                    480:        } else {
                    481:                sigdelset(&p->p_sigctx.ps_sigignore, signum);
                    482:                if (nsa->sa_handler == SIG_DFL)
                    483:                        sigdelset(&p->p_sigctx.ps_sigcatch, signum);
                    484:                else
                    485:                        sigaddset(&p->p_sigctx.ps_sigcatch, signum);
                    486:        }
                    487:
                    488:        /*
                    489:         * Previously held signals may now have become visible.  Ensure that
                    490:         * we check for them before returning to userspace.
                    491:         */
1.6       ad        492:        if (sigispending(l, 0)) {
                    493:                lwp_lock(l);
                    494:                l->l_flag |= LW_PENDSIG;
                    495:                lwp_unlock(l);
                    496:        }
1.25      rmind     497: out:
1.14      ad        498:        mutex_exit(p->p_lock);
1.2       ad        499:        ksiginfo_queue_drain(&kq);
                    500:
1.25      rmind     501:        return error;
1.2       ad        502: }
                    503:
                    504: int
                    505: sigprocmask1(struct lwp *l, int how, const sigset_t *nss, sigset_t *oss)
                    506: {
                    507:        int more;
1.17      wrstuden  508:        struct proc *p = l->l_proc;
                    509:        sigset_t *mask;
                    510:        mask = (p->p_sa != NULL) ? &p->p_sa->sa_sigmask : &l->l_sigmask;
1.2       ad        511:
1.17      wrstuden  512:        KASSERT(mutex_owned(p->p_lock));
1.2       ad        513:
                    514:        if (oss)
1.17      wrstuden  515:                *oss = *mask;
1.2       ad        516:        if (nss) {
                    517:                switch (how) {
                    518:                case SIG_BLOCK:
1.17      wrstuden  519:                        sigplusset(nss, mask);
1.2       ad        520:                        more = 0;
                    521:                        break;
                    522:                case SIG_UNBLOCK:
1.17      wrstuden  523:                        sigminusset(nss, mask);
1.2       ad        524:                        more = 1;
                    525:                        break;
                    526:                case SIG_SETMASK:
1.17      wrstuden  527:                        *mask = *nss;
1.2       ad        528:                        more = 1;
                    529:                        break;
                    530:                default:
                    531:                        return (EINVAL);
                    532:                }
1.17      wrstuden  533:                sigminusset(&sigcantmask, mask);
1.6       ad        534:                if (more && sigispending(l, 0)) {
1.2       ad        535:                        /*
                    536:                         * Check for pending signals on return to user.
                    537:                         */
                    538:                        lwp_lock(l);
1.4       pavel     539:                        l->l_flag |= LW_PENDSIG;
1.2       ad        540:                        lwp_unlock(l);
                    541:                }
                    542:        }
                    543:
1.25      rmind     544:        return 0;
1.2       ad        545: }
                    546:
                    547: void
                    548: sigpending1(struct lwp *l, sigset_t *ss)
                    549: {
                    550:        struct proc *p = l->l_proc;
                    551:
1.14      ad        552:        mutex_enter(p->p_lock);
1.2       ad        553:        *ss = l->l_sigpend.sp_set;
                    554:        sigplusset(&p->p_sigpend.sp_set, ss);
1.14      ad        555:        mutex_exit(p->p_lock);
1.2       ad        556: }
                    557:
                    558: int
                    559: sigsuspend1(struct lwp *l, const sigset_t *ss)
                    560: {
1.25      rmind     561:        struct proc *p = l->l_proc;
1.2       ad        562:
                    563:        if (ss) {
                    564:                /*
1.12      yamt      565:                 * When returning from sigsuspend, we want
1.2       ad        566:                 * the old mask to be restored after the
                    567:                 * signal handler has finished.  Thus, we
                    568:                 * save it here and mark the sigctx structure
                    569:                 * to indicate this.
                    570:                 */
1.14      ad        571:                mutex_enter(p->p_lock);
1.2       ad        572:                l->l_sigrestore = 1;
                    573:                l->l_sigoldmask = l->l_sigmask;
                    574:                l->l_sigmask = *ss;
                    575:                sigminusset(&sigcantmask, &l->l_sigmask);
                    576:
                    577:                /* Check for pending signals when sleeping. */
1.6       ad        578:                if (sigispending(l, 0)) {
                    579:                        lwp_lock(l);
                    580:                        l->l_flag |= LW_PENDSIG;
                    581:                        lwp_unlock(l);
                    582:                }
1.14      ad        583:                mutex_exit(p->p_lock);
1.2       ad        584:        }
                    585:
1.5       thorpej   586:        while (kpause("pause", true, 0, NULL) == 0)
1.2       ad        587:                ;
                    588:
                    589:        /* always return EINTR rather than ERESTART... */
1.25      rmind     590:        return EINTR;
1.2       ad        591: }
                    592:
                    593: int
                    594: sigaltstack1(struct lwp *l, const struct sigaltstack *nss,
1.25      rmind     595:     struct sigaltstack *oss)
1.2       ad        596: {
                    597:        struct proc *p = l->l_proc;
                    598:        int error = 0;
                    599:
1.14      ad        600:        mutex_enter(p->p_lock);
1.2       ad        601:
                    602:        if (oss)
                    603:                *oss = l->l_sigstk;
                    604:
                    605:        if (nss) {
                    606:                if (nss->ss_flags & ~SS_ALLBITS)
                    607:                        error = EINVAL;
                    608:                else if (nss->ss_flags & SS_DISABLE) {
                    609:                        if (l->l_sigstk.ss_flags & SS_ONSTACK)
                    610:                                error = EINVAL;
                    611:                } else if (nss->ss_size < MINSIGSTKSZ)
                    612:                        error = ENOMEM;
                    613:
                    614:                if (!error)
                    615:                        l->l_sigstk = *nss;
                    616:        }
                    617:
1.14      ad        618:        mutex_exit(p->p_lock);
1.2       ad        619:
1.25      rmind     620:        return error;
1.2       ad        621: }
                    622:
                    623: int
1.26      pooka     624: sigtimedwait1(struct lwp *l, const struct sys_____sigtimedwait50_args *uap,
1.25      rmind     625:     register_t *retval, copyout_t storeinf, copyin_t fetchts, copyout_t storets)
1.2       ad        626: {
1.9       dsl       627:        /* {
1.2       ad        628:                syscallarg(const sigset_t *) set;
                    629:                syscallarg(siginfo_t *) info;
                    630:                syscallarg(struct timespec *) timeout;
1.9       dsl       631:        } */
1.2       ad        632:        struct proc *p = l->l_proc;
1.25      rmind     633:        int error, signum, timo;
1.2       ad        634:        struct timespec ts, tsstart, tsnow;
1.24      rmind     635:        ksiginfo_t ksi;
1.2       ad        636:
                    637:        /*
                    638:         * Calculate timeout, if it was specified.
                    639:         */
                    640:        if (SCARG(uap, timeout)) {
1.25      rmind     641:                error = (*fetchts)(SCARG(uap, timeout), &ts, sizeof(ts));
1.23      christos  642:                if (error)
                    643:                        return error;
1.2       ad        644:
1.23      christos  645:                if ((error = itimespecfix(&ts)) != 0)
                    646:                        return error;
1.2       ad        647:
1.23      christos  648:                timo = tstohz(&ts);
                    649:                if (timo == 0 && ts.tv_sec == 0 && ts.tv_nsec != 0)
                    650:                        timo++;
1.2       ad        651:
                    652:                /*
                    653:                 * Remember current uptime, it would be used in
                    654:                 * ECANCELED/ERESTART case.
                    655:                 */
                    656:                getnanouptime(&tsstart);
1.25      rmind     657:        } else {
                    658:                memset(&tsstart, 0, sizeof(tsstart)); /* XXXgcc */
                    659:                timo = 0;
1.2       ad        660:        }
                    661:
                    662:        error = copyin(SCARG(uap, set), &l->l_sigwaitset,
                    663:            sizeof(l->l_sigwaitset));
1.25      rmind     664:        if (error)
                    665:                return error;
1.2       ad        666:
                    667:        /*
                    668:         * Silently ignore SA_CANTMASK signals. psignal1() would ignore
                    669:         * SA_CANTMASK signals in waitset, we do this only for the below
                    670:         * siglist check.
                    671:         */
                    672:        sigminusset(&sigcantmask, &l->l_sigwaitset);
                    673:
1.14      ad        674:        mutex_enter(p->p_lock);
1.2       ad        675:
1.25      rmind     676:        /* SA processes can have no more than 1 sigwaiter. */
1.17      wrstuden  677:        if ((p->p_sflag & PS_SA) != 0 && !LIST_EMPTY(&p->p_sigwaiters)) {
                    678:                mutex_exit(p->p_lock);
                    679:                error = EINVAL;
                    680:                goto out;
                    681:        }
                    682:
1.25      rmind     683:        /* Check for pending signals in the process, if no - then in LWP. */
1.24      rmind     684:        if ((signum = sigget(&p->p_sigpend, &ksi, 0, &l->l_sigwaitset)) == 0)
                    685:                signum = sigget(&l->l_sigpend, &ksi, 0, &l->l_sigwaitset);
1.2       ad        686:
                    687:        if (signum != 0) {
1.25      rmind     688:                /* If found a pending signal, just copy it out to the user. */
1.14      ad        689:                mutex_exit(p->p_lock);
1.2       ad        690:                goto out;
                    691:        }
                    692:
                    693:        /*
1.25      rmind     694:         * Set up the sigwait list and wait for signal to arrive.
                    695:         * We can either be woken up or time out.
1.2       ad        696:         */
1.24      rmind     697:        l->l_sigwaited = &ksi;
1.2       ad        698:        LIST_INSERT_HEAD(&p->p_sigwaiters, l, l_sigwaiter);
1.14      ad        699:        error = cv_timedwait_sig(&l->l_sigcv, p->p_lock, timo);
1.2       ad        700:
                    701:        /*
1.25      rmind     702:         * Need to find out if we woke as a result of _lwp_wakeup() or a
1.2       ad        703:         * signal outside our wait set.
                    704:         */
                    705:        if (l->l_sigwaited != NULL) {
                    706:                if (error == EINTR) {
1.25      rmind     707:                        /* Wakeup via _lwp_wakeup(). */
1.2       ad        708:                        error = ECANCELED;
                    709:                } else if (!error) {
1.25      rmind     710:                        /* Spurious wakeup - arrange for syscall restart. */
1.2       ad        711:                        error = ERESTART;
                    712:                }
                    713:                l->l_sigwaited = NULL;
                    714:                LIST_REMOVE(l, l_sigwaiter);
                    715:        }
1.14      ad        716:        mutex_exit(p->p_lock);
1.2       ad        717:
                    718:        /*
                    719:         * If the sleep was interrupted (either by signal or wakeup), update
                    720:         * the timeout and copyout new value back.  It would be used when
                    721:         * the syscall would be restarted or called again.
                    722:         */
                    723:        if (timo && (error == ERESTART || error == ECANCELED)) {
                    724:                getnanouptime(&tsnow);
                    725:
1.25      rmind     726:                /* Compute how much time has passed since start. */
1.2       ad        727:                timespecsub(&tsnow, &tsstart, &tsnow);
1.25      rmind     728:
                    729:                /* Substract passed time from timeout. */
1.2       ad        730:                timespecsub(&ts, &tsnow, &ts);
                    731:
                    732:                if (ts.tv_sec < 0)
                    733:                        error = EAGAIN;
                    734:                else {
1.25      rmind     735:                        /* Copy updated timeout to userland. */
                    736:                        error = (*storets)(&ts, SCARG(uap, timeout),
1.2       ad        737:                            sizeof(ts));
                    738:                }
                    739:        }
1.25      rmind     740: out:
1.2       ad        741:        /*
                    742:         * If a signal from the wait set arrived, copy it to userland.
                    743:         * Copy only the used part of siginfo, the padding part is
                    744:         * left unchanged (userland is not supposed to touch it anyway).
                    745:         */
1.27      drochner  746:        if (error == 0 && SCARG(uap, info)) {
1.25      rmind     747:                error = (*storeinf)(&ksi.ksi_info, SCARG(uap, info),
1.24      rmind     748:                    sizeof(ksi.ksi_info));
1.25      rmind     749:        }
1.27      drochner  750:        if (error == 0)
                    751:                *retval = ksi.ksi_info._signo;
1.2       ad        752:        return error;
                    753: }

CVSweb <webmaster@jp.NetBSD.org>