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

Annotation of sys/compat/linux/linux_signal.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: linux_signal.c,v 1.12 2003/02/25 09:10:27 tedu Exp $  */
                      2: /*     $NetBSD: linux_signal.c,v 1.10 1996/04/04 23:51:36 christos Exp $       */
                      3:
                      4: /*
                      5:  * Copyright (c) 1995 Frank van der Linden
                      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. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed for the NetBSD Project
                     19:  *      by Frank van der Linden
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  *
                     34:  * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
                     35:  */
                     36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/namei.h>
                     40: #include <sys/proc.h>
                     41: #include <sys/filedesc.h>
                     42: #include <sys/ioctl.h>
                     43: #include <sys/mount.h>
                     44: #include <sys/kernel.h>
                     45: #include <sys/signal.h>
                     46: #include <sys/signalvar.h>
                     47: #include <sys/malloc.h>
                     48:
                     49: #include <sys/syscallargs.h>
                     50:
                     51: #include <compat/linux/linux_types.h>
                     52: #include <compat/linux/linux_signal.h>
                     53: #include <compat/linux/linux_syscallargs.h>
                     54: #include <compat/linux/linux_util.h>
                     55:
                     56: #define        sigemptyset(s)          bzero((s), sizeof(*(s)))
                     57: #define        sigismember(s, n)       (*(s) & sigmask(n))
                     58: #define        sigaddset(s, n)         (*(s) |= sigmask(n))
                     59:
                     60: /* Locally used defines (in bsd<->linux conversion functions): */
                     61: #define        linux_sigmask(n)        (1 << ((n) - 1))
                     62: #define        linux_sigemptyset(s)    bzero((s), sizeof(*(s)))
                     63: #define        linux_sigismember(s, n) ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
                     64:                                        & (1 << ((n) - 1) % LINUX__NSIG_BPW))
                     65: #define        linux_sigaddset(s, n)   ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
                     66:                                        |= (1 << ((n) - 1) % LINUX__NSIG_BPW))
                     67:
                     68: int bsd_to_linux_sig[NSIG] = {
                     69:        0,
                     70:        LINUX_SIGHUP,
                     71:        LINUX_SIGINT,
                     72:        LINUX_SIGQUIT,
                     73:        LINUX_SIGILL,
                     74:        LINUX_SIGTRAP,
                     75:        LINUX_SIGABRT,
                     76:        LINUX_NSIG,             /* XXX Kludge to get RT signal #32 to work */
                     77:        LINUX_SIGFPE,
                     78:        LINUX_SIGKILL,
                     79:        LINUX_SIGBUS,
                     80:        LINUX_SIGSEGV,
                     81:        LINUX_NSIG + 1,                 /* XXX Kludge to get RT signal #32 to work */
                     82:        LINUX_SIGPIPE,
                     83:        LINUX_SIGALRM,
                     84:        LINUX_SIGTERM,
                     85:        LINUX_SIGURG,
                     86:        LINUX_SIGSTOP,
                     87:        LINUX_SIGTSTP,
                     88:        LINUX_SIGCONT,
                     89:        LINUX_SIGCHLD,
                     90:        LINUX_SIGTTIN,
                     91:        LINUX_SIGTTOU,
                     92:        LINUX_SIGIO,
                     93:        LINUX_SIGXCPU,
                     94:        LINUX_SIGXFSZ,
                     95:        LINUX_SIGVTALRM,
                     96:        LINUX_SIGPROF,
                     97:        LINUX_SIGWINCH,
                     98:        0,                      /* SIGINFO */
                     99:        LINUX_SIGUSR1,
                    100:        LINUX_SIGUSR2,
                    101: };
                    102:
                    103: int linux_to_bsd_sig[LINUX__NSIG] = {
                    104:        0,
                    105:        SIGHUP,
                    106:        SIGINT,
                    107:        SIGQUIT,
                    108:        SIGILL,
                    109:        SIGTRAP,
                    110:        SIGABRT,
                    111:        SIGBUS,
                    112:        SIGFPE,
                    113:        SIGKILL,
                    114:        SIGUSR1,
                    115:        SIGSEGV,
                    116:        SIGUSR2,
                    117:        SIGPIPE,
                    118:        SIGALRM,
                    119:        SIGTERM,
                    120:        0,                      /* SIGSTKFLT */
                    121:        SIGCHLD,
                    122:        SIGCONT,
                    123:        SIGSTOP,
                    124:        SIGTSTP,
                    125:        SIGTTIN,
                    126:        SIGTTOU,
                    127:        SIGURG,
                    128:        SIGXCPU,
                    129:        SIGXFSZ,
                    130:        SIGVTALRM,
                    131:        SIGPROF,
                    132:        SIGWINCH,
                    133:        SIGIO,
                    134:        0,                      /* SIGUNUSED */
                    135:        0,
                    136:        SIGEMT,                 /* XXX Gruesome hack for linuxthreads:       */
                    137:        SIGSYS,                 /* Map 1st 2 RT signals onto ones we handle. */
                    138:        0,
                    139:        0,
                    140:        0,
                    141:        0,
                    142:        0,
                    143:        0,
                    144:        0,
                    145:        0,
                    146:        0,
                    147:        0,
                    148:        0,
                    149:        0,
                    150:        0,
                    151:        0,
                    152:        0,
                    153:        0,
                    154:        0,
                    155:        0,
                    156:        0,
                    157:        0,
                    158:        0,
                    159:        0,
                    160:        0,
                    161:        0,
                    162:        0,
                    163:        0,
                    164:        0,
                    165:        0,
                    166:        0,
                    167:        0,
                    168: };
                    169:
                    170: /*
                    171:  * Convert between Linux and BSD signal sets.
                    172:  */
                    173: void
                    174: linux_old_to_bsd_sigset(lss, bss)
                    175:        const linux_old_sigset_t *lss;
                    176:        sigset_t *bss;
                    177: {
                    178:        linux_old_extra_to_bsd_sigset(lss, (const unsigned long *) 0, bss);
                    179: }
                    180:
                    181: void
                    182: bsd_to_linux_old_sigset(bss, lss)
                    183:        const sigset_t *bss;
                    184:        linux_old_sigset_t *lss;
                    185: {
                    186:        bsd_to_linux_old_extra_sigset(bss, lss, (unsigned long *) 0);
                    187: }
                    188:
                    189: void
                    190: linux_old_extra_to_bsd_sigset(lss, extra, bss)
                    191:        const linux_old_sigset_t *lss;
                    192:        const unsigned long *extra;
                    193:        sigset_t *bss;
                    194: {
                    195:        linux_sigset_t lsnew;
                    196:
                    197:        /* convert old sigset to new sigset */
                    198:        linux_sigemptyset(&lsnew);
                    199:        lsnew.sig[0] = *lss;
                    200:        if (extra)
                    201:                bcopy(extra, &lsnew.sig[1],
                    202:                        sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
                    203:
                    204:        linux_to_bsd_sigset(&lsnew, bss);
                    205: }
                    206:
                    207: void
                    208: bsd_to_linux_old_extra_sigset(bss, lss, extra)
                    209:        const sigset_t *bss;
                    210:        linux_old_sigset_t *lss;
                    211:        unsigned long *extra;
                    212: {
                    213:        linux_sigset_t lsnew;
                    214:
                    215:        bsd_to_linux_sigset(bss, &lsnew);
                    216:
                    217:        /* convert new sigset to old sigset */
                    218:        *lss = lsnew.sig[0];
                    219:        if (extra)
                    220:                bcopy(&lsnew.sig[1], extra,
                    221:                        sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
                    222: }
                    223:
                    224: void
                    225: linux_to_bsd_sigset(lss, bss)
                    226:        const linux_sigset_t *lss;
                    227:        sigset_t *bss;
                    228: {
                    229:        int i, newsig;
                    230:
                    231:        sigemptyset(bss);
                    232:        for (i = 1; i < LINUX__NSIG; i++) {
                    233:                if (linux_sigismember(lss, i)) {
                    234:                        newsig = linux_to_bsd_sig[i];
                    235:                        if (newsig)
                    236:                                sigaddset(bss, newsig);
                    237:                }
                    238:        }
                    239: }
                    240:
                    241: void
                    242: bsd_to_linux_sigset(bss, lss)
                    243:        const sigset_t *bss;
                    244:        linux_sigset_t *lss;
                    245: {
                    246:        int i, newsig;
                    247:
                    248:        linux_sigemptyset(lss);
                    249:        for (i = 1; i < NSIG; i++) {
                    250:                if (sigismember(bss, i)) {
                    251:                        newsig = bsd_to_linux_sig[i];
                    252:                        if (newsig)
                    253:                                linux_sigaddset(lss, newsig);
                    254:                }
                    255:        }
                    256: }
                    257:
                    258: /*
                    259:  * Convert between Linux and BSD sigaction structures. Linux has
                    260:  * one extra field (sa_restorer) which we don't support.
                    261:  */
                    262: void
                    263: linux_old_to_bsd_sigaction(lsa, bsa)
                    264:        struct linux_old_sigaction *lsa;
                    265:        struct sigaction *bsa;
                    266: {
                    267:
                    268:        bsa->sa_handler = lsa->sa__handler;
                    269:        linux_old_to_bsd_sigset(&lsa->sa_mask, &bsa->sa_mask);
                    270:        bsa->sa_flags = 0;
                    271:        if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
                    272:                bsa->sa_flags |= SA_ONSTACK;
                    273:        if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
                    274:                bsa->sa_flags |= SA_RESTART;
                    275:        if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
                    276:                bsa->sa_flags |= SA_RESETHAND;
                    277:        if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
                    278:                bsa->sa_flags |= SA_NOCLDSTOP;
                    279:        if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
                    280:                bsa->sa_flags |= SA_NODEFER;
                    281: }
                    282:
                    283: void
                    284: bsd_to_linux_old_sigaction(bsa, lsa)
                    285:        struct sigaction *bsa;
                    286:        struct linux_old_sigaction *lsa;
                    287: {
                    288:
                    289:        lsa->sa__handler = bsa->sa_handler;
                    290:        bsd_to_linux_old_sigset(&bsa->sa_mask, &lsa->sa_mask);
                    291:        lsa->sa_flags = 0;
                    292:        if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
                    293:                lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
                    294:        if ((bsa->sa_flags & SA_ONSTACK) != 0)
                    295:                lsa->sa_flags |= LINUX_SA_ONSTACK;
                    296:        if ((bsa->sa_flags & SA_RESTART) != 0)
                    297:                lsa->sa_flags |= LINUX_SA_RESTART;
                    298:        if ((bsa->sa_flags & SA_NODEFER) != 0)
                    299:                lsa->sa_flags |= LINUX_SA_NOMASK;
                    300:        if ((bsa->sa_flags & SA_RESETHAND) != 0)
                    301:                lsa->sa_flags |= LINUX_SA_ONESHOT;
                    302:        lsa->sa_restorer = NULL;
                    303: }
                    304:
                    305: void
                    306: linux_to_bsd_sigaction(lsa, bsa)
                    307:        struct linux_sigaction *lsa;
                    308:        struct sigaction *bsa;
                    309: {
                    310:
                    311:        bsa->sa_handler = lsa->sa__handler;
                    312:        linux_to_bsd_sigset(&lsa->sa_mask, &bsa->sa_mask);
                    313:        bsa->sa_flags = 0;
                    314:        if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
                    315:                bsa->sa_flags |= SA_NOCLDSTOP;
                    316:        if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
                    317:                bsa->sa_flags |= SA_ONSTACK;
                    318:        if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
                    319:                bsa->sa_flags |= SA_RESTART;
                    320:        if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
                    321:                bsa->sa_flags |= SA_RESETHAND;
                    322:        if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
                    323:                bsa->sa_flags |= SA_NODEFER;
                    324:        if ((lsa->sa_flags & LINUX_SA_SIGINFO) != 0)
                    325:                bsa->sa_flags |= SA_SIGINFO;
                    326: }
                    327:
                    328: void
                    329: bsd_to_linux_sigaction(bsa, lsa)
                    330:        struct sigaction *bsa;
                    331:        struct linux_sigaction *lsa;
                    332: {
                    333:
                    334:        /* Clear sa_flags and sa_restorer (if it exists) */
                    335:        bzero(lsa, sizeof(struct linux_sigaction));
                    336:
                    337:        /* ...and fill in the mask and flags */
                    338:        bsd_to_linux_sigset(&bsa->sa_mask, &lsa->sa_mask);
                    339:        if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
                    340:                lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
                    341:        if ((bsa->sa_flags & SA_ONSTACK) != 0)
                    342:                lsa->sa_flags |= LINUX_SA_ONSTACK;
                    343:        if ((bsa->sa_flags & SA_RESTART) != 0)
                    344:                lsa->sa_flags |= LINUX_SA_RESTART;
                    345:        if ((bsa->sa_flags & SA_NODEFER) != 0)
                    346:                lsa->sa_flags |= LINUX_SA_NOMASK;
                    347:        if ((bsa->sa_flags & SA_RESETHAND) != 0)
                    348:                lsa->sa_flags |= LINUX_SA_ONESHOT;
                    349:        if ((bsa->sa_flags & SA_SIGINFO) != 0)
                    350:                lsa->sa_flags |= LINUX_SA_SIGINFO;
                    351:        lsa->sa__handler = bsa->sa_handler;
                    352: }
                    353:
                    354: int
                    355: linux_to_bsd_signal(int linuxsig, int *bsdsig)
                    356: {
                    357:        if (linuxsig < 0 || linuxsig >= LINUX__NSIG)
                    358:                return (EINVAL);
                    359:
                    360:        *bsdsig = linux_to_bsd_sig[linuxsig];
                    361:        return (0);
                    362: }
                    363:
                    364: int
                    365: bsd_to_linux_signal(int bsdsig, int *linuxsig)
                    366: {
                    367:        if (bsdsig < 0 || bsdsig >= NSIG)
                    368:                return (EINVAL);
                    369:
                    370:        *linuxsig = bsd_to_linux_sig[bsdsig];
                    371:        return (0);
                    372: }
                    373:
                    374: /*
                    375:  * The Linux sigaction() system call. Do the usual conversions,
                    376:  * and just call sigaction(). Some flags and values are silently
                    377:  * ignored (see above).
                    378:  */
                    379: int
                    380: linux_sys_sigaction(p, v, retval)
                    381:        register struct proc *p;
                    382:        void *v;
                    383:        register_t *retval;
                    384: {
                    385:        struct linux_sys_sigaction_args /* {
                    386:                syscallarg(int) signum;
                    387:                syscallarg(struct linux_old_sigaction *) nsa;
                    388:                syscallarg(struct linux_old_sigaction *) osa;
                    389:        } */ *uap = v;
                    390:        struct linux_old_sigaction *nlsa, *olsa, tmplsa;
                    391:        struct sigaction *nbsa, *obsa, tmpbsa;
                    392:        struct sys_sigaction_args sa;
                    393:        caddr_t sg;
                    394:        int error;
                    395:
                    396:        if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
                    397:                return (EINVAL);
                    398:
                    399:        sg = stackgap_init(p->p_emul);
                    400:        nlsa = SCARG(uap, nsa);
                    401:        olsa = SCARG(uap, osa);
                    402:
                    403:        if (olsa != NULL)
                    404:                obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    405:        else
                    406:                obsa = NULL;
                    407:
                    408:        if (nlsa != NULL) {
                    409:                nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    410:                if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
                    411:                        return (error);
                    412:                linux_old_to_bsd_sigaction(&tmplsa, &tmpbsa);
                    413:                if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
                    414:                        return (error);
                    415:        } else
                    416:                nbsa = NULL;
                    417:
                    418:        SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
                    419:        SCARG(&sa, nsa) = nbsa;
                    420:        SCARG(&sa, osa) = obsa;
                    421:
                    422:        /* Silently ignore unknown signals */
                    423:        if (SCARG(&sa, signum) == 0) {
                    424:                if (obsa != NULL) {
                    425:                        obsa->sa_handler = SIG_IGN;
                    426:                        sigemptyset(&obsa->sa_mask);
                    427:                        obsa->sa_flags = 0;
                    428:                }
                    429:        }
                    430:        else {
                    431:                if ((error = sys_sigaction(p, &sa, retval)) != 0)
                    432:                        return (error);
                    433:        }
                    434:
                    435:        if (olsa != NULL) {
                    436:                if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
                    437:                        return (error);
                    438:                bsd_to_linux_old_sigaction(&tmpbsa, &tmplsa);
                    439:                if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
                    440:                        return (error);
                    441:        }
                    442:
                    443:        return (0);
                    444: }
                    445:
                    446: int
                    447: linux_sys_rt_sigaction(p, v, retval)
                    448:        register struct proc *p;
                    449:        void *v;
                    450:        register_t *retval;
                    451: {
                    452:        struct linux_sys_rt_sigaction_args /* {
                    453:                syscallarg(int) signum;
                    454:                syscallarg(struct linux_sigaction *) nsa;
                    455:                syscallarg(struct linux_sigaction *) osa;
                    456:                syscallarg(size_t) sigsetsize;
                    457:        } */ *uap = v;
                    458:        struct linux_sigaction *nlsa, *olsa, tmplsa;
                    459:        struct sigaction *nbsa, *obsa, tmpbsa;
                    460:        struct sys_sigaction_args sa;
                    461:        caddr_t sg;
                    462:        int error;
                    463:
                    464:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    465:                return (EINVAL);
                    466:
                    467:        if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
                    468:                return (EINVAL);
                    469:
                    470:        sg = stackgap_init(p->p_emul);
                    471:        nlsa = SCARG(uap, nsa);
                    472:        olsa = SCARG(uap, osa);
                    473:
                    474:        if (olsa != NULL)
                    475:                obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    476:        else
                    477:                obsa = NULL;
                    478:
                    479:        if (nlsa != NULL) {
                    480:                nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
                    481:                if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
                    482:                        return (error);
                    483:                linux_to_bsd_sigaction(&tmplsa, &tmpbsa);
                    484:                if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
                    485:                        return (error);
                    486:        }
                    487:        else
                    488:                nbsa = NULL;
                    489:
                    490:        SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
                    491:        SCARG(&sa, nsa) = nbsa;
                    492:        SCARG(&sa, osa) = obsa;
                    493:
                    494:        /* Silently ignore unknown signals */
                    495:        if (SCARG(&sa, signum) == 0) {
                    496:                if (obsa != NULL) {
                    497:                        obsa->sa_handler = SIG_IGN;
                    498:                        sigemptyset(&obsa->sa_mask);
                    499:                        obsa->sa_flags = 0;
                    500:                }
                    501:        }
                    502:        else {
                    503:                if ((error = sys_sigaction(p, &sa, retval)) != 0)
                    504:                        return (error);
                    505:        }
                    506:
                    507:        if (olsa != NULL) {
                    508:                if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
                    509:                        return (error);
                    510:                bsd_to_linux_sigaction(&tmpbsa, &tmplsa);
                    511:                if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
                    512:                        return (error);
                    513:        }
                    514:
                    515:        return (0);
                    516: }
                    517:
                    518: /*
                    519:  * The Linux signal() system call. I think that the signal() in the C
                    520:  * library actually calls sigaction, so I doubt this one is ever used.
                    521:  * But hey, it can't hurt having it here. The same restrictions as for
                    522:  * sigaction() apply.
                    523:  */
                    524: int
                    525: linux_sys_signal(p, v, retval)
                    526:        register struct proc *p;
                    527:        void *v;
                    528:        register_t *retval;
                    529: {
                    530:        struct linux_sys_signal_args /* {
                    531:                syscallarg(int) sig;
                    532:                syscallarg(linux_handler_t) handler;
                    533:        } */ *uap = v;
                    534:        caddr_t sg;
                    535:        struct sys_sigaction_args sa_args;
                    536:        struct sigaction *osa, *nsa, tmpsa;
                    537:        int error;
                    538:
                    539:        if (SCARG(uap, sig) < 0 || SCARG(uap, sig) >= LINUX__NSIG)
                    540:                return (EINVAL);
                    541:
                    542:        sg = stackgap_init(p->p_emul);
                    543:        nsa = stackgap_alloc(&sg, sizeof *nsa);
                    544:        osa = stackgap_alloc(&sg, sizeof *osa);
                    545:
                    546:        tmpsa.sa_handler = SCARG(uap, handler);
                    547:        tmpsa.sa_mask = (sigset_t) 0;
                    548:        tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
                    549:        if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
                    550:                return (error);
                    551:
                    552:        SCARG(&sa_args, signum) = linux_to_bsd_sig[SCARG(uap, sig)];
                    553:        SCARG(&sa_args, osa) = osa;
                    554:        SCARG(&sa_args, nsa) = nsa;
                    555:
                    556:        /* Silently ignore unknown signals */
                    557:        if (SCARG(&sa_args, signum) != 0) {
                    558:                if ((error = sys_sigaction(p, &sa_args, retval)))
                    559:                        return (error);
                    560:        }
                    561:
                    562:        if ((error = copyin(osa, &tmpsa, sizeof *osa)))
                    563:                return (error);
                    564:        retval[0] = (register_t) tmpsa.sa_handler;
                    565:
                    566:        return (0);
                    567: }
                    568:
                    569: /*
                    570:  * This is just a copy of the svr4 compat one. I feel so creative now.
                    571:  */
                    572: int
                    573: linux_sys_sigprocmask(p, v, retval)
                    574:        register struct proc *p;
                    575:        void *v;
                    576:        register_t *retval;
                    577: {
                    578:        struct linux_sys_sigprocmask_args /* {
                    579:                syscallarg(int) how;
                    580:                syscallarg(linux_old_sigset_t *) set;
                    581:                syscallarg(linux_old_sigset_t *) oset;
                    582:        } */ *uap = v;
                    583:        linux_old_sigset_t ss;
                    584:        sigset_t bs;
                    585:        int error = 0;
                    586:
                    587:        *retval = 0;
                    588:
                    589:        if (SCARG(uap, oset) != NULL) {
                    590:                /* Fix the return value first if needed */
                    591:                bsd_to_linux_old_sigset(&p->p_sigmask, &ss);
                    592:                if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0)
                    593:                        return (error);
                    594:        }
                    595:
                    596:        if (SCARG(uap, set) == NULL)
                    597:                /* Just examine */
                    598:                return (0);
                    599:
                    600:        if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0)
                    601:                return (error);
                    602:
                    603:        linux_old_to_bsd_sigset(&ss, &bs);
                    604:
                    605:        (void) splhigh();
                    606:
                    607:        switch (SCARG(uap, how)) {
                    608:        case LINUX_SIG_BLOCK:
                    609:                p->p_sigmask |= bs & ~sigcantmask;
                    610:                break;
                    611:
                    612:        case LINUX_SIG_UNBLOCK:
                    613:                p->p_sigmask &= ~bs;
                    614:                break;
                    615:
                    616:        case LINUX_SIG_SETMASK:
                    617:                p->p_sigmask = bs & ~sigcantmask;
                    618:                break;
                    619:
                    620:        default:
                    621:                error = EINVAL;
                    622:                break;
                    623:        }
                    624:
                    625:        (void) spl0();
                    626:
                    627:        return (error);
                    628: }
                    629:
                    630: int
                    631: linux_sys_rt_sigprocmask(p, v, retval)
                    632:        register struct proc *p;
                    633:        void *v;
                    634:        register_t *retval;
                    635: {
                    636:        struct linux_sys_rt_sigprocmask_args /* {
                    637:                syscallarg(int) how;
                    638:                syscallarg(const linux_sigset_t *) set;
                    639:                syscallarg(linux_sigset_t *) oset;
                    640:                syscallarg(size_t) sigsetsize;
                    641:        } */ *uap = v;
                    642:        linux_sigset_t ls;
                    643:        sigset_t bs;
                    644:        int error = 0;
                    645:
                    646:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    647:                return (EINVAL);
                    648:
                    649:        *retval = 0;
                    650:
                    651:        if (SCARG(uap, oset) != NULL) {
                    652:                /* Fix the return value first if needed */
                    653:                bsd_to_linux_sigset(&p->p_sigmask, &ls);
                    654:                if ((error = copyout(&ls, SCARG(uap, oset), sizeof(ls))) != 0)
                    655:                        return (error);
                    656:        }
                    657:
                    658:        if (SCARG(uap, set) == NULL)
                    659:                /* Just examine */
                    660:                return (0);
                    661:
                    662:        if ((error = copyin(SCARG(uap, set), &ls, sizeof(ls))) != 0)
                    663:                return (error);
                    664:
                    665:        linux_to_bsd_sigset(&ls, &bs);
                    666:
                    667:        (void) splhigh();
                    668:
                    669:        switch (SCARG(uap, how)) {
                    670:        case LINUX_SIG_BLOCK:
                    671:                p->p_sigmask |= bs & ~sigcantmask;
                    672:                break;
                    673:
                    674:        case LINUX_SIG_UNBLOCK:
                    675:                p->p_sigmask &= ~bs;
                    676:                break;
                    677:
                    678:        case LINUX_SIG_SETMASK:
                    679:                p->p_sigmask = bs & ~sigcantmask;
                    680:                break;
                    681:
                    682:        default:
                    683:                error = EINVAL;
                    684:                break;
                    685:        }
                    686:
                    687:        (void) spl0();
                    688:
                    689:        return (error);
                    690: }
                    691:
                    692: /*
                    693:  * The functions below really make no distinction between an int
                    694:  * and [linux_]sigset_t. This is ok for now, but it might break
                    695:  * sometime. Then again, sigset_t is trusted to be an int everywhere
                    696:  * else in the kernel too.
                    697:  */
                    698: /* ARGSUSED */
                    699: int
                    700: linux_sys_siggetmask(p, v, retval)
                    701:        register struct proc *p;
                    702:        void *v;
                    703:        register_t *retval;
                    704: {
                    705:
                    706:        bsd_to_linux_old_sigset(&p->p_sigmask, (linux_old_sigset_t *)retval);
                    707:        return (0);
                    708: }
                    709:
                    710: /*
                    711:  * The following three functions fiddle with a process' signal mask.
                    712:  * Convert the signal masks because of the different signal
                    713:  * values for Linux. The need for this is the reason why
                    714:  * they are here, and have not been mapped directly.
                    715:  */
                    716: int
                    717: linux_sys_sigsetmask(p, v, retval)
                    718:        register struct proc *p;
                    719:        void *v;
                    720:        register_t *retval;
                    721: {
                    722:        struct linux_sys_sigsetmask_args /* {
                    723:                syscallarg(linux_old_sigset_t) mask;
                    724:        } */ *uap = v;
                    725:        linux_old_sigset_t mask;
                    726:        sigset_t bsdsig;
                    727:
                    728:        bsd_to_linux_old_sigset(&p->p_sigmask, (linux_old_sigset_t *)retval);
                    729:
                    730:        mask = SCARG(uap, mask);
                    731:        bsd_to_linux_old_sigset(&bsdsig, &mask);
                    732:
                    733:        splhigh();
                    734:        p->p_sigmask = bsdsig & ~sigcantmask;
                    735:        spl0();
                    736:
                    737:        return (0);
                    738: }
                    739:
                    740: int
                    741: linux_sys_sigpending(p, v, retval)
                    742:        register struct proc *p;
                    743:        void *v;
                    744:        register_t *retval;
                    745: {
                    746:        struct linux_sys_sigpending_args /* {
                    747:                syscallarg(linux_old_sigset_t *) mask;
                    748:        } */ *uap = v;
                    749:        sigset_t bs;
                    750:        linux_old_sigset_t ls;
                    751:
                    752:        bs = p->p_siglist & p->p_sigmask;
                    753:        bsd_to_linux_old_sigset(&bs, &ls);
                    754:
                    755:        return (copyout(&ls, SCARG(uap, mask), sizeof ls));
                    756: }
                    757:
                    758: int
                    759: linux_sys_rt_sigpending(p, v, retval)
                    760:        register struct proc *p;
                    761:        void *v;
                    762:        register_t *retval;
                    763: {
                    764:        struct linux_sys_rt_sigpending_args /* {
                    765:                syscallarg(linux_sigset_t *) set;
                    766:                syscallarg(size_t) sigsetsize;
                    767:        } */ *uap = v;
                    768:        sigset_t bs;
                    769:        linux_sigset_t ls;
                    770:
                    771:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    772:                return (EINVAL);
                    773:
                    774:        bs = p->p_siglist & p->p_sigmask;
                    775:        bsd_to_linux_sigset(&bs, &ls);
                    776:
                    777:        return (copyout(&ls, SCARG(uap, set), sizeof ls));
                    778: }
                    779:
                    780: int
                    781: linux_sys_sigsuspend(p, v, retval)
                    782:        register struct proc *p;
                    783:        void *v;
                    784:        register_t *retval;
                    785: {
                    786:        struct linux_sys_sigsuspend_args /* {
                    787:                syscallarg(caddr_t) restart;
                    788:                syscallarg(int) oldmask;
                    789:                syscallarg(int) mask;
                    790:        } */ *uap = v;
                    791:        struct sys_sigsuspend_args sa;
                    792:        linux_old_sigset_t mask = SCARG(uap, mask);
                    793:
                    794:        linux_old_to_bsd_sigset(&mask, &SCARG(&sa, mask));
                    795:        return (sys_sigsuspend(p, &sa, retval));
                    796: }
                    797:
                    798: int
                    799: linux_sys_rt_sigsuspend(p, v, retval)
                    800:        register struct proc *p;
                    801:        void *v;
                    802:        register_t *retval;
                    803: {
                    804:        struct linux_sys_rt_sigsuspend_args /* {
                    805:                syscallarg(sigset_t *) unewset;
                    806:                syscallarg(size_t) sigsetsize;
                    807:        } */ *uap = v;
                    808:        struct sys_sigsuspend_args sa;
                    809:        linux_sigset_t mask;
                    810:        int error;
                    811:
                    812:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    813:                return (EINVAL);
                    814:
                    815:        error = copyin(SCARG(uap, unewset), &mask, sizeof mask);
                    816:        if (error)
                    817:                return (error);
                    818:
                    819:        linux_to_bsd_sigset(&mask, &SCARG(&sa, mask));
                    820:        return (sys_sigsuspend(p, &sa, retval));
                    821: }
                    822:
                    823: /*
                    824:  * Linux' sigaltstack structure is just of a different order than BSD's
                    825:  * so just shuffle the fields around and call our version.
                    826:  */
                    827: int
                    828: linux_sys_sigaltstack(p, v, retval)
                    829:        register struct proc *p;
                    830:        void *v;
                    831:        register_t *retval;
                    832: {
                    833:        struct linux_sys_sigaltstack_args /* {
                    834:                syscallarg(const struct linux_sigaltstack *) nss;
                    835:                syscallarg(struct linux_sigaltstack *) oss;
                    836:        } */ *uap = v;
                    837:        struct linux_sigaltstack linux_ss;
                    838:        struct sigaltstack *bsd_nss, *bsd_oss;
                    839:        struct sys_sigaltstack_args sa;
                    840:        int error;
                    841:        caddr_t sg;
                    842:
                    843:        sg = stackgap_init(p->p_emul);
                    844:
                    845:        if (SCARG(uap, nss) != NULL) {
                    846:                bsd_nss = stackgap_alloc(&sg, sizeof *bsd_nss);
                    847:
                    848:                error = copyin(SCARG(uap, nss), &linux_ss, sizeof linux_ss);
                    849:                if (error)
                    850:                        return (error);
                    851:
                    852:                bsd_nss->ss_sp = linux_ss.ss_sp;
                    853:                bsd_nss->ss_size = linux_ss.ss_size;
                    854:                bsd_nss->ss_flags = (linux_ss.ss_flags & LINUX_SS_DISABLE) ?
                    855:                    SS_DISABLE : 0;
                    856:
                    857:                SCARG(&sa, nss) = bsd_nss;
                    858:        } else
                    859:                SCARG(&sa, nss) = NULL;
                    860:
                    861:        if (SCARG(uap, oss) == NULL) {
                    862:                SCARG(&sa, oss) = NULL;
                    863:                return (sys_sigaltstack(p, &sa, retval));
                    864:        }
                    865:        SCARG(&sa, oss) = bsd_oss = stackgap_alloc(&sg, sizeof *bsd_oss);
                    866:
                    867:        error = sys_sigaltstack(p, &sa, retval);
                    868:        if (error)
                    869:                return (error);
                    870:
                    871:        linux_ss.ss_sp = bsd_oss->ss_sp;
                    872:        linux_ss.ss_size = bsd_oss->ss_size;
                    873:        linux_ss.ss_flags = 0;
                    874:        if (bsd_oss->ss_flags & SS_ONSTACK)
                    875:                linux_ss.ss_flags |= LINUX_SS_ONSTACK;
                    876:        if (bsd_oss->ss_flags & SS_DISABLE)
                    877:                linux_ss.ss_flags |= LINUX_SS_DISABLE;
                    878:        return (copyout(&linux_ss, SCARG(uap, oss), sizeof linux_ss));
                    879: }
                    880:
                    881: /*
                    882:  * The deprecated pause(2), which is really just an instance
                    883:  * of sigsuspend(2).
                    884:  */
                    885: int
                    886: linux_sys_pause(p, v, retval)
                    887:        register struct proc *p;
                    888:        void *v;
                    889:        register_t *retval;
                    890: {
                    891:        struct sys_sigsuspend_args bsa;
                    892:
                    893:        SCARG(&bsa, mask) = p->p_sigmask;
                    894:        return (sys_sigsuspend(p, &bsa, retval));
                    895: }
                    896:
                    897: /*
                    898:  * Once more: only a signal conversion is needed.
                    899:  */
                    900: int
                    901: linux_sys_kill(p, v, retval)
                    902:        register struct proc *p;
                    903:        void *v;
                    904:        register_t *retval;
                    905: {
                    906:        struct linux_sys_kill_args /* {
                    907:                syscallarg(int) pid;
                    908:                syscallarg(int) signum;
                    909:        } */ *uap = v;
                    910:        struct sys_kill_args ka;
                    911:
                    912:        SCARG(&ka, pid) = SCARG(uap, pid);
                    913:        if (SCARG(uap, signum) < 0 || SCARG(uap, signum) >= LINUX__NSIG)
                    914:                return (EINVAL);
                    915:        SCARG(&ka, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
                    916:        return (sys_kill(p, &ka, retval));
                    917: }

CVSweb