[BACK]Return to ibcs2_signal.c CVS log [TXT][DIR] Up to [local] / sys / compat / ibcs2

Annotation of sys/compat/ibcs2/ibcs2_signal.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ibcs2_signal.c,v 1.7 2002/03/14 01:26:50 millert Exp $        */
                      2: /*     $NetBSD: ibcs2_signal.c,v 1.8 1996/05/03 17:05:27 christos Exp $        */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Scott Bartram
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. The name of the author may not be used to endorse or promote products
                     17:  *    derived from this software without specific prior written permission
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     20:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     21:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     22:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     23:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     24:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     25:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     26:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     27:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     28:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     29:  */
                     30:
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/namei.h>
                     34: #include <sys/proc.h>
                     35: #include <sys/filedesc.h>
                     36: #include <sys/ioctl.h>
                     37: #include <sys/mount.h>
                     38: #include <sys/kernel.h>
                     39: #include <sys/signal.h>
                     40: #include <sys/signalvar.h>
                     41: #include <sys/malloc.h>
                     42:
                     43: #include <sys/syscallargs.h>
                     44:
                     45: #include <compat/ibcs2/ibcs2_types.h>
                     46: #include <compat/ibcs2/ibcs2_signal.h>
                     47: #include <compat/ibcs2/ibcs2_syscallargs.h>
                     48: #include <compat/ibcs2/ibcs2_util.h>
                     49:
                     50: #define sigemptyset(s)         bzero((s), sizeof(*(s)))
                     51: #define sigismember(s, n)      (*(s) & sigmask(n))
                     52: #define sigaddset(s, n)                (*(s) |= sigmask(n))
                     53:
                     54: #define        ibcs2_sigmask(n)        (1 << ((n) - 1))
                     55: #define ibcs2_sigemptyset(s)   bzero((s), sizeof(*(s)))
                     56: #define ibcs2_sigismember(s, n)        (*(s) & ibcs2_sigmask(n))
                     57: #define ibcs2_sigaddset(s, n)  (*(s) |= ibcs2_sigmask(n))
                     58:
                     59: int bsd_to_ibcs2_sig[] = {
                     60:        0,                      /* 0 */
                     61:        IBCS2_SIGHUP,           /* 1 */
                     62:        IBCS2_SIGINT,           /* 2 */
                     63:        IBCS2_SIGQUIT,          /* 3 */
                     64:        IBCS2_SIGILL,           /* 4 */
                     65:        IBCS2_SIGTRAP,          /* 5 */
                     66:        IBCS2_SIGABRT,          /* 6 */
                     67:        IBCS2_SIGEMT,           /* 7 */
                     68:        IBCS2_SIGFPE,           /* 8 */
                     69:        IBCS2_SIGKILL,          /* 9 */
                     70:        IBCS2_SIGBUS,           /* 10 */
                     71:        IBCS2_SIGSEGV,          /* 11 */
                     72:        IBCS2_SIGSYS,           /* 12 */
                     73:        IBCS2_SIGPIPE,          /* 13 */
                     74:        IBCS2_SIGALRM,          /* 14 */
                     75:        IBCS2_SIGTERM,          /* 15 */
                     76:        0,                      /* 16 - SIGURG */
                     77:        IBCS2_SIGSTOP,          /* 17 */
                     78:        IBCS2_SIGTSTP,          /* 18 */
                     79:        IBCS2_SIGCONT,          /* 19 */
                     80:        IBCS2_SIGCLD,           /* 20 */
                     81:        IBCS2_SIGTTIN,          /* 21 */
                     82:        IBCS2_SIGTTOU,          /* 22 */
                     83:        IBCS2_SIGPOLL,          /* 23 */
                     84:        0,                      /* 24 - SIGXCPU */
                     85:        0,                      /* 25 - SIGXFSZ */
                     86:        IBCS2_SIGVTALRM,        /* 26 */
                     87:        IBCS2_SIGPROF,          /* 27 */
                     88:        IBCS2_SIGWINCH,         /* 28 */
                     89:        0,                      /* 29 */
                     90:        IBCS2_SIGUSR1,          /* 30 */
                     91:        IBCS2_SIGUSR2,          /* 31 */
                     92: };
                     93:
                     94: int ibcs2_to_bsd_sig[] = {
                     95:        0,                      /* 0 */
                     96:        SIGHUP,                 /* 1 */
                     97:        SIGINT,                 /* 2 */
                     98:        SIGQUIT,                /* 3 */
                     99:        SIGILL,                 /* 4 */
                    100:        SIGTRAP,                /* 5 */
                    101:        SIGABRT,                /* 6 */
                    102:        SIGEMT,                 /* 7 */
                    103:        SIGFPE,                 /* 8 */
                    104:        SIGKILL,                /* 9 */
                    105:        SIGBUS,                 /* 10 */
                    106:        SIGSEGV,                /* 11 */
                    107:        SIGSYS,                 /* 12 */
                    108:        SIGPIPE,                /* 13 */
                    109:        SIGALRM,                /* 14 */
                    110:        SIGTERM,                /* 15 */
                    111:        SIGUSR1,                /* 16 */
                    112:        SIGUSR2,                /* 17 */
                    113:        SIGCHLD,                /* 18 */
                    114:        0,                      /* 19 - SIGPWR */
                    115:        SIGWINCH,               /* 20 */
                    116:        0,                      /* 21 */
                    117:        SIGIO,                  /* 22 */
                    118:        SIGSTOP,                /* 23 */
                    119:        SIGTSTP,                /* 24 */
                    120:        SIGCONT,                /* 25 */
                    121:        SIGTTIN,                /* 26 */
                    122:        SIGTTOU,                /* 27 */
                    123:        SIGVTALRM,              /* 28 */
                    124:        SIGPROF,                /* 29 */
                    125:        0,                      /* 30 */
                    126:        0,                      /* 31 */
                    127: };
                    128:
                    129: void ibcs2_to_bsd_sigset(const ibcs2_sigset_t *, sigset_t *);
                    130: void bsd_to_ibcs2_sigset(const sigset_t *, ibcs2_sigset_t *);
                    131: void ibcs2_to_bsd_sigaction(struct ibcs2_sigaction *,
                    132:     struct sigaction *);
                    133: void bsd_to_ibcs2_sigaction(struct sigaction *, struct ibcs2_sigaction *);
                    134:
                    135: void
                    136: ibcs2_to_bsd_sigset(iss, bss)
                    137:        const ibcs2_sigset_t *iss;
                    138:        sigset_t *bss;
                    139: {
                    140:        int i, newsig;
                    141:
                    142:        sigemptyset(bss);
                    143:        for (i = 1; i < IBCS2_NSIG; i++) {
                    144:                if (ibcs2_sigismember(iss, i)) {
                    145:                        newsig = ibcs2_to_bsd_sig[i];
                    146:                        if (newsig)
                    147:                                sigaddset(bss, newsig);
                    148:                }
                    149:        }
                    150: }
                    151:
                    152: void
                    153: bsd_to_ibcs2_sigset(bss, iss)
                    154:        const sigset_t *bss;
                    155:        ibcs2_sigset_t *iss;
                    156: {
                    157:        int i, newsig;
                    158:
                    159:        ibcs2_sigemptyset(iss);
                    160:        for (i = 1; i < NSIG; i++) {
                    161:                if (sigismember(bss, i)) {
                    162:                        newsig = bsd_to_ibcs2_sig[i];
                    163:                        if (newsig)
                    164:                                ibcs2_sigaddset(iss, newsig);
                    165:                }
                    166:        }
                    167: }
                    168:
                    169: void
                    170: ibcs2_to_bsd_sigaction(isa, bsa)
                    171:        struct ibcs2_sigaction *isa;
                    172:        struct sigaction *bsa;
                    173: {
                    174:
                    175:        bsa->sa_handler = isa->sa__handler;
                    176:        ibcs2_to_bsd_sigset(&isa->sa_mask, &bsa->sa_mask);
                    177:        bsa->sa_flags = 0;
                    178:        if ((isa->sa_flags & IBCS2_SA_NOCLDSTOP) != 0)
                    179:                bsa->sa_flags |= SA_NOCLDSTOP;
                    180: }
                    181:
                    182: void
                    183: bsd_to_ibcs2_sigaction(bsa, isa)
                    184:        struct sigaction *bsa;
                    185:        struct ibcs2_sigaction *isa;
                    186: {
                    187:
                    188:        isa->sa__handler = bsa->sa_handler;
                    189:        bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->sa_mask);
                    190:        isa->sa_flags = 0;
                    191:        if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
                    192:                isa->sa_flags |= IBCS2_SA_NOCLDSTOP;
                    193: }
                    194:
                    195: int
                    196: ibcs2_sys_sigaction(p, v, retval)
                    197:        register struct proc *p;
                    198:        void *v;
                    199:        register_t *retval;
                    200: {
                    201:        struct ibcs2_sys_sigaction_args /* {
                    202:                syscallarg(int) signum;
                    203:                syscallarg(struct ibcs2_sigaction *) nsa;
                    204:                syscallarg(struct ibcs2_sigaction *) osa;
                    205:        } */ *uap = v;
                    206:        struct ibcs2_sigaction *nisa, *oisa, tmpisa;
                    207:        struct sigaction *nbsa, *obsa, tmpbsa;
                    208:        struct sys_sigaction_args sa;
                    209:        caddr_t sg;
                    210:        int error;
                    211:
                    212:        if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= IBCS2_NSIG)
                    213:                return (EINVAL);
                    214:
                    215:        sg = stackgap_init(p->p_emul);
                    216:        nisa = SCARG(uap, nsa);
                    217:        oisa = SCARG(uap, osa);
                    218:
                    219:        if (oisa != NULL)
                    220:                obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    221:        else
                    222:                obsa = NULL;
                    223:
                    224:        if (nisa != NULL) {
                    225:                nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    226:                if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
                    227:                        return error;
                    228:                ibcs2_to_bsd_sigaction(&tmpisa, &tmpbsa);
                    229:                if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
                    230:                        return error;
                    231:        } else
                    232:                nbsa = NULL;
                    233:
                    234:        SCARG(&sa, signum) = ibcs2_to_bsd_sig[SCARG(uap, signum)];
                    235:        SCARG(&sa, nsa) = nbsa;
                    236:        SCARG(&sa, osa) = obsa;
                    237:
                    238:        if ((error = sys_sigaction(p, &sa, retval)) != 0)
                    239:                return error;
                    240:
                    241:        if (oisa != NULL) {
                    242:                if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
                    243:                        return error;
                    244:                bsd_to_ibcs2_sigaction(&tmpbsa, &tmpisa);
                    245:                if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
                    246:                        return error;
                    247:        }
                    248:
                    249:        return 0;
                    250: }
                    251:
                    252: int
                    253: ibcs2_sys_sigsys(p, v, retval)
                    254:        register struct proc *p;
                    255:        void *v;
                    256:        register_t *retval;
                    257: {
                    258:        struct ibcs2_sys_sigsys_args /* {
                    259:                syscallarg(int) sig;
                    260:                syscallarg(ibcs2_sig_t) fp;
                    261:        } */ *uap = v;
                    262:        int signum, error;
                    263:        caddr_t sg = stackgap_init(p->p_emul);
                    264:
                    265:        signum = IBCS2_SIGNO(SCARG(uap, sig));
                    266:        if (signum < 0 || signum >= IBCS2_NSIG) {
                    267:                if (IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGNAL_MASK ||
                    268:                    IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGSET_MASK)
                    269:                        *retval = (int)IBCS2_SIG_ERR;
                    270:                return EINVAL;
                    271:        }
                    272:        signum = ibcs2_to_bsd_sig[signum];
                    273:
                    274:        switch (IBCS2_SIGCALL(SCARG(uap, sig))) {
                    275:        /*
                    276:         * sigset is identical to signal() except that SIG_HOLD is allowed as
                    277:         * an action.
                    278:         */
                    279:        case IBCS2_SIGSET_MASK:
                    280:                /*
                    281:                 * sigset is identical to signal() except
                    282:                 * that SIG_HOLD is allowed as
                    283:                 * an action.
                    284:                 */
                    285:                if (SCARG(uap, fp) == IBCS2_SIG_HOLD) {
                    286:                        struct sys_sigprocmask_args sa;
                    287:
                    288:                        SCARG(&sa, how) = SIG_BLOCK;
                    289:                        SCARG(&sa, mask) = sigmask(signum);
                    290:                        return sys_sigprocmask(p, &sa, retval);
                    291:                }
                    292:                /* FALLTHROUGH */
                    293:
                    294:        case IBCS2_SIGNAL_MASK:
                    295:                {
                    296:                        struct sys_sigaction_args sa_args;
                    297:                        struct sigaction *nbsa, *obsa, sa;
                    298:
                    299:                        nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    300:                        obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    301:                        SCARG(&sa_args, signum) = signum;
                    302:                        SCARG(&sa_args, nsa) = nbsa;
                    303:                        SCARG(&sa_args, osa) = obsa;
                    304:
                    305:                        sa.sa_handler = SCARG(uap, fp);
                    306:                        sigemptyset(&sa.sa_mask);
                    307:                        sa.sa_flags = 0;
                    308: #if 0
                    309:                        if (signum != SIGALRM)
                    310:                                sa.sa_flags = SA_RESTART;
                    311: #endif
                    312:                        if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
                    313:                                return error;
                    314:                        if ((error = sys_sigaction(p, &sa_args, retval)) != 0) {
                    315:                                DPRINTF(("signal: sigaction failed: %d\n",
                    316:                                         error));
                    317:                                *retval = (int)IBCS2_SIG_ERR;
                    318:                                return error;
                    319:                        }
                    320:                        if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
                    321:                                return error;
                    322:                        *retval = (int)sa.sa_handler;
                    323:                        return 0;
                    324:                }
                    325:
                    326:        case IBCS2_SIGHOLD_MASK:
                    327:                {
                    328:                        struct sys_sigprocmask_args sa;
                    329:
                    330:                        SCARG(&sa, how) = SIG_BLOCK;
                    331:                        SCARG(&sa, mask) = sigmask(signum);
                    332:                        return sys_sigprocmask(p, &sa, retval);
                    333:                }
                    334:
                    335:        case IBCS2_SIGRELSE_MASK:
                    336:                {
                    337:                        struct sys_sigprocmask_args sa;
                    338:
                    339:                        SCARG(&sa, how) = SIG_UNBLOCK;
                    340:                        SCARG(&sa, mask) = sigmask(signum);
                    341:                        return sys_sigprocmask(p, &sa, retval);
                    342:                }
                    343:
                    344:        case IBCS2_SIGIGNORE_MASK:
                    345:                {
                    346:                        struct sys_sigaction_args sa_args;
                    347:                        struct sigaction *bsa, sa;
                    348:
                    349:                        bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    350:                        SCARG(&sa_args, signum) = signum;
                    351:                        SCARG(&sa_args, nsa) = bsa;
                    352:                        SCARG(&sa_args, osa) = NULL;
                    353:
                    354:                        sa.sa_handler = SIG_IGN;
                    355:                        sigemptyset(&sa.sa_mask);
                    356:                        sa.sa_flags = 0;
                    357:                        if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
                    358:                                return error;
                    359:                        if ((error = sys_sigaction(p, &sa_args, retval)) != 0) {
                    360:                                DPRINTF(("sigignore: sigaction failed\n"));
                    361:                                return error;
                    362:                        }
                    363:                        return 0;
                    364:                }
                    365:
                    366:        case IBCS2_SIGPAUSE_MASK:
                    367:                {
                    368:                        struct sys_sigsuspend_args sa;
                    369:
                    370:                        SCARG(&sa, mask) = p->p_sigmask &~ sigmask(signum);
                    371:                        return sys_sigsuspend(p, &sa, retval);
                    372:                }
                    373:
                    374:        default:
                    375:                return ENOSYS;
                    376:        }
                    377: }
                    378:
                    379: int
                    380: ibcs2_sys_sigprocmask(p, v, retval)
                    381:        register struct proc *p;
                    382:        void *v;
                    383:        register_t *retval;
                    384: {
                    385:        struct ibcs2_sys_sigprocmask_args /* {
                    386:                syscallarg(int) how;
                    387:                syscallarg(ibcs2_sigset_t *) set;
                    388:                syscallarg(ibcs2_sigset_t *) oset;
                    389:        } */ *uap = v;
                    390:        ibcs2_sigset_t iss;
                    391:        sigset_t bss;
                    392:        int error = 0;
                    393:
                    394:        if (SCARG(uap, oset) != NULL) {
                    395:                /* Fix the return value first if needed */
                    396:                bsd_to_ibcs2_sigset(&p->p_sigmask, &iss);
                    397:                if ((error = copyout(&iss, SCARG(uap, oset), sizeof(iss))) != 0)
                    398:                        return error;
                    399:        }
                    400:
                    401:        if (SCARG(uap, set) == NULL)
                    402:                /* Just examine */
                    403:                return 0;
                    404:
                    405:        if ((error = copyin(SCARG(uap, set), &iss, sizeof(iss))) != 0)
                    406:                return error;
                    407:
                    408:        ibcs2_to_bsd_sigset(&iss, &bss);
                    409:
                    410:        (void) splhigh();
                    411:
                    412:        switch (SCARG(uap, how)) {
                    413:        case IBCS2_SIG_BLOCK:
                    414:                p->p_sigmask |= bss & ~sigcantmask;
                    415:                break;
                    416:
                    417:        case IBCS2_SIG_UNBLOCK:
                    418:                p->p_sigmask &= ~bss;
                    419:                break;
                    420:
                    421:        case IBCS2_SIG_SETMASK:
                    422:                p->p_sigmask = bss & ~sigcantmask;
                    423:                break;
                    424:
                    425:        default:
                    426:                error = EINVAL;
                    427:                break;
                    428:        }
                    429:
                    430:        (void) spl0();
                    431:
                    432:        return error;
                    433: }
                    434:
                    435: int
                    436: ibcs2_sys_sigpending(p, v, retval)
                    437:        register struct proc *p;
                    438:        void *v;
                    439:        register_t *retval;
                    440: {
                    441:        struct ibcs2_sys_sigpending_args /* {
                    442:                syscallarg(ibcs2_sigset_t *) mask;
                    443:        } */ *uap = v;
                    444:        sigset_t bss;
                    445:        ibcs2_sigset_t iss;
                    446:
                    447:        bss = p->p_siglist & p->p_sigmask;
                    448:        bsd_to_ibcs2_sigset(&bss, &iss);
                    449:
                    450:        return copyout(&iss, SCARG(uap, mask), sizeof(iss));
                    451: }
                    452:
                    453: int
                    454: ibcs2_sys_sigsuspend(p, v, retval)
                    455:        register struct proc *p;
                    456:        void *v;
                    457:        register_t *retval;
                    458: {
                    459:        struct ibcs2_sys_sigsuspend_args /* {
                    460:                syscallarg(ibcs2_sigset_t *) mask;
                    461:        } */ *uap = v;
                    462:        ibcs2_sigset_t sss;
                    463:        sigset_t bss;
                    464:        struct sys_sigsuspend_args sa;
                    465:        int error;
                    466:
                    467:        if ((error = copyin(SCARG(uap, mask), &sss, sizeof(sss))) != 0)
                    468:                return error;
                    469:
                    470:        ibcs2_to_bsd_sigset(&sss, &bss);
                    471:
                    472:        SCARG(&sa, mask) = bss;
                    473:        return sys_sigsuspend(p, &sa, retval);
                    474: }
                    475:
                    476: int
                    477: ibcs2_sys_pause(p, v, retval)
                    478:        register struct proc *p;
                    479:        void *v;
                    480:        register_t *retval;
                    481: {
                    482:        struct sys_sigsuspend_args bsa;
                    483:
                    484:        SCARG(&bsa, mask) = p->p_sigmask;
                    485:        return sys_sigsuspend(p, &bsa, retval);
                    486: }
                    487:
                    488: int
                    489: ibcs2_sys_kill(p, v, retval)
                    490:        register struct proc *p;
                    491:        void *v;
                    492:        register_t *retval;
                    493: {
                    494:        struct ibcs2_sys_kill_args /* {
                    495:                syscallarg(int) pid;
                    496:                syscallarg(int) signo;
                    497:        } */ *uap = v;
                    498:        struct sys_kill_args ka;
                    499:
                    500:        if (SCARG(uap, signo) < 0 || SCARG(uap, signo) >= IBCS2_NSIG)
                    501:                return (EINVAL);
                    502:        SCARG(&ka, pid) = SCARG(uap, pid);
                    503:        SCARG(&ka, signum) = ibcs2_to_bsd_sig[SCARG(uap, signo)];
                    504:        return sys_kill(p, &ka, retval);
                    505: }

CVSweb