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

Annotation of src/sys/compat/linux32/common/linux32_signal.c, Revision 1.1.16.5

1.1.16.5! yamt        1: /*     $NetBSD: linux32_signal.c,v 1.1.16.4 2008/01/21 09:41:35 yamt Exp $ */
1.1.16.2  yamt        2:
                      3: /*-
                      4:  * Copyright (c) 2006 Emmanuel Dreyfus, all rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  * 3. All advertising materials mentioning features or use of this software
                     15:  *    must display the following acknowledgement:
                     16:  *     This product includes software developed by Emmanuel Dreyfus
                     17:  * 4. The name of the author may not be used to endorse or promote
                     18:  *    products derived from this software without specific prior written
                     19:  *    permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE THE AUTHOR AND CONTRIBUTORS ``AS IS''
                     22:  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
                     23:  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     24:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
                     25:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     26:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     27:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     28:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     29:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     30:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     31:  * POSSIBILITY OF SUCH DAMAGE.
                     32:  */
1.1.16.5! yamt       33:
        !            34: #include <sys/cdefs.h>
        !            35: __KERNEL_RCSID(0, "$NetBSD: linux32_signal.c,v 1.1.16.4 2008/01/21 09:41:35 yamt Exp $");
        !            36:
1.1.16.2  yamt       37: #include <sys/param.h>
                     38: #include <sys/ucred.h>
                     39: #include <sys/signalvar.h>
                     40: #include <sys/lwp.h>
                     41: #include <sys/time.h>
1.1.16.3  yamt       42: #include <sys/proc.h>
1.1.16.2  yamt       43:
                     44: #include <compat/netbsd32/netbsd32.h>
                     45:
                     46: #include <compat/linux32/common/linux32_types.h>
                     47: #include <compat/linux32/common/linux32_signal.h>
                     48: #include <compat/linux32/linux32_syscallargs.h>
                     49:
                     50: #define linux32_sigemptyset(s)    memset((s), 0, sizeof(*(s)))
                     51: #define linux32_sigismember(s, n) ((s)->sig[((n) - 1) / LINUX32__NSIG_BPW]  \
                     52:                                    & (1 << ((n) - 1) % LINUX32__NSIG_BPW))
                     53: #define linux32_sigaddset(s, n)   ((s)->sig[((n) - 1) / LINUX32__NSIG_BPW]  \
                     54:                                    |= (1 << ((n) - 1) % LINUX32__NSIG_BPW))
                     55:
                     56: extern const int native_to_linux32_signo[];
                     57: extern const int linux32_to_native_signo[];
                     58:
                     59: void
1.1.16.5! yamt       60: linux32_to_native_sigset(sigset_t *bss, const linux32_sigset_t *lss)
1.1.16.2  yamt       61: {
                     62:        int i, newsig;
                     63:
                     64:        sigemptyset(bss);
                     65:        for (i = 1; i < LINUX32__NSIG; i++) {
                     66:                if (linux32_sigismember(lss, i)) {
                     67:                        newsig = linux32_to_native_signo[i];
                     68:                        if (newsig)
                     69:                                sigaddset(bss, newsig);
                     70:                }
                     71:        }
                     72: }
                     73:
                     74: void
1.1.16.5! yamt       75: native_to_linux32_sigset(linux32_sigset_t *lss, const sigset_t *bss)
1.1.16.2  yamt       76: {
                     77:        int i, newsig;
                     78:
                     79:        linux32_sigemptyset(lss);
                     80:        for (i = 1; i < NSIG; i++) {
                     81:                if (sigismember(bss, i)) {
                     82:                        newsig = native_to_linux32_signo[i];
                     83:                        if (newsig)
                     84:                                linux32_sigaddset(lss, newsig);
                     85:                }
                     86:        }
                     87: }
                     88:
                     89: unsigned int
1.1.16.5! yamt       90: native_to_linux32_sigflags(const int bsf)
1.1.16.2  yamt       91: {
                     92:        unsigned int lsf = 0;
                     93:        if ((bsf & SA_NOCLDSTOP) != 0)
                     94:                lsf |= LINUX32_SA_NOCLDSTOP;
                     95:        if ((bsf & SA_NOCLDWAIT) != 0)
                     96:                lsf |= LINUX32_SA_NOCLDWAIT;
                     97:        if ((bsf & SA_ONSTACK) != 0)
                     98:                lsf |= LINUX32_SA_ONSTACK;
                     99:        if ((bsf & SA_RESTART) != 0)
                    100:                lsf |= LINUX32_SA_RESTART;
                    101:        if ((bsf & SA_NODEFER) != 0)
                    102:                lsf |= LINUX32_SA_NOMASK;
                    103:        if ((bsf & SA_RESETHAND) != 0)
                    104:                lsf |= LINUX32_SA_ONESHOT;
                    105:        if ((bsf & SA_SIGINFO) != 0)
                    106:                lsf |= LINUX32_SA_SIGINFO;
                    107:        return lsf;
                    108: }
                    109:
                    110: int
