[BACK]Return to linux_signal.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / compat / linux / common

Annotation of src/sys/compat/linux/common/linux_signal.c, Revision 1.55

1.55    ! njoly       1: /*     $NetBSD: linux_signal.c,v 1.54 2007/03/04 06:01:24 christos Exp $       */
1.53      ad          2:
1.16      fvdl        3: /*-
                      4:  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
1.1       fvdl        5:  * All rights reserved.
                      6:  *
1.16      fvdl        7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Frank van der Linden and Eric Haszlakiewicz.
                      9:  *
1.1       fvdl       10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
1.16      fvdl       20:  *     This product includes software developed by the NetBSD
                     21:  *     Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
1.1       fvdl       25:  *
1.16      fvdl       26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38: /*
1.1       fvdl       39:  * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp
                     40:  */
                     41:
1.14      erh        42: /*
                     43:  *   Functions in multiarch:
                     44:  *     linux_sys_signal        : linux_sig_notalpha.c
                     45:  *     linux_sys_siggetmask    : linux_sig_notalpha.c
                     46:  *     linux_sys_sigsetmask    : linux_sig_notalpha.c
                     47:  *     linux_sys_pause         : linux_sig_notalpha.c
                     48:  *     linux_sys_sigaction     : linux_sigaction.c
                     49:  *
                     50:  */
                     51:
                     52: /*
                     53:  *   Unimplemented:
                     54:  *     linux_sys_rt_sigtimedwait       : sigsuspend w/timeout.
                     55:  */
1.32      lukem      56:
                     57: #include <sys/cdefs.h>
1.55    ! njoly      58: __KERNEL_RCSID(0, "$NetBSD: linux_signal.c,v 1.54 2007/03/04 06:01:24 christos Exp $");
1.21      drochner   59:
                     60: #define COMPAT_LINUX 1
1.14      erh        61:
1.1       fvdl       62: #include <sys/param.h>
                     63: #include <sys/systm.h>
                     64: #include <sys/namei.h>
                     65: #include <sys/proc.h>
                     66: #include <sys/filedesc.h>
                     67: #include <sys/ioctl.h>
                     68: #include <sys/mount.h>
                     69: #include <sys/kernel.h>
                     70: #include <sys/signal.h>
                     71: #include <sys/signalvar.h>
                     72: #include <sys/malloc.h>
                     73:
                     74: #include <sys/syscallargs.h>
                     75:
1.15      christos   76: #include <compat/linux/common/linux_types.h>
                     77: #include <compat/linux/common/linux_signal.h>
1.49      manu       78: #include <compat/linux/common/linux_exec.h> /* For emul_linux */
                     79: #include <compat/linux/common/linux_machdep.h> /* For LINUX_NPTL */
                     80: #include <compat/linux/common/linux_emuldata.h> /* for linux_emuldata */
1.17      erh        81: #include <compat/linux/common/linux_siginfo.h>
1.45      fvdl       82: #include <compat/linux/common/linux_sigevent.h>
1.15      christos   83: #include <compat/linux/common/linux_util.h>
1.55    ! njoly      84: #include <compat/linux/common/linux_ipc.h>
        !            85: #include <compat/linux/common/linux_sem.h>
1.15      christos   86:
1.1       fvdl       87: #include <compat/linux/linux_syscallargs.h>
                     88:
1.14      erh        89: /* Locally used defines (in bsd<->linux conversion functions): */
1.11      perry      90: #define        linux_sigemptyset(s)    memset((s), 0, sizeof(*(s)))
1.20      itohy      91: #define        linux_sigismember(s, n) ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
                     92:                                        & (1 << ((n) - 1) % LINUX__NSIG_BPW))
                     93: #define        linux_sigaddset(s, n)   ((s)->sig[((n) - 1) / LINUX__NSIG_BPW]  \
                     94:                                        |= (1 << ((n) - 1) % LINUX__NSIG_BPW))
1.6       mycroft    95:
1.36      christos   96: #ifdef DEBUG_LINUX
                     97: #define DPRINTF(a)     uprintf a
                     98: #else
                     99: #define DPRINTF(a)
                    100: #endif
                    101:
