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