1.1.16.5! yamt      111: linux32_to_native_sigflags(const unsigned long lsf)
1.1.16.2  yamt      112: {
                    113:        int bsf = 0;
                    114:        if ((lsf & LINUX32_SA_NOCLDSTOP) != 0)
                    115:                bsf |= SA_NOCLDSTOP;
                    116:        if ((lsf & LINUX32_SA_NOCLDWAIT) != 0)
                    117:                bsf |= SA_NOCLDWAIT;
                    118:        if ((lsf & LINUX32_SA_ONSTACK) != 0)
                    119:                bsf |= SA_ONSTACK;
                    120:        if ((lsf & LINUX32_SA_RESTART) != 0)
                    121:                bsf |= SA_RESTART;
                    122:        if ((lsf & LINUX32_SA_ONESHOT) != 0)
                    123:                bsf |= SA_RESETHAND;
                    124:        if ((lsf & LINUX32_SA_NOMASK) != 0)
                    125:                bsf |= SA_NODEFER;
                    126:        if ((lsf & LINUX32_SA_SIGINFO) != 0)
                    127:                bsf |= SA_SIGINFO;
                    128:        if ((lsf & ~LINUX32_SA_ALLBITS) != 0) {
                    129: #ifdef DEBUG_LINUX
                    130:                printf("linux32_old_to_native_sigflags: "
                    131:                    "%lx extra bits ignored\n", lsf);
                    132: #endif
                    133:        }
                    134:        return bsf;
                    135: }
                    136:
                    137: void
1.1.16.5! yamt      138: linux32_to_native_sigaction(struct sigaction *bsa, const struct linux32_sigaction *lsa)
1.1.16.2  yamt      139: {
                    140:        bsa->sa_handler = NETBSD32PTR64(lsa->linux_sa_handler);
                    141:        linux32_to_native_sigset(&bsa->sa_mask, &lsa->linux_sa_mask);
                    142:        bsa->sa_flags = linux32_to_native_sigflags(lsa->linux_sa_flags);
                    143: }
                    144:
                    145: void
1.1.16.5! yamt      146: native_to_linux32_sigaction(struct linux32_sigaction *lsa, const struct sigaction *bsa)
1.1.16.2  yamt      147: {
1.1.16.4  yamt      148:        NETBSD32PTR32(lsa->linux_sa_handler, bsa->sa_handler);
1.1.16.2  yamt      149:        native_to_linux32_sigset(&lsa->linux_sa_mask, &bsa->sa_mask);
                    150:        lsa->linux_sa_flags = native_to_linux32_sigflags(bsa->sa_flags);
1.1.16.4  yamt      151:        NETBSD32PTR32(lsa->linux_sa_restorer, NULL);
1.1.16.2  yamt      152: }
                    153:
                    154: void
1.1.16.5! yamt      155: native_to_linux32_sigaltstack(struct linux32_sigaltstack *lss, const struct sigaltstack *bss)
1.1.16.2  yamt      156: {
1.1.16.4  yamt      157:        NETBSD32PTR32(lss->ss_sp, bss->ss_sp);
1.1.16.2  yamt      158:        lss->ss_size = bss->ss_size;
                    159:        if (bss->ss_flags & SS_ONSTACK)
                    160:            lss->ss_flags = LINUX32_SS_ONSTACK;
                    161:        else if (bss->ss_flags & SS_DISABLE)
                    162:            lss->ss_flags = LINUX32_SS_DISABLE;
                    163:        else
                    164:            lss->ss_flags = 0;
                    165: }
                    166:
                    167:
                    168: void
1.1.16.5! yamt      169: native_to_linux32_old_sigset(linux32_old_sigset_t *lss, const sigset_t *bss)
1.1.16.2  yamt      170: {
                    171:        linux32_sigset_t lsnew;
                    172:
                    173:        native_to_linux32_sigset(&lsnew, bss);
                    174:
                    175:        /* convert new sigset to old sigset */
                    176:        *lss = lsnew.sig[0];
                    177: }
                    178:
                    179: void
1.1.16.5! yamt      180: linux32_old_to_native_sigset(sigset_t *bss, const linux32_old_sigset_t *lss)
1.1.16.2  yamt      181: {
                    182:        linux32_sigset_t ls;
                    183:
                    184:        bzero(&ls, sizeof(ls));
                    185:        ls.sig[0] = *lss;
                    186:
                    187:        linux32_to_native_sigset(bss, &ls);
                    188: }
                    189:
                    190: int
