[BACK]Return to signals.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / rump / librump / rumpkern

Annotation of src/sys/rump/librump/rumpkern/signals.c, Revision 1.5

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

CVSweb <webmaster@jp.NetBSD.org>