linux_sigarray.c revision 1.5
11.5Schristos/*	$NetBSD: linux_sigarray.c,v 1.5 1995/06/24 20:20:30 christos 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.5Schristos	sg = stackgap_init(p->p_emul);
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.5Schristos	sg = stackgap_init(p->p_emul);
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