1.37      christos  102: extern const int native_to_linux_signo[];
                    103: extern const int linux_to_native_signo[];
1.6       mycroft   104:
1.14      erh       105: /*
1.20      itohy     106:  * Convert between Linux and BSD signal sets.
1.14      erh       107:  */
1.20      itohy     108: #if LINUX__NSIG_WORDS > 1
1.6       mycroft   109: void
1.33      christos  110: linux_old_extra_to_native_sigset(bss, lss, extra)
                    111:        sigset_t *bss;
1.14      erh       112:        const linux_old_sigset_t *lss;
1.20      itohy     113:        const unsigned long *extra;
                    114: {
                    115:        linux_sigset_t lsnew;
                    116:
                    117:        /* convert old sigset to new sigset */
                    118:        linux_sigemptyset(&lsnew);
                    119:        lsnew.sig[0] = *lss;
                    120:        if (extra)
1.33      christos  121:                memcpy(&lsnew.sig[1], extra,
                    122:                    sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
1.20      itohy     123:
1.33      christos  124:        linux_to_native_sigset(bss, &lsnew);
1.20      itohy     125: }
                    126:
                    127: void
1.33      christos  128: native_to_linux_old_extra_sigset(lss, extra, bss)
1.20      itohy     129:        linux_old_sigset_t *lss;
                    130:        unsigned long *extra;
1.33      christos  131:        const sigset_t *bss;
1.20      itohy     132: {
                    133:        linux_sigset_t lsnew;
                    134:
1.33      christos  135:        native_to_linux_sigset(&lsnew, bss);
1.20      itohy     136:
                    137:        /* convert new sigset to old sigset */
                    138:        *lss = lsnew.sig[0];
                    139:        if (extra)
1.33      christos  140:                memcpy(extra, &lsnew.sig[1],
                    141:                    sizeof(linux_sigset_t) - sizeof(linux_old_sigset_t));
1.20      itohy     142: }
1.43      manu      143: #endif /* LINUX__NSIG_WORDS > 1 */
1.20      itohy     144:
                    145: void
1.33      christos  146: linux_to_native_sigset(bss, lss)
                    147:        sigset_t *bss;
1.20      itohy     148:        const linux_sigset_t *lss;
1.1       fvdl      149: {
                    150:        int i, newsig;
                    151:
1.6       mycroft   152:        sigemptyset(bss);
1.20      itohy     153:        for (i = 1; i < LINUX__NSIG; i++) {
1.6       mycroft   154:                if (linux_sigismember(lss, i)) {
1.37      christos  155:                        newsig = linux_to_native_signo[i];
1.1       fvdl      156:                        if (newsig)
1.6       mycroft   157:                                sigaddset(bss, newsig);
1.1       fvdl      158:                }
                    159:        }
                    160: }
                    161:
                    162: void
1.33      christos  163: native_to_linux_sigset(lss, bss)
                    164:        linux_sigset_t *lss;
1.1       fvdl      165:        const sigset_t *bss;
                    166: {
                    167:        int i, newsig;
1.20      itohy     168:
1.6       mycroft   169:        linux_sigemptyset(lss);
                    170:        for (i = 1; i < NSIG; i++) {
                    171:                if (sigismember(bss, i)) {
1.37      christos  172:                        newsig = native_to_linux_signo[i];
1.1       fvdl      173:                        if (newsig)
1.6       mycroft   174:                                linux_sigaddset(lss, newsig);
1.1       fvdl      175:                }
                    176:        }
                    177: }
                    178:
1.34      christos  179: unsigned int
                    180: native_to_linux_sigflags(bsf)
                    181:        const int bsf;
1.33      christos  182: {
1.34      christos  183:        unsigned int lsf = 0;
                    184:        if ((bsf & SA_NOCLDSTOP) != 0)
                    185:                lsf |= LINUX_SA_NOCLDSTOP;
                    186:        if ((bsf & SA_NOCLDWAIT) != 0)
                    187:                lsf |= LINUX_SA_NOCLDWAIT;
                    188:        if ((bsf & SA_ONSTACK) != 0)
                    189:                lsf |= LINUX_SA_ONSTACK;
                    190:        if ((bsf & SA_RESTART) != 0)
                    191:                lsf |= LINUX_SA_RESTART;
                    192:        if ((bsf & SA_NODEFER) != 0)
                    193:                lsf |= LINUX_SA_NOMASK;
                    194:        if ((bsf & SA_RESETHAND) != 0)
                    195:                lsf |= LINUX_SA_ONESHOT;
                    196:        if ((bsf & SA_SIGINFO) != 0)
                    197:                lsf |= LINUX_SA_SIGINFO;
                    198:        return lsf;
1.33      christos  199: }
                    200:
1.34      christos  201: int
                    202: linux_to_native_sigflags(lsf)
                    203:        const unsigned long lsf;
1.33      christos  204: {
1.34      christos  205:        int bsf = 0;
                    206:        if ((lsf & LINUX_SA_NOCLDSTOP) != 0)
                    207:                bsf |= SA_NOCLDSTOP;
                    208:        if ((lsf & LINUX_SA_NOCLDWAIT) != 0)
                    209:                bsf |= SA_NOCLDWAIT;
                    210:        if ((lsf & LINUX_SA_ONSTACK) != 0)
                    211:                bsf |= SA_ONSTACK;
                    212:        if ((lsf & LINUX_SA_RESTART) != 0)
                    213:                bsf |= SA_RESTART;
                    214:        if ((lsf & LINUX_SA_ONESHOT) != 0)
                    215:                bsf |= SA_RESETHAND;
                    216:        if ((lsf & LINUX_SA_NOMASK) != 0)
                    217:                bsf |= SA_NODEFER;
                    218:        if ((lsf & LINUX_SA_SIGINFO) != 0)
                    219:                bsf |= SA_SIGINFO;
1.50      christos  220:        if ((lsf & ~LINUX_SA_ALLBITS) != 0) {
1.36      christos  221:                DPRINTF(("linux_old_to_native_sigflags: "
                    222:                    "%lx extra bits ignored\n", lsf));
1.50      christos  223:        }
1.34      christos  224:        return bsf;
1.33      christos  225: }
                    226:
1.1       fvdl      227: /*
1.46      manu      228:  * Convert between Linux and BSD sigaction structures.
1.1       fvdl      229:  */
                    230: void
1.33      christos  231: linux_old_to_native_sigaction(bsa, lsa)
1.14      erh       232:        struct sigaction *bsa;
1.33      christos  233:        const struct linux_old_sigaction *lsa;
1.14      erh       234: {
1.39      christos  235:        bsa->sa_handler = lsa->linux_sa_handler;
                    236:        linux_old_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
                    237:        bsa->sa_flags = linux_to_native_sigflags(lsa->linux_sa_flags);
1.14      erh       238: }
                    239:
                    240: void
1.33      christos  241: native_to_linux_old_sigaction(lsa, bsa)
1.14      erh       242:        struct linux_old_sigaction *lsa;
1.33      christos  243:        const struct sigaction *bsa;
1.14      erh       244: {
1.39      christos  245:        lsa->linux_sa_handler = bsa->sa_handler;
                    246:        native_to_linux_old_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
                    247:        lsa->linux_sa_flags = native_to_linux_sigflags(bsa->sa_flags);
1.34      christos  248: #ifndef __alpha__
1.39      christos  249:        lsa->linux_sa_restorer = NULL;
1.34      christos  250: #endif
1.14      erh       251: }
                    252:
                    253: /* ...and the new sigaction conversion funcs. */
                    254: void
1.33      christos  255: linux_to_native_sigaction(bsa, lsa)
1.1       fvdl      256:        struct sigaction *bsa;
1.33      christos  257:        const struct linux_sigaction *lsa;
1.1       fvdl      258: {
1.39      christos  259:        bsa->sa_handler = lsa->linux_sa_handler;
                    260:        linux_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
                    261:        bsa->sa_flags = linux_to_native_sigflags(lsa->linux_sa_flags);
1.1       fvdl      262: }
                    263:
                    264: void
1.33      christos  265: native_to_linux_sigaction(lsa, bsa)
1.1       fvdl      266:        struct linux_sigaction *lsa;
1.33      christos  267:        const struct sigaction *bsa;
1.1       fvdl      268: {
1.39      christos  269:        lsa->linux_sa_handler = bsa->sa_handler;
                    270:        native_to_linux_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
                    271:        lsa->linux_sa_flags = native_to_linux_sigflags(bsa->sa_flags);
1.34      christos  272: #ifndef __alpha__
1.39      christos  273:        lsa->linux_sa_restorer = NULL;
1.34      christos  274: #endif
1.1       fvdl      275: }
                    276:
1.14      erh       277: /* ----------------------------------------------------------------------- */
1.1       fvdl      278:
                    279: /*
                    280:  * The Linux sigaction() system call. Do the usual conversions,
                    281:  * and just call sigaction(). Some flags and values are silently
                    282:  * ignored (see above).
                    283:  */
                    284: int
1.52      christos  285: linux_sys_rt_sigaction(struct lwp *l, void *v, register_t *retval)
1.8       thorpej   286: {
1.14      erh       287:        struct linux_sys_rt_sigaction_args /* {
1.1       fvdl      288:                syscallarg(int) signum;
1.12      mycroft   289:                syscallarg(const struct linux_sigaction *) nsa;
1.1       fvdl      290:                syscallarg(struct linux_sigaction *) osa;
1.14      erh       291:                syscallarg(size_t) sigsetsize;
1.8       thorpej   292:        } */ *uap = v;
1.12      mycroft   293:        struct linux_sigaction nlsa, olsa;
                    294:        struct sigaction nbsa, obsa;
1.25      tron      295:        int error, sig;
1.46      manu      296:        void *tramp = NULL;
                    297:        int vers = 0;
1.47      mrg       298: #if defined __amd64__
1.53      ad        299:        struct sigacts *ps = l->l_proc->p_sigacts;
1.46      manu      300: #endif
1.1       fvdl      301:
1.14      erh       302:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    303:                return (EINVAL);
                    304:
1.12      mycroft   305:        if (SCARG(uap, nsa)) {
                    306:                error = copyin(SCARG(uap, nsa), &nlsa, sizeof(nlsa));
                    307:                if (error)
                    308:                        return (error);
1.33      christos  309:                linux_to_native_sigaction(&nbsa, &nlsa);
1.12      mycroft   310:        }
1.46      manu      311:
1.25      tron      312:        sig = SCARG(uap, signum);
                    313:        if (sig < 0 || sig >= LINUX__NSIG)
                    314:                return (EINVAL);
1.37      christos  315:        if (sig > 0 && !linux_to_native_signo[sig]) {
1.29      tv        316:                /* Pretend that we did something useful for unknown signals. */
                    317:                obsa.sa_handler = SIG_IGN;
                    318:                sigemptyset(&obsa.sa_mask);
                    319:                obsa.sa_flags = 0;
                    320:        } else {
1.46      manu      321: #if defined __amd64__
                    322:                if (nlsa.linux_sa_flags & LINUX_SA_RESTORER) {
                    323:                        if ((tramp = nlsa.linux_sa_restorer) != NULL)
                    324:                                vers = 2; /* XXX arch dependant */
                    325:                }
                    326: #endif
                    327:
1.53      ad        328:                error = sigaction1(l, linux_to_native_signo[sig],
1.38      thorpej   329:                    SCARG(uap, nsa) ? &nbsa : NULL,
                    330:                    SCARG(uap, osa) ? &obsa : NULL,
1.46      manu      331:                    tramp, vers);
1.29      tv        332:                if (error)
                    333:                        return (error);
                    334:        }
1.12      mycroft   335:        if (SCARG(uap, osa)) {
1.33      christos  336:                native_to_linux_sigaction(&olsa, &obsa);
1.46      manu      337:
                    338: #if defined __amd64__
                    339:                if (ps->sa_sigdesc[sig].sd_vers != 0) {
                    340:                        olsa.linux_sa_restorer = ps->sa_sigdesc[sig].sd_tramp;
                    341:                        olsa.linux_sa_flags |= LINUX_SA_RESTORER;
                    342:                }
                    343: #endif
                    344:
1.12      mycroft   345:                error = copyout(&olsa, SCARG(uap, osa), sizeof(olsa));
                    346:                if (error)
                    347:                        return (error);
1.1       fvdl      348:        }
1.12      mycroft   349:        return (0);
1.1       fvdl      350: }
                    351:
                    352: int
1.53      ad        353: linux_sigprocmask1(l, how, set, oset)
                    354:        struct lwp *l;
1.17      erh       355:        int how;
                    356:        const linux_old_sigset_t *set;
                    357:        linux_old_sigset_t *oset;
1.8       thorpej   358: {
1.53      ad        359:        struct proc *p = l->l_proc;
1.14      erh       360:        linux_old_sigset_t nlss, olss;
1.12      mycroft   361:        sigset_t nbss, obss;
                    362:        int error;
1.1       fvdl      363:
1.17      erh       364:        switch (how) {
1.1       fvdl      365:        case LINUX_SIG_BLOCK:
1.12      mycroft   366:                how = SIG_BLOCK;
1.1       fvdl      367:                break;
                    368:        case LINUX_SIG_UNBLOCK:
1.12      mycroft   369:                how = SIG_UNBLOCK;
1.1       fvdl      370:                break;
                    371:        case LINUX_SIG_SETMASK:
1.12      mycroft   372:                how = SIG_SETMASK;
1.1       fvdl      373:                break;
                    374:        default:
1.12      mycroft   375:                return (EINVAL);
1.1       fvdl      376:        }
                    377:
1.17      erh       378:        if (set) {
                    379:                error = copyin(set, &nlss, sizeof(nlss));
1.12      mycroft   380:                if (error)
                    381:                        return (error);
1.33      christos  382:                linux_old_to_native_sigset(&nbss, &nlss);
1.12      mycroft   383:        }
1.53      ad        384:        mutex_enter(&p->p_smutex);
                    385:        error = sigprocmask1(l, how,
1.27      tron      386:            set ? &nbss : NULL, oset ? &obss : NULL);
1.53      ad        387:        mutex_exit(&p->p_smutex);
1.12      mycroft   388:        if (error)
1.42      perry     389:                return (error);
1.17      erh       390:        if (oset) {
1.33      christos  391:                native_to_linux_old_sigset(&olss, &obss);
1.17      erh       392:                error = copyout(&olss, oset, sizeof(olss));
1.12      mycroft   393:                if (error)
                    394:                        return (error);
1.42      perry     395:        }
1.12      mycroft   396:        return (error);
1.17      erh       397: }
                    398:
                    399: int
1.52      christos  400: linux_sys_rt_sigprocmask(struct lwp *l, void *v, register_t *retval)
1.17      erh       401: {
                    402:        struct linux_sys_rt_sigprocmask_args /* {
                    403:                syscallarg(int) how;
                    404:                syscallarg(const linux_sigset_t *) set;
                    405:                syscallarg(linux_sigset_t *) oset;
                    406:                syscallarg(size_t) sigsetsize;
                    407:        } */ *uap = v;
1.24      fvdl      408:        linux_sigset_t nlss, olss, *oset;
                    409:        const linux_sigset_t *set;
1.53      ad        410:        struct proc *p = l->l_proc;
1.24      fvdl      411:        sigset_t nbss, obss;
                    412:        int error, how;
                    413:
                    414:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    415:                return (EINVAL);
                    416:
                    417:        switch (SCARG(uap, how)) {
                    418:        case LINUX_SIG_BLOCK:
                    419:                how = SIG_BLOCK;
                    420:                break;
                    421:        case LINUX_SIG_UNBLOCK:
                    422:                how = SIG_UNBLOCK;
                    423:                break;
                    424:        case LINUX_SIG_SETMASK:
                    425:                how = SIG_SETMASK;
                    426:                break;
                    427:        default:
                    428:                return (EINVAL);
1.17      erh       429:        }
                    430:
1.24      fvdl      431:        set = SCARG(uap, set);
                    432:        oset = SCARG(uap, oset);
                    433:
                    434:        if (set) {
                    435:                error = copyin(set, &nlss, sizeof(nlss));
                    436:                if (error)
                    437:                        return (error);
1.33      christos  438:                linux_to_native_sigset(&nbss, &nlss);
1.24      fvdl      439:        }
1.53      ad        440:        mutex_enter(&p->p_smutex);
                    441:        error = sigprocmask1(l, how,
1.27      tron      442:            set ? &nbss : NULL, oset ? &obss : NULL);
1.53      ad        443:        mutex_exit(&p->p_smutex);
1.28      tron      444:        if (!error && oset) {
1.33      christos  445:                native_to_linux_sigset(&olss, &obss);
1.24      fvdl      446:                error = copyout(&olss, oset, sizeof(olss));
1.42      perry     447:        }
1.24      fvdl      448:        return (error);
1.1       fvdl      449: }
                    450:
                    451: int
1.52      christos  452: linux_sys_rt_sigpending(struct lwp *l, void *v, register_t *retval)
1.1       fvdl      453: {
1.14      erh       454:        struct linux_sys_rt_sigpending_args /* {
                    455:                syscallarg(linux_sigset_t *) set;
                    456:                syscallarg(size_t) sigsetsize;
                    457:        } */ *uap = v;
1.12      mycroft   458:        sigset_t bss;
                    459:        linux_sigset_t lss;
1.6       mycroft   460:
1.14      erh       461:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    462:                return (EINVAL);
                    463:
1.53      ad        464:        sigpending1(l, &bss);
1.33      christos  465:        native_to_linux_sigset(&lss, &bss);
1.14      erh       466:        return copyout(&lss, SCARG(uap, set), sizeof(lss));
1.1       fvdl      467: }
1.24      fvdl      468:
1.43      manu      469: #ifndef __amd64__
1.1       fvdl      470: int
1.52      christos  471: linux_sys_sigpending(struct lwp *l, void *v, register_t *retval)
1.8       thorpej   472: {
1.9       mycroft   473:        struct linux_sys_sigpending_args /* {
1.14      erh       474:                syscallarg(linux_old_sigset_t *) mask;
1.8       thorpej   475:        } */ *uap = v;
1.12      mycroft   476:        sigset_t bss;
1.14      erh       477:        linux_old_sigset_t lss;
1.1       fvdl      478:
1.53      ad        479:        sigpending1(l, &bss);
1.33      christos  480:        native_to_linux_old_sigset(&lss, &bss);
1.12      mycroft   481:        return copyout(&lss, SCARG(uap, set), sizeof(lss));
1.1       fvdl      482: }
                    483:
                    484: int
1.52      christos  485: linux_sys_sigsuspend(struct lwp *l, void *v, register_t *retval)
1.8       thorpej   486: {
1.9       mycroft   487:        struct linux_sys_sigsuspend_args /* {
1.54      christos  488:                syscallarg(void *) restart;
1.3       fvdl      489:                syscallarg(int) oldmask;
1.1       fvdl      490:                syscallarg(int) mask;
1.8       thorpej   491:        } */ *uap = v;
1.14      erh       492:        linux_old_sigset_t lss;
                    493:        sigset_t bss;
                    494:
                    495:        lss = SCARG(uap, mask);
1.33      christos  496:        linux_old_to_native_sigset(&bss, &lss);
1.53      ad        497:        return (sigsuspend1(l, &bss));
1.14      erh       498: }
1.43      manu      499: #endif /* __amd64__ */
                    500:
1.14      erh       501: int
1.52      christos  502: linux_sys_rt_sigsuspend(struct lwp *l, void *v, register_t *retval)
1.14      erh       503: {
                    504:        struct linux_sys_rt_sigsuspend_args /* {
                    505:                syscallarg(linux_sigset_t *) unewset;
                    506:                syscallarg(size_t) sigsetsize;
                    507:        } */ *uap = v;
1.12      mycroft   508:        linux_sigset_t lss;
                    509:        sigset_t bss;
1.14      erh       510:        int error;
                    511:
                    512:        if (SCARG(uap, sigsetsize) != sizeof(linux_sigset_t))
                    513:                return (EINVAL);
                    514:
                    515:        error = copyin(SCARG(uap, unewset), &lss, sizeof(linux_sigset_t));
                    516:        if (error)
                    517:                return (error);
                    518:
1.33      christos  519:        linux_to_native_sigset(&bss, &lss);
1.14      erh       520:
1.53      ad        521:        return (sigsuspend1(l, &bss));
1.3       fvdl      522: }
                    523:
                    524: /*
1.14      erh       525:  * Once more: only a signal conversion is needed.
                    526:  * Note: also used as sys_rt_queueinfo.  The info field is ignored.
1.3       fvdl      527:  */
                    528: int
1.40      thorpej   529: linux_sys_rt_queueinfo(l, v, retval)
                    530:        struct lwp *l;
1.14      erh       531:        void *v;
1.3       fvdl      532:        register_t *retval;
1.14      erh       533: {
                    534:        /* XXX XAX This isn't this really int, int, siginfo_t *, is it? */
                    535: #if 0
                    536:        struct linux_sys_rt_queueinfo_args /* {
                    537:                syscallarg(int) pid;
                    538:                syscallarg(int) signum;
                    539:                syscallarg(siginfo_t *) uinfo;
                    540:        } */ *uap = v;
                    541: #endif
1.3       fvdl      542:
1.14      erh       543:        /* XXX To really implement this we need to      */
                    544:        /* XXX keep a list of queued signals somewhere. */
1.40      thorpej   545:        return (linux_sys_kill(l, v, retval));
1.1       fvdl      546: }
                    547:
                    548: int
1.40      thorpej   549: linux_sys_kill(l, v, retval)
                    550:        struct lwp *l;
1.8       thorpej   551:        void *v;
                    552:        register_t *retval;
                    553: {
1.9       mycroft   554:        struct linux_sys_kill_args /* {
1.1       fvdl      555:                syscallarg(int) pid;
                    556:                syscallarg(int) signum;
1.8       thorpej   557:        } */ *uap = v;
1.40      thorpej   558:
1.9       mycroft   559:        struct sys_kill_args ka;
1.25      tron      560:        int sig;
1.6       mycroft   561:
                    562:        SCARG(&ka, pid) = SCARG(uap, pid);
1.25      tron      563:        sig = SCARG(uap, signum);
                    564:        if (sig < 0 || sig >= LINUX__NSIG)
                    565:                return (EINVAL);
1.37      christos  566:        SCARG(&ka, signum) = linux_to_native_signo[sig];
1.40      thorpej   567:        return sys_kill(l, &ka, retval);
1.1       fvdl      568: }
1.30      christos  569:
                    570: #ifdef LINUX_SS_ONSTACK
                    571: static void linux_to_native_sigaltstack __P((struct sigaltstack *,
                    572:     const struct linux_sigaltstack *));
                    573:
                    574: static void
                    575: linux_to_native_sigaltstack(bss, lss)
                    576:        struct sigaltstack *bss;
                    577:        const struct linux_sigaltstack *lss;
                    578: {
                    579:        bss->ss_sp = lss->ss_sp;
                    580:        bss->ss_size = lss->ss_size;
                    581:        if (lss->ss_flags & LINUX_SS_ONSTACK)
                    582:            bss->ss_flags = SS_ONSTACK;
                    583:        else if (lss->ss_flags & LINUX_SS_DISABLE)
                    584:            bss->ss_flags = SS_DISABLE;
                    585:        else
                    586:            bss->ss_flags = 0;
                    587: }
                    588:
1.41      christos  589: void
1.30      christos  590: native_to_linux_sigaltstack(lss, bss)
                    591:        struct linux_sigaltstack *lss;
                    592:        const struct sigaltstack *bss;
                    593: {
                    594:        lss->ss_sp = bss->ss_sp;
                    595:        lss->ss_size = bss->ss_size;
                    596:        if (bss->ss_flags & SS_ONSTACK)
                    597:            lss->ss_flags = LINUX_SS_ONSTACK;
                    598:        else if (bss->ss_flags & SS_DISABLE)
                    599:            lss->ss_flags = LINUX_SS_DISABLE;
                    600:        else
                    601:            lss->ss_flags = 0;
                    602: }
                    603:
                    604: int
1.52      christos  605: linux_sys_sigaltstack(struct lwp *l, void *v, register_t *retval)
1.30      christos  606: {
                    607:        struct linux_sys_sigaltstack_args /* {
                    608:                syscallarg(const struct linux_sigaltstack *) ss;
                    609:                syscallarg(struct linux_sigaltstack *) oss;
                    610:        } */ *uap = v;
                    611:        struct linux_sigaltstack ss;
1.48      christos  612:        struct sigaltstack nss;
1.53      ad        613:        struct proc *p = l->l_proc;
                    614:        int error = 0;
1.30      christos  615:
1.48      christos  616:        if (SCARG(uap, oss)) {
1.53      ad        617:                native_to_linux_sigaltstack(&ss, &l->l_sigstk);
1.48      christos  618:                if ((error = copyout(&ss, SCARG(uap, oss), sizeof(ss))) != 0)
                    619:                        return error;
                    620:        }
                    621:
1.30      christos  622:        if (SCARG(uap, ss) != NULL) {
                    623:                if ((error = copyin(SCARG(uap, ss), &ss, sizeof(ss))) != 0)
                    624:                        return error;
                    625:                linux_to_native_sigaltstack(&nss, &ss);
                    626:
1.53      ad        627:                mutex_enter(&p->p_smutex);
                    628:
1.48      christos  629:                if (nss.ss_flags & ~SS_ALLBITS)
1.53      ad        630:                        error = EINVAL;
                    631:                else if (nss.ss_flags & SS_DISABLE) {
                    632:                        if (l->l_sigstk.ss_flags & SS_ONSTACK)
                    633:                                error = EINVAL;
                    634:                } else if (nss.ss_size < LINUX_MINSIGSTKSZ)
                    635:                        error = ENOMEM;
1.30      christos  636:
1.53      ad        637:                if (error == 0)
                    638:                        l->l_sigstk = nss;
                    639:
                    640:                mutex_exit(&p->p_smutex);
1.30      christos  641:        }
1.48      christos  642:
1.53      ad        643:        return error;
1.30      christos  644: }
1.44      jmc       645: #endif /* LINUX_SS_ONSTACK */
1.49      manu      646:
                    647: #ifdef LINUX_NPTL
                    648: int
                    649: linux_sys_tkill(l, v, retval)
                    650:        struct lwp *l;
                    651:        void *v;
                    652:        register_t *retval;
                    653: {
                    654:        struct linux_sys_tkill_args /* {
                    655:                syscallarg(int) tid;
                    656:                syscallarg(int) sig;
                    657:        } */ *uap = v;
                    658:        struct linux_sys_kill_args cup;
                    659:
                    660:        /* We use the PID as the TID ... */
                    661:        SCARG(&cup, pid) = SCARG(uap, tid);
                    662:        SCARG(&cup, signum) = SCARG(uap, sig);
                    663:
                    664:        return linux_sys_kill(l, &cup, retval);
                    665: }
                    666:
                    667: int
                    668: linux_sys_tgkill(l, v, retval)
                    669:        struct lwp *l;
                    670:        void *v;
                    671:        register_t *retval;
                    672: {
                    673:        struct linux_sys_tgkill_args /* {
                    674:                syscallarg(int) tgid;
                    675:                syscallarg(int) tid;
                    676:                syscallarg(int) sig;
                    677:        } */ *uap = v;
                    678:        struct linux_sys_kill_args cup;
                    679:        struct linux_emuldata *led;
                    680:        struct proc *p;
                    681:
                    682:        SCARG(&cup, pid) = SCARG(uap, tid);
                    683:        SCARG(&cup, signum) = SCARG(uap, sig);
                    684:
                    685:        if (SCARG(uap, tgid) == -1)
                    686:                return linux_sys_kill(l, &cup, retval);
                    687:
                    688:        /* We use the PID as the TID, but make sure the group ID is right */
                    689:        if ((p = pfind(SCARG(uap, tid))) == NULL)
                    690:                return ESRCH;
                    691:
                    692:        if (p->p_emul != &emul_linux)
                    693:                return ESRCH;
                    694:
                    695:        led = p->p_emuldata;
                    696:
                    697:        if (led->s->group_pid != SCARG(uap, tgid))
                    698:                return ESRCH;
                    699:
                    700:        return linux_sys_kill(l, &cup, retval);
                    701: }
                    702: #endif /* LINUX_NPTL */

CVSweb <webmaster@jp.NetBSD.org>