1.1.16.5! yamt      191: linux32_sys_rt_sigaction(struct lwp *l, const struct linux32_sys_rt_sigaction_args *uap, register_t *retval)
1.1.16.2  yamt      192: {
1.1.16.5! yamt      193:        /* {
1.1.16.2  yamt      194:                syscallarg(int) signum;
                    195:                syscallarg(const linux32_sigactionp_t) nsa;
                    196:                syscallarg(linux32_sigactionp_t) osa;
                    197:                syscallarg(netbsd32_size_t) sigsetsize;
1.1.16.5! yamt      198:        } */
1.1.16.2  yamt      199:        struct linux32_sigaction nls32;
                    200:        struct linux32_sigaction ols32;
                    201:        struct sigaction ns;
                    202:        struct sigaction os;
                    203:        int error;
                    204:        int sig;
                    205:        int vers = 0;
                    206:        void *tramp = NULL;
                    207:
                    208:        if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t))
                    209:                return EINVAL;
                    210:
1.1.16.4  yamt      211:        if (SCARG_P32(uap, nsa) != NULL) {
                    212:                if ((error = copyin(SCARG_P32(uap, nsa),
1.1.16.2  yamt      213:                    &nls32, sizeof(nls32))) != 0)
                    214:                        return error;
                    215:                linux32_to_native_sigaction(&ns, &nls32);
                    216:        }
                    217:
                    218:        sig = SCARG(uap, signum);
                    219:        if (sig < 0 || sig >= LINUX32__NSIG)
                    220:                return EINVAL;
                    221:        if (sig > 0 && !linux32_to_native_signo[sig]) {
                    222:                /* unknown signal... */
                    223:                os.sa_handler = SIG_IGN;
                    224:                sigemptyset(&os.sa_mask);
                    225:                os.sa_flags = 0;
                    226:        } else {
1.1.16.3  yamt      227:                if ((error = sigaction1(l,
1.1.16.2  yamt      228:                    linux32_to_native_signo[sig],
1.1.16.4  yamt      229:                    SCARG_P32(uap, nsa) ? &ns : NULL,
                    230:                    SCARG_P32(uap, osa) ? &os : NULL,
1.1.16.2  yamt      231:                    tramp, vers)) != 0)
                    232:                        return error;
                    233:        }
                    234:
1.1.16.4  yamt      235:        if (SCARG_P32(uap, osa) != NULL) {
1.1.16.2  yamt      236:                native_to_linux32_sigaction(&ols32, &os);
                    237:
1.1.16.4  yamt      238:                if ((error = copyout(&ols32, SCARG_P32(uap, osa),
1.1.16.2  yamt      239:                    sizeof(ols32))) != 0)
                    240:                        return error;
                    241:        }
                    242:
                    243:        return 0;
                    244: }
                    245:
                    246: int
1.1.16.5! yamt      247: linux32_sys_rt_sigprocmask(struct lwp *l, const struct linux32_sys_rt_sigprocmask_args *uap, register_t *retval)
1.1.16.2  yamt      248: {
1.1.16.5! yamt      249:        /* {
1.1.16.2  yamt      250:                syscallarg(int) how;
                    251:                syscallarg(const linux32_sigsetp_t) set;
                    252:                syscallarg(linux32_sigsetp_t) oset;
                    253:                syscallarg(netbsd32_size_t) sigsetsize;
1.1.16.5! yamt      254:        } */
1.1.16.2  yamt      255:        struct proc *p = l->l_proc;
                    256:        linux32_sigset_t nls32, ols32;
                    257:        sigset_t ns, os;
                    258:        int error;
                    259:        int how;
                    260:
                    261:        if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t))
                    262:                return EINVAL;
                    263:
                    264:        switch (SCARG(uap, how)) {
                    265:        case LINUX32_SIG_BLOCK:
                    266:                how = SIG_BLOCK;
                    267:                break;
                    268:        case LINUX32_SIG_UNBLOCK:
                    269:                how = SIG_UNBLOCK;
                    270:                break;
                    271:        case LINUX32_SIG_SETMASK:
                    272:                how = SIG_SETMASK;
                    273:                break;
                    274:        default:
                    275:                return EINVAL;
                    276:                break;
                    277:        }
                    278:
1.1.16.4  yamt      279:        if (SCARG_P32(uap, set) != NULL) {
                    280:                if ((error = copyin(SCARG_P32(uap, set),
1.1.16.2  yamt      281:                    &nls32, sizeof(nls32))) != 0)
                    282:                        return error;
                    283:                linux32_to_native_sigset(&ns, &nls32);
                    284:        }
                    285:
