linux_sigarray.c revision 1.3
11.2Sfvdl/* $NetBSD: linux_sigarray.c,v 1.3 1995/03/10 22:55:04 fvdl Exp $ */ 21.1Sfvdl 31.1Sfvdl/* 41.1Sfvdl * Copyright (c) 1995 Frank van der Linden 51.1Sfvdl * All rights reserved. 61.1Sfvdl * 71.1Sfvdl * Redistribution and use in source and binary forms, with or without 81.1Sfvdl * modification, are permitted provided that the following conditions 91.1Sfvdl * are met: 101.1Sfvdl * 1. Redistributions of source code must retain the above copyright 111.1Sfvdl * notice, this list of conditions and the following disclaimer. 121.1Sfvdl * 2. Redistributions in binary form must reproduce the above copyright 131.1Sfvdl * notice, this list of conditions and the following disclaimer in the 141.1Sfvdl * documentation and/or other materials provided with the distribution. 151.1Sfvdl * 3. All advertising materials mentioning features or use of this software 161.1Sfvdl * must display the following acknowledgement: 171.1Sfvdl * This product includes software developed for the NetBSD Project 181.1Sfvdl * by Frank van der Linden 191.1Sfvdl * 4. The name of the author may not be used to endorse or promote products 201.1Sfvdl * derived from this software without specific prior written permission 211.1Sfvdl * 221.1Sfvdl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 231.1Sfvdl * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 241.1Sfvdl * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 251.1Sfvdl * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 261.1Sfvdl * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 271.1Sfvdl * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 281.1Sfvdl * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 291.1Sfvdl * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 301.1Sfvdl * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 311.1Sfvdl * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 321.1Sfvdl * 331.1Sfvdl * heavily from: svr4_signal.c,v 1.7 1995/01/09 01:04:21 christos Exp 341.1Sfvdl */ 351.1Sfvdl 361.1Sfvdl#include <sys/param.h> 371.1Sfvdl#include <sys/systm.h> 381.1Sfvdl#include <sys/namei.h> 391.1Sfvdl#include <sys/proc.h> 401.1Sfvdl#include <sys/filedesc.h> 411.1Sfvdl#include <sys/ioctl.h> 421.1Sfvdl#include <sys/mount.h> 431.1Sfvdl#include <sys/kernel.h> 441.1Sfvdl#include <sys/signal.h> 451.1Sfvdl#include <sys/signalvar.h> 461.1Sfvdl#include <sys/malloc.h> 471.1Sfvdl 481.1Sfvdl#include <sys/syscallargs.h> 491.1Sfvdl 501.1Sfvdl#include <compat/linux/linux_types.h> 511.1Sfvdl#include <compat/linux/linux_syscallargs.h> 521.1Sfvdl#include <compat/linux/linux_util.h> 531.1Sfvdl#include <compat/linux/linux_signal.h> 541.1Sfvdl 551.1Sfvdl/* 561.3Sfvdl * Most of ths stuff in this file is taken from Christos' SVR4 emul 571.1Sfvdl * code. The things that need to be done are largely the same, so 581.1Sfvdl * re-inventing the wheel doesn't make much sense. 591.1Sfvdl */ 601.1Sfvdl 611.1Sfvdl/* 621.1Sfvdl * Some boring signal conversion functions. Just a switch() for all signals; 631.1Sfvdl * return the converted signal number, 0 if not supported. 641.1Sfvdl */ 651.1Sfvdl 661.1Sfvdlint 671.1Sfvdlbsd_to_linux_sig(sig) 681.1Sfvdl int sig; 691.1Sfvdl{ 701.1Sfvdl switch(sig) { 711.1Sfvdl case SIGHUP: 721.1Sfvdl return LINUX_SIGHUP; 731.1Sfvdl case SIGINT: 741.1Sfvdl return LINUX_SIGINT; 751.1Sfvdl case SIGQUIT: 761.1Sfvdl return LINUX_SIGQUIT; 771.1Sfvdl case SIGILL: 781.1Sfvdl return LINUX_SIGILL; 791.1Sfvdl case SIGTRAP: 801.1Sfvdl return LINUX_SIGTRAP; 811.1Sfvdl case SIGABRT: 821.1Sfvdl return LINUX_SIGABRT; 831.1Sfvdl case SIGFPE: 841.1Sfvdl return LINUX_SIGFPE; 851.1Sfvdl case SIGKILL: 861.1Sfvdl return LINUX_SIGKILL; 871.1Sfvdl case SIGBUS: 881.1Sfvdl return LINUX_SIGBUS; 891.1Sfvdl case SIGSEGV: 901.1Sfvdl return LINUX_SIGSEGV; 911.1Sfvdl case SIGPIPE: 921.1Sfvdl return LINUX_SIGPIPE; 931.1Sfvdl case SIGALRM: 941.1Sfvdl return LINUX_SIGALRM; 951.1Sfvdl case SIGTERM: 961.1Sfvdl return LINUX_SIGTERM; 971.1Sfvdl case SIGURG: 981.1Sfvdl return LINUX_SIGURG; 991.1Sfvdl case SIGSTOP: 1001.1Sfvdl return LINUX_SIGSTOP; 1011.1Sfvdl case SIGTSTP: 1021.1Sfvdl return LINUX_SIGTSTP; 1031.1Sfvdl case SIGCONT: 1041.1Sfvdl return LINUX_SIGCONT; 1051.1Sfvdl case SIGCHLD: 1061.1Sfvdl return LINUX_SIGCHLD; 1071.1Sfvdl case SIGTTIN: 1081.1Sfvdl return LINUX_SIGTTIN; 1091.1Sfvdl case SIGTTOU: 1101.1Sfvdl return LINUX_SIGTTOU; 1111.1Sfvdl case SIGIO: 1121.1Sfvdl return LINUX_SIGIO; 1131.1Sfvdl case SIGXCPU: 1141.1Sfvdl return LINUX_SIGXCPU; 1151.1Sfvdl case SIGXFSZ: 1161.1Sfvdl return LINUX_SIGXFSZ; 1171.1Sfvdl case SIGVTALRM: 1181.1Sfvdl return LINUX_SIGVTALRM; 1191.1Sfvdl case SIGPROF: 1201.1Sfvdl return LINUX_SIGPROF; 1211.1Sfvdl case SIGWINCH: 1221.1Sfvdl return LINUX_SIGWINCH; 1231.1Sfvdl case SIGUSR1: 1241.1Sfvdl return LINUX_SIGUSR1; 1251.1Sfvdl case SIGUSR2: 1261.1Sfvdl return LINUX_SIGUSR2; 1271.1Sfvdl /* Not supported: EMT, SYS, INFO */ 1281.1Sfvdl } 1291.1Sfvdl return 0; 1301.1Sfvdl} 1311.1Sfvdl 1321.1Sfvdlint 1331.1Sfvdllinux_to_bsd_sig(sig) 1341.1Sfvdl int sig; 1351.1Sfvdl{ 1361.1Sfvdl switch(sig) { 1371.1Sfvdl case LINUX_SIGHUP: 1381.1Sfvdl return SIGHUP; 1391.1Sfvdl case LINUX_SIGINT: 1401.1Sfvdl return SIGINT; 1411.1Sfvdl case LINUX_SIGQUIT: 1421.1Sfvdl return SIGQUIT; 1431.1Sfvdl case LINUX_SIGILL: 1441.1Sfvdl return SIGILL; 1451.1Sfvdl case LINUX_SIGTRAP: 1461.1Sfvdl return SIGTRAP; 1471.1Sfvdl case LINUX_SIGABRT: 1481.1Sfvdl return SIGABRT; 1491.1Sfvdl case LINUX_SIGBUS: 1501.1Sfvdl return SIGBUS; 1511.1Sfvdl case LINUX_SIGFPE: 1521.1Sfvdl return SIGFPE; 1531.1Sfvdl case LINUX_SIGKILL: 1541.1Sfvdl return SIGKILL; 1551.1Sfvdl case LINUX_SIGUSR1: 1561.1Sfvdl return SIGUSR1; 1571.1Sfvdl case LINUX_SIGSEGV: 1581.1Sfvdl return SIGSEGV; 1591.1Sfvdl case LINUX_SIGUSR2: 1601.1Sfvdl return SIGUSR2; 1611.1Sfvdl case LINUX_SIGPIPE: 1621.1Sfvdl return SIGPIPE; 1631.1Sfvdl case LINUX_SIGALRM: 1641.1Sfvdl return SIGALRM; 1651.1Sfvdl case LINUX_SIGTERM: 1661.1Sfvdl return SIGTERM; 1671.1Sfvdl case LINUX_SIGCHLD: 1681.1Sfvdl return SIGCHLD; 1691.1Sfvdl case LINUX_SIGCONT: 1701.1Sfvdl return SIGCONT; 1711.1Sfvdl case LINUX_SIGSTOP: 1721.1Sfvdl return SIGSTOP; 1731.1Sfvdl case LINUX_SIGTSTP: 1741.1Sfvdl return SIGTSTP; 1751.1Sfvdl case LINUX_SIGTTIN: 1761.1Sfvdl return SIGTTIN; 1771.1Sfvdl case LINUX_SIGTTOU: 1781.1Sfvdl return SIGTTOU; 1791.1Sfvdl case LINUX_SIGURG: 1801.1Sfvdl return SIGURG; 1811.1Sfvdl case LINUX_SIGXCPU: 1821.1Sfvdl return SIGXCPU; 1831.1Sfvdl case LINUX_SIGXFSZ: 1841.1Sfvdl return SIGXFSZ; 1851.1Sfvdl case LINUX_SIGVTALRM: 1861.1Sfvdl return SIGVTALRM; 1871.1Sfvdl case LINUX_SIGPROF: 1881.1Sfvdl return SIGPROF; 1891.1Sfvdl case LINUX_SIGWINCH: 1901.1Sfvdl return SIGWINCH; 1911.1Sfvdl case LINUX_SIGIO: 1921.1Sfvdl return SIGIO; 1931.1Sfvdl /* Not supported: STKFLT, PWR */ 1941.1Sfvdl } 1951.1Sfvdl return 0; 1961.1Sfvdl} 1971.1Sfvdl 1981.1Sfvdl/* 1991.1Sfvdl * Ok, we know that Linux and BSD signals both are just an unsigned int. 2001.1Sfvdl * Don't bother to use the sigismember() stuff for now. 2011.1Sfvdl */ 2021.1Sfvdlstatic void 2031.1Sfvdllinux_to_bsd_sigset(lss, bss) 2041.1Sfvdl const linux_sigset_t *lss; 2051.1Sfvdl sigset_t *bss; 2061.1Sfvdl{ 2071.1Sfvdl int i, newsig; 2081.1Sfvdl 2091.1Sfvdl *bss = (sigset_t) 0; 2101.1Sfvdl for (i = 1; i <= LINUX_NSIG; i++) { 2111.1Sfvdl if (*lss & sigmask(i)) { 2121.1Sfvdl newsig = linux_to_bsd_sig(i); 2131.1Sfvdl if (newsig) 2141.1Sfvdl *bss |= sigmask(newsig); 2151.1Sfvdl } 2161.1Sfvdl } 2171.1Sfvdl} 2181.1Sfvdl 2191.1Sfvdlvoid 2201.1Sfvdlbsd_to_linux_sigset(bss, lss) 2211.1Sfvdl const sigset_t *bss; 2221.1Sfvdl linux_sigset_t *lss; 2231.1Sfvdl{ 2241.1Sfvdl int i, newsig; 2251.1Sfvdl 2261.1Sfvdl *lss = (linux_sigset_t) 0; 2271.1Sfvdl for (i = 1; i <= NSIG; i++) { 2281.1Sfvdl if (*bss & sigmask(i)) { 2291.1Sfvdl newsig = bsd_to_linux_sig(i); 2301.1Sfvdl if (newsig) 2311.1Sfvdl *lss |= sigmask(newsig); 2321.1Sfvdl } 2331.1Sfvdl } 2341.1Sfvdl} 2351.1Sfvdl 2361.1Sfvdl/* 2371.1Sfvdl * Convert between Linux and BSD sigaction structures. Linux has 2381.1Sfvdl * one extra field (sa_restorer) which we don't support. The Linux 2391.1Sfvdl * SA_ONESHOT and SA_NOMASK flags (which together form the old 2401.1Sfvdl * SysV signal behavior) are silently ignored. XXX 2411.1Sfvdl */ 2421.1Sfvdlvoid 2431.1Sfvdllinux_to_bsd_sigaction(lsa, bsa) 2441.1Sfvdl struct linux_sigaction *lsa; 2451.1Sfvdl struct sigaction *bsa; 2461.1Sfvdl{ 2471.1Sfvdl bsa->sa_handler = lsa->sa_handler; 2481.1Sfvdl linux_to_bsd_sigset(&bsa->sa_mask, &lsa->sa_mask); 2491.1Sfvdl bsa->sa_flags = 0; 2501.1Sfvdl bsa->sa_flags |= cvtto_bsd_mask(lsa->sa_flags, LINUX_SA_NOCLDSTOP, 2511.1Sfvdl SA_NOCLDSTOP); 2521.1Sfvdl bsa->sa_flags |= cvtto_bsd_mask(lsa->sa_flags, LINUX_SA_ONSTACK, 2531.1Sfvdl SA_ONSTACK); 2541.1Sfvdl bsa->sa_flags |= cvtto_bsd_mask(lsa->sa_flags, LINUX_SA_RESTART, 2551.1Sfvdl SA_RESTART); 2561.1Sfvdl} 2571.1Sfvdl 2581.1Sfvdlvoid 2591.1Sfvdlbsd_to_linux_sigaction(bsa, lsa) 2601.1Sfvdl struct sigaction *bsa; 2611.1Sfvdl struct linux_sigaction *lsa; 2621.1Sfvdl{ 2631.1Sfvdl lsa->sa_handler = bsa->sa_handler; 2641.1Sfvdl bsd_to_linux_sigset(&lsa->sa_mask, &bsa->sa_mask); 2651.1Sfvdl lsa->sa_flags = 0; 2661.1Sfvdl lsa->sa_flags |= cvtto_linux_mask(bsa->sa_flags, SA_NOCLDSTOP, 2671.1Sfvdl LINUX_SA_NOCLDSTOP); 2681.1Sfvdl lsa->sa_flags |= cvtto_linux_mask(bsa->sa_flags, SA_ONSTACK, 2691.1Sfvdl LINUX_SA_ONSTACK); 2701.1Sfvdl lsa->sa_flags |= cvtto_linux_mask(bsa->sa_flags, SA_RESTART, 2711.1Sfvdl LINUX_SA_RESTART); 2721.1Sfvdl lsa->sa_restorer = NULL; 2731.1Sfvdl} 2741.1Sfvdl 2751.1Sfvdl 2761.1Sfvdl/* 2771.1Sfvdl * The Linux sigaction() system call. Do the usual conversions, 2781.1Sfvdl * and just call sigaction(). Some flags and values are silently 2791.1Sfvdl * ignored (see above). 2801.1Sfvdl */ 2811.1Sfvdlint 2821.1Sfvdllinux_sigaction(p, uap, retval) 2831.1Sfvdl register struct proc *p; 2841.1Sfvdl struct linux_sigaction_args /* { 2851.1Sfvdl syscallarg(int) signum; 2861.1Sfvdl syscallarg(struct linux_sigaction *) nsa; 2871.1Sfvdl syscallarg(struct linux_sigaction *) osa; 2881.1Sfvdl } */ *uap; 2891.1Sfvdl register_t *retval; 2901.1Sfvdl{ 2911.1Sfvdl struct sigaction *nbsda = NULL, *obsda = NULL, tmpbsda; 2921.1Sfvdl struct linux_sigaction *nlsa, *olsa, tmplsa; 2931.1Sfvdl struct sigaction_args sa; 2941.1Sfvdl caddr_t sg; 2951.1Sfvdl int error; 2961.1Sfvdl 2971.1Sfvdl sg = stackgap_init(); 2981.1Sfvdl olsa = SCARG(uap, osa); 2991.1Sfvdl nlsa = SCARG(uap, nsa); 3001.1Sfvdl 3011.1Sfvdl if (olsa != NULL) 3021.1Sfvdl obsda = stackgap_alloc(&sg, sizeof (struct sigaction)); 3031.1Sfvdl 3041.1Sfvdl if (nlsa != NULL) { 3051.1Sfvdl nbsda = stackgap_alloc(&sg, sizeof (struct sigaction)); 3061.1Sfvdl if ((error = copyin(nlsa, &tmplsa, sizeof tmplsa))) 3071.1Sfvdl return error; 3081.1Sfvdl linux_to_bsd_sigaction(&tmplsa, &tmpbsda); 3091.1Sfvdl if ((error = copyout(&tmpbsda, nbsda, sizeof tmpbsda))) 3101.1Sfvdl return error; 3111.1Sfvdl } 3121.1Sfvdl 3131.1Sfvdl SCARG(&sa, signum) = linux_to_bsd_sig(SCARG(uap, signum)); 3141.1Sfvdl SCARG(&sa, nsa) = nbsda; 3151.1Sfvdl SCARG(&sa, osa) = obsda; 3161.1Sfvdl 3171.1Sfvdl if ((error = sigaction(p, &sa, retval))) 3181.1Sfvdl return error; 3191.1Sfvdl 3201.1Sfvdl if (olsa != NULL) { 3211.1Sfvdl if ((error = copyin(obsda, &tmpbsda, sizeof tmpbsda))) 3221.1Sfvdl return error; 3231.1Sfvdl bsd_to_linux_sigaction(&tmpbsda, &tmplsa); 3241.1Sfvdl if ((error = copyout(&tmplsa, olsa, sizeof tmplsa))) 3251.1Sfvdl return error; 3261.1Sfvdl } 3271.1Sfvdl return 0; 3281.1Sfvdl} 3291.1Sfvdl 3301.1Sfvdl/* 3311.1Sfvdl * The Linux signal() system call. I think that the signal() in the C 3321.1Sfvdl * library actually calls sigaction, so I doubt this one is ever used. 3331.1Sfvdl * But hey, it can't hurt having it here. The same restrictions as for 3341.1Sfvdl * sigaction() apply. 3351.1Sfvdl */ 3361.1Sfvdlint 3371.1Sfvdllinux_signal(p, uap, retval) 3381.1Sfvdl register struct proc *p; 3391.1Sfvdl struct linux_signal_args /* { 3401.1Sfvdl syscallarg(int) sig; 3411.1Sfvdl syscallarg(linux_handler_t) handler; 3421.1Sfvdl } */ *uap; 3431.1Sfvdl register_t *retval; 3441.1Sfvdl{ 3451.1Sfvdl caddr_t sg; 3461.1Sfvdl struct sigaction_args sa_args; 3471.1Sfvdl struct sigaction *osa, *nsa, tmpsa; 3481.1Sfvdl int error; 3491.1Sfvdl 3501.1Sfvdl sg = stackgap_init(); 3511.1Sfvdl nsa = stackgap_alloc(&sg, sizeof *nsa); 3521.1Sfvdl osa = stackgap_alloc(&sg, sizeof *osa); 3531.1Sfvdl 3541.1Sfvdl tmpsa.sa_handler = SCARG(uap, handler); 3551.1Sfvdl tmpsa.sa_mask = (sigset_t) 0; 3561.1Sfvdl tmpsa.sa_flags = 0; 3571.1Sfvdl if ((error = copyout(&tmpsa, nsa, sizeof tmpsa))) 3581.1Sfvdl return error; 3591.1Sfvdl 3601.1Sfvdl SCARG(&sa_args, signum) = linux_to_bsd_sig(SCARG(uap, sig)); 3611.1Sfvdl SCARG(&sa_args, osa) = osa; 3621.1Sfvdl SCARG(&sa_args, nsa) = nsa; 3631.1Sfvdl if ((error = sigaction(p, &sa_args, retval))) 3641.1Sfvdl return error; 3651.1Sfvdl 3661.1Sfvdl if ((error = copyin(osa, &tmpsa, sizeof *osa))) 3671.1Sfvdl return error; 3681.1Sfvdl retval[0] = (register_t) tmpsa.sa_handler; 3691.1Sfvdl 3701.1Sfvdl return 0; 3711.1Sfvdl} 3721.1Sfvdl 3731.1Sfvdl/* 3741.1Sfvdl * This is just a copy of the svr4 compat one. I feel so creative now. 3751.1Sfvdl */ 3761.1Sfvdlint 3771.1Sfvdllinux_sigprocmask(p, uap, retval) 3781.1Sfvdl register struct proc *p; 3791.1Sfvdl register struct linux_sigprocmask_args /* { 3801.1Sfvdl syscallarg(int) how; 3811.1Sfvdl syscallarg(linux_sigset_t *) set; 3821.1Sfvdl syscallarg(linux_sigset_t * oset; 3831.1Sfvdl } */ *uap; 3841.1Sfvdl register_t *retval; 3851.1Sfvdl{ 3861.1Sfvdl linux_sigset_t ss; 3871.1Sfvdl sigset_t bs; 3881.1Sfvdl int error = 0; 3891.1Sfvdl 3901.1Sfvdl *retval = 0; 3911.1Sfvdl 3921.1Sfvdl if (SCARG(uap, oset) != NULL) { 3931.1Sfvdl /* Fix the return value first if needed */ 3941.1Sfvdl bsd_to_linux_sigset(&p->p_sigmask, &ss); 3951.1Sfvdl if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0) 3961.1Sfvdl return error; 3971.1Sfvdl } 3981.1Sfvdl 3991.1Sfvdl if (SCARG(uap, set) == NULL) 4001.1Sfvdl /* Just examine */ 4011.1Sfvdl return 0; 4021.1Sfvdl 4031.1Sfvdl if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0) 4041.1Sfvdl return error; 4051.1Sfvdl 4061.1Sfvdl linux_to_bsd_sigset(&ss, &bs); 4071.1Sfvdl 4081.1Sfvdl (void) splhigh(); 4091.1Sfvdl 4101.1Sfvdl switch (SCARG(uap, how)) { 4111.1Sfvdl case LINUX_SIG_BLOCK: 4121.1Sfvdl p->p_sigmask |= bs & ~sigcantmask; 4131.1Sfvdl break; 4141.1Sfvdl 4151.1Sfvdl case LINUX_SIG_UNBLOCK: 4161.1Sfvdl p->p_sigmask &= ~bs; 4171.1Sfvdl break; 4181.1Sfvdl 4191.1Sfvdl case LINUX_SIG_SETMASK: 4201.1Sfvdl p->p_sigmask = bs & ~sigcantmask; 4211.1Sfvdl break; 4221.1Sfvdl 4231.1Sfvdl default: 4241.1Sfvdl error = EINVAL; 4251.1Sfvdl break; 4261.1Sfvdl } 4271.1Sfvdl 4281.1Sfvdl (void) spl0(); 4291.1Sfvdl 4301.1Sfvdl return error; 4311.1Sfvdl} 4321.1Sfvdl 4331.1Sfvdl/* 4341.1Sfvdl * The functions below really make no distinction between an int 4351.1Sfvdl * and [linux_]sigset_t. This is ok for now, but it might break 4361.1Sfvdl * sometime. Then again, sigset_t is trusted to be an int everywhere 4371.1Sfvdl * else in the kernel too. 4381.1Sfvdl */ 4391.1Sfvdl/* ARGSUSED */ 4401.1Sfvdlint 4411.1Sfvdllinux_siggetmask(p, uap, retval) 4421.1Sfvdl struct proc *p; 4431.1Sfvdl void *uap; 4441.1Sfvdl register_t *retval; 4451.1Sfvdl{ 4461.1Sfvdl bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *) retval); 4471.1Sfvdl return 0; 4481.1Sfvdl} 4491.1Sfvdl 4501.1Sfvdl/* 4511.1Sfvdl * The following three functions fiddle with a process' signal mask. 4521.1Sfvdl * Convert the signal masks because of the different signal 4531.1Sfvdl * values for Linux. The need for this is the reason why 4541.1Sfvdl * they are here, and have not been mapped directly. 4551.1Sfvdl */ 4561.1Sfvdlint 4571.1Sfvdllinux_sigsetmask(p, uap, retval) 4581.1Sfvdl struct proc *p; 4591.1Sfvdl struct linux_sigsetmask_args /* { 4601.1Sfvdl syscallarg(linux_sigset_t) mask; 4611.1Sfvdl } */ *uap; 4621.1Sfvdl register_t *retval; 4631.1Sfvdl{ 4641.1Sfvdl linux_sigset_t mask; 4651.1Sfvdl sigset_t bsdsig; 4661.1Sfvdl 4671.1Sfvdl bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *) retval); 4681.1Sfvdl 4691.1Sfvdl mask = SCARG(uap, mask); 4701.1Sfvdl bsd_to_linux_sigset(&mask, &bsdsig); 4711.1Sfvdl 4721.1Sfvdl splhigh(); 4731.1Sfvdl p->p_sigmask = bsdsig & ~sigcantmask; 4741.1Sfvdl spl0(); 4751.1Sfvdl 4761.1Sfvdl return 0; 4771.1Sfvdl} 4781.1Sfvdl 4791.1Sfvdlint 4801.1Sfvdllinux_sigpending(p, uap, retval) 4811.1Sfvdl struct proc *p; 4821.1Sfvdl struct linux_sigpending_args /* { 4831.1Sfvdl syscallarg(linux_sigset_t *) mask; 4841.1Sfvdl } */ *uap; 4851.1Sfvdl register_t *retval; 4861.1Sfvdl{ 4871.1Sfvdl sigset_t bsdsig; 4881.1Sfvdl linux_sigset_t linuxsig; 4891.1Sfvdl 4901.1Sfvdl bsdsig = p->p_siglist & p->p_sigmask; 4911.1Sfvdl 4921.1Sfvdl bsd_to_linux_sigset(&bsdsig, &linuxsig); 4931.1Sfvdl return copyout(&linuxsig, SCARG(uap, mask), sizeof linuxsig); 4941.1Sfvdl} 4951.1Sfvdl 4961.1Sfvdlint 4971.1Sfvdllinux_sigsuspend(p, uap, retval) 4981.1Sfvdl struct proc *p; 4991.1Sfvdl struct linux_sigsuspend_args /* { 5001.3Sfvdl syscallarg(caddr_t) restart; 5011.3Sfvdl syscallarg(int) oldmask; 5021.1Sfvdl syscallarg(int) mask; 5031.1Sfvdl } */ *uap; 5041.1Sfvdl register_t *retval; 5051.1Sfvdl{ 5061.1Sfvdl struct sigsuspend_args ssa; 5071.1Sfvdl 5081.1Sfvdl linux_to_bsd_sigset(&SCARG(uap, mask), &SCARG(&ssa, mask)); 5091.1Sfvdl return sigsuspend(p, &ssa, retval); 5101.3Sfvdl} 5111.3Sfvdl 5121.3Sfvdl/* 5131.3Sfvdl * The deprecated pause(2), which is really just an instance 5141.3Sfvdl * of sigsuspend(2). 5151.3Sfvdl */ 5161.3Sfvdlint 5171.3Sfvdllinux_pause(p, uap, retval) 5181.3Sfvdl struct proc *p; 5191.3Sfvdl void *uap; 5201.3Sfvdl register_t *retval; 5211.3Sfvdl{ 5221.3Sfvdl struct sigsuspend_args bsa; 5231.3Sfvdl 5241.3Sfvdl SCARG(&bsa, mask) = p->p_sigmask; 5251.3Sfvdl return sigsuspend(p, &bsa, retval); 5261.1Sfvdl} 5271.1Sfvdl 5281.1Sfvdl/* 5291.1Sfvdl * Once more: only a signal conversion is needed. 5301.1Sfvdl */ 5311.1Sfvdlint 5321.1Sfvdllinux_kill(p, uap, retval) 5331.1Sfvdl struct proc *p; 5341.1Sfvdl struct linux_kill_args /* { 5351.1Sfvdl syscallarg(int) pid; 5361.1Sfvdl syscallarg(int) signum; 5371.1Sfvdl } */ *uap; 5381.1Sfvdl register_t *retval; 5391.1Sfvdl{ 5401.1Sfvdl SCARG(uap, signum) = linux_to_bsd_sig(SCARG(uap, signum)); 5411.1Sfvdl return kill(p, (struct kill_args *) uap, retval); 5421.1Sfvdl} 543