[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.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>