1.1.16.3  yamt      286:        mutex_enter(&p->p_smutex);
                    287:        error = sigprocmask1(l, how,
1.1.16.4  yamt      288:            SCARG_P32(uap, set) ? &ns : NULL,
                    289:            SCARG_P32(uap, oset) ? &os : NULL);
1.1.16.3  yamt      290:        mutex_exit(&p->p_smutex);
                    291:
                    292:         if (error != 0)
1.1.16.2  yamt      293:                return error;
                    294:
1.1.16.4  yamt      295:        if (SCARG_P32(uap, oset) != NULL) {
1.1.16.2  yamt      296:                native_to_linux32_sigset(&ols32, &os);
                    297:                if ((error = copyout(&ols32,
1.1.16.4  yamt      298:                    SCARG_P32(uap, oset), sizeof(ols32))) != 0)
1.1.16.2  yamt      299:                        return error;
                    300:        }
                    301:
                    302:        return 0;
                    303: }
                    304:
                    305: int
1.1.16.5! yamt      306: linux32_sys_kill(struct lwp *l, const struct linux32_sys_kill_args *uap, register_t *retval)
        !           307: {
        !           308:        /* {
1.1.16.2  yamt      309:                syscallarg(int) pid;
                    310:                syscallarg(int) signum;
1.1.16.5! yamt      311:        } */
1.1.16.2  yamt      312:
                    313:        struct sys_kill_args ka;
                    314:        int sig;
                    315:
                    316:        SCARG(&ka, pid) = SCARG(uap, pid);
                    317:        sig = SCARG(uap, signum);
                    318:        if (sig < 0 || sig >= LINUX32__NSIG)
                    319:                return (EINVAL);
                    320:        SCARG(&ka, signum) = linux32_to_native_signo[sig];
                    321:        return sys_kill(l, &ka, retval);
                    322: }
                    323:
                    324: int
1.1.16.5! yamt      325: linux32_sys_rt_sigsuspend(struct lwp *l, const struct linux32_sys_rt_sigsuspend_args *uap, register_t *retval)
        !           326: {
        !           327:        /* {
1.1.16.2  yamt      328:                syscallarg(linux32_sigsetp_t) unewset;
                    329:                 syscallarg(netbsd32_size_t) sigsetsize;
1.1.16.5! yamt      330:        } */
1.1.16.2  yamt      331:        linux32_sigset_t lss;
                    332:        sigset_t bss;
                    333:        int error;
                    334:
                    335:        if (SCARG(uap, sigsetsize) != sizeof(linux32_sigset_t))
                    336:                return EINVAL;
                    337:
1.1.16.4  yamt      338:        if ((error = copyin(SCARG_P32(uap, unewset),
1.1.16.2  yamt      339:            &lss, sizeof(linux32_sigset_t))) != 0)
                    340:                return error;
                    341:
                    342:        linux32_to_native_sigset(&bss, &lss);
                    343:
1.1.16.3  yamt      344:        return sigsuspend1(l, &bss);
1.1.16.2  yamt      345: }
                    346:
                    347: int
1.1.16.5! yamt      348: linux32_sys_signal(struct lwp *l, const struct linux32_sys_signal_args *uap, register_t *retval)
1.1.16.2  yamt      349: {
1.1.16.5! yamt      350:        /* {
1.1.16.2  yamt      351:                syscallarg(int) signum;
                    352:                syscallarg(linux32_handler_t) handler;
1.1.16.5! yamt      353:        } */
1.1.16.2  yamt      354:         struct sigaction nbsa, obsa;
                    355:         int error, sig;
                    356:
                    357:         *retval = -1;
                    358:
                    359:         sig = SCARG(uap, signum);
                    360:         if (sig < 0 || sig >= LINUX32__NSIG)
                    361:                 return EINVAL;
                    362:
1.1.16.4  yamt      363:         nbsa.sa_handler = SCARG_P32(uap, handler);
1.1.16.2  yamt      364:         sigemptyset(&nbsa.sa_mask);
                    365:         nbsa.sa_flags = SA_RESETHAND | SA_NODEFER;
                    366:
1.1.16.3  yamt      367:         if ((error = sigaction1(l, linux32_to_native_signo[sig],
1.1.16.2  yamt      368:             &nbsa, &obsa, NULL, 0)) != 0)
                    369:                return error;
                    370:
                    371:         *retval = (int)(long)obsa.sa_handler;
                    372:         return 0;
                    373: }

CVSweb <webmaster@jp.NetBSD.org>