linux_sigarray.c revision 1.6
11.6Smycroft/*	$NetBSD: linux_sigarray.c,v 1.6 1995/08/13 22:55:28 mycroft 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.6Smycroft#define	sigemptyset(s)		bzero((s), sizeof(*(s)))
561.6Smycroft#define	sigismember(s, n)	(*(s) & sigmask(n))
571.6Smycroft#define	sigaddset(s, n)		(*(s) |= sigmask(n))
581.6Smycroft
591.6Smycroft#define	linux_sigmask(n)	(1 << ((n) - 1))
601.6Smycroft#define	linux_sigemptyset(s)	bzero((s), sizeof(*(s)))
611.6Smycroft#define	linux_sigismember(s, n)	(*(s) & linux_sigmask(n))
621.6Smycroft#define	linux_sigaddset(s, n)	(*(s) |= linux_sigmask(n))
631.6Smycroft
641.6Smycroftint bsd_to_linux_sig[] = {
651.6Smycroft	0,
661.6Smycroft	LINUX_SIGHUP,
671.6Smycroft	LINUX_SIGINT,
681.6Smycroft	LINUX_SIGQUIT,
691.6Smycroft	LINUX_SIGILL,
701.6Smycroft	LINUX_SIGTRAP,
711.6Smycroft	LINUX_SIGABRT,
721.6Smycroft	0,
731.6Smycroft	LINUX_SIGFPE,
741.6Smycroft	LINUX_SIGKILL,
751.6Smycroft	LINUX_SIGBUS,
761.6Smycroft	LINUX_SIGSEGV,
771.6Smycroft	0,
781.6Smycroft	LINUX_SIGPIPE,
791.6Smycroft	LINUX_SIGALRM,
801.6Smycroft	LINUX_SIGTERM,
811.6Smycroft	LINUX_SIGURG,
821.6Smycroft	LINUX_SIGSTOP,
831.6Smycroft	LINUX_SIGTSTP,
841.6Smycroft	LINUX_SIGCONT,
851.6Smycroft	LINUX_SIGCHLD,
861.6Smycroft	LINUX_SIGTTIN,
871.6Smycroft	LINUX_SIGTTOU,
881.6Smycroft	LINUX_SIGIO,
891.6Smycroft	LINUX_SIGXCPU,
901.6Smycroft	LINUX_SIGXFSZ,
911.6Smycroft	LINUX_SIGVTALRM,
921.6Smycroft	LINUX_SIGPROF,
931.6Smycroft	LINUX_SIGWINCH,
941.6Smycroft	0,
951.6Smycroft	LINUX_SIGUSR1,
961.6Smycroft	LINUX_SIGUSR2,
971.6Smycroft};
981.6Smycroft
991.6Smycroftint linux_to_bsd_sig[] = {
1001.6Smycroft	0,
1011.6Smycroft	SIGHUP,
1021.6Smycroft	SIGINT,
1031.6Smycroft	SIGQUIT,
1041.6Smycroft	SIGILL,
1051.6Smycroft	SIGTRAP,
1061.6Smycroft	SIGABRT,
1071.6Smycroft	SIGBUS,
1081.6Smycroft	SIGFPE,
1091.6Smycroft	SIGKILL,
1101.6Smycroft	SIGUSR1,
1111.6Smycroft	SIGSEGV,
1121.6Smycroft	SIGUSR2,
1131.6Smycroft	SIGPIPE,
1141.6Smycroft	SIGALRM,
1151.6Smycroft	SIGTERM,
1161.6Smycroft	0,
1171.6Smycroft	SIGCHLD,
1181.6Smycroft	SIGCONT,
1191.6Smycroft	SIGSTOP,
1201.6Smycroft	SIGTSTP,
1211.6Smycroft	SIGTTIN,
1221.6Smycroft	SIGTTOU,
1231.6Smycroft	SIGURG,
1241.6Smycroft	SIGXCPU,
1251.6Smycroft	SIGXFSZ,
1261.6Smycroft	SIGVTALRM,
1271.6Smycroft	SIGPROF,
1281.6Smycroft	SIGWINCH,
1291.6Smycroft	SIGIO,
1301.6Smycroft	0,
1311.6Smycroft	0,
1321.6Smycroft};
1331.1Sfvdl
1341.1Sfvdl/*
1351.1Sfvdl * Ok, we know that Linux and BSD signals both are just an unsigned int.
1361.1Sfvdl * Don't bother to use the sigismember() stuff for now.
1371.1Sfvdl */
1381.6Smycroftvoid
1391.1Sfvdllinux_to_bsd_sigset(lss, bss)
1401.1Sfvdl	const linux_sigset_t *lss;
1411.1Sfvdl	sigset_t *bss;
1421.1Sfvdl{
1431.1Sfvdl	int i, newsig;
1441.1Sfvdl
1451.6Smycroft	sigemptyset(bss);
1461.6Smycroft	for (i = 1; i < LINUX_NSIG; i++) {
1471.6Smycroft		if (linux_sigismember(lss, i)) {
1481.6Smycroft			newsig = linux_to_bsd_sig[i];
1491.1Sfvdl			if (newsig)
1501.6Smycroft				sigaddset(bss, newsig);
1511.1Sfvdl		}
1521.1Sfvdl	}
1531.1Sfvdl}
1541.1Sfvdl
1551.1Sfvdlvoid
1561.1Sfvdlbsd_to_linux_sigset(bss, lss)
1571.1Sfvdl	const sigset_t *bss;
1581.1Sfvdl	linux_sigset_t *lss;
1591.1Sfvdl{
1601.1Sfvdl	int i, newsig;
1611.1Sfvdl
1621.6Smycroft	linux_sigemptyset(lss);
1631.6Smycroft	for (i = 1; i < NSIG; i++) {
1641.6Smycroft		if (sigismember(bss, i)) {
1651.6Smycroft			newsig = bsd_to_linux_sig[i];
1661.1Sfvdl			if (newsig)
1671.6Smycroft				linux_sigaddset(lss, newsig);
1681.1Sfvdl		}
1691.1Sfvdl	}
1701.1Sfvdl}
1711.1Sfvdl
1721.1Sfvdl/*
1731.1Sfvdl * Convert between Linux and BSD sigaction structures. Linux has
1741.6Smycroft * one extra field (sa_restorer) which we don't support.
1751.1Sfvdl */
1761.1Sfvdlvoid
1771.1Sfvdllinux_to_bsd_sigaction(lsa, bsa)
1781.1Sfvdl	struct linux_sigaction *lsa;
1791.1Sfvdl	struct sigaction *bsa;
1801.1Sfvdl{
1811.6Smycroft
1821.1Sfvdl	bsa->sa_handler = lsa->sa_handler;
1831.1Sfvdl	linux_to_bsd_sigset(&bsa->sa_mask, &lsa->sa_mask);
1841.1Sfvdl	bsa->sa_flags = 0;
1851.6Smycroft	if ((lsa->sa_flags & LINUX_SA_ONSTACK) != 0)
1861.6Smycroft		bsa->sa_flags |= SA_ONSTACK;
1871.6Smycroft	if ((lsa->sa_flags & LINUX_SA_RESTART) != 0)
1881.6Smycroft		bsa->sa_flags |= SA_RESTART;
1891.6Smycroft	if ((lsa->sa_flags & LINUX_SA_ONESHOT) != 0)
1901.6Smycroft		bsa->sa_flags |= SA_RESETHAND;
1911.6Smycroft	if ((lsa->sa_flags & LINUX_SA_NOCLDSTOP) != 0)
1921.6Smycroft		bsa->sa_flags |= SA_NOCLDSTOP;
1931.6Smycroft	if ((lsa->sa_flags & LINUX_SA_NOMASK) != 0)
1941.6Smycroft		bsa->sa_flags |= SA_NODEFER;
1951.1Sfvdl}
1961.1Sfvdl
1971.1Sfvdlvoid
1981.1Sfvdlbsd_to_linux_sigaction(bsa, lsa)
1991.1Sfvdl	struct sigaction *bsa;
2001.1Sfvdl	struct linux_sigaction *lsa;
2011.1Sfvdl{
2021.6Smycroft
2031.1Sfvdl	lsa->sa_handler = bsa->sa_handler;
2041.1Sfvdl	bsd_to_linux_sigset(&lsa->sa_mask, &bsa->sa_mask);
2051.1Sfvdl	lsa->sa_flags = 0;
2061.6Smycroft	if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
2071.6Smycroft		lsa->sa_flags |= LINUX_SA_NOCLDSTOP;
2081.6Smycroft	if ((bsa->sa_flags & SA_ONSTACK) != 0)
2091.6Smycroft		lsa->sa_flags |= LINUX_SA_ONSTACK;
2101.6Smycroft	if ((bsa->sa_flags & SA_RESTART) != 0)
2111.6Smycroft		lsa->sa_flags |= LINUX_SA_RESTART;
2121.6Smycroft	if ((bsa->sa_flags & SA_NODEFER) != 0)
2131.6Smycroft		lsa->sa_flags |= LINUX_SA_NOMASK;
2141.6Smycroft	if ((bsa->sa_flags & SA_RESETHAND) != 0)
2151.6Smycroft		lsa->sa_flags |= LINUX_SA_ONESHOT;
2161.1Sfvdl	lsa->sa_restorer = NULL;
2171.1Sfvdl}
2181.1Sfvdl
2191.1Sfvdl
2201.1Sfvdl/*
2211.1Sfvdl * The Linux sigaction() system call. Do the usual conversions,
2221.1Sfvdl * and just call sigaction(). Some flags and values are silently
2231.1Sfvdl * ignored (see above).
2241.1Sfvdl */
2251.1Sfvdlint
2261.1Sfvdllinux_sigaction(p, uap, retval)
2271.1Sfvdl	register struct proc *p;
2281.1Sfvdl	struct linux_sigaction_args /* {
2291.1Sfvdl		syscallarg(int) signum;
2301.1Sfvdl		syscallarg(struct linux_sigaction *) nsa;
2311.1Sfvdl		syscallarg(struct linux_sigaction *) osa;
2321.1Sfvdl	} */ *uap;
2331.1Sfvdl	register_t *retval;
2341.1Sfvdl{
2351.1Sfvdl	struct linux_sigaction *nlsa, *olsa, tmplsa;
2361.6Smycroft	struct sigaction *nbsa, *obsa, tmpbsa;
2371.1Sfvdl	struct sigaction_args sa;
2381.1Sfvdl	caddr_t sg;
2391.1Sfvdl	int error;
2401.1Sfvdl
2411.5Schristos	sg = stackgap_init(p->p_emul);
2421.6Smycroft	nlsa = SCARG(uap, nsa);
2431.1Sfvdl	olsa = SCARG(uap, osa);
2441.1Sfvdl
2451.1Sfvdl	if (olsa != NULL)
2461.6Smycroft		obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
2471.6Smycroft	else
2481.6Smycroft		obsa = NULL;
2491.1Sfvdl
2501.1Sfvdl	if (nlsa != NULL) {
2511.6Smycroft		nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
2521.6Smycroft		if ((error = copyin(nlsa, &tmplsa, sizeof(tmplsa))) != 0)
2531.1Sfvdl			return error;
2541.6Smycroft		linux_to_bsd_sigaction(&tmplsa, &tmpbsa);
2551.6Smycroft		if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
2561.1Sfvdl			return error;
2571.6Smycroft	} else
2581.6Smycroft		nbsa = NULL;
2591.1Sfvdl
2601.6Smycroft	SCARG(&sa, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
2611.6Smycroft	SCARG(&sa, nsa) = nbsa;
2621.6Smycroft	SCARG(&sa, osa) = obsa;
2631.1Sfvdl
2641.6Smycroft	if ((error = sigaction(p, &sa, retval)) != 0)
2651.1Sfvdl		return error;
2661.1Sfvdl
2671.1Sfvdl	if (olsa != NULL) {
2681.6Smycroft		if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
2691.1Sfvdl			return error;
2701.6Smycroft		bsd_to_linux_sigaction(&tmpbsa, &tmplsa);
2711.6Smycroft		if ((error = copyout(&tmplsa, olsa, sizeof(tmplsa))) != 0)
2721.1Sfvdl			return error;
2731.1Sfvdl	}
2741.6Smycroft
2751.1Sfvdl	return 0;
2761.1Sfvdl}
2771.1Sfvdl
2781.1Sfvdl/*
2791.1Sfvdl * The Linux signal() system call. I think that the signal() in the C
2801.1Sfvdl * library actually calls sigaction, so I doubt this one is ever used.
2811.1Sfvdl * But hey, it can't hurt having it here. The same restrictions as for
2821.1Sfvdl * sigaction() apply.
2831.1Sfvdl */
2841.1Sfvdlint
2851.1Sfvdllinux_signal(p, uap, retval)
2861.1Sfvdl	register struct proc *p;
2871.1Sfvdl	struct linux_signal_args /* {
2881.1Sfvdl		syscallarg(int) sig;
2891.1Sfvdl		syscallarg(linux_handler_t) handler;
2901.1Sfvdl	} */ *uap;
2911.1Sfvdl	register_t *retval;
2921.1Sfvdl{
2931.1Sfvdl	caddr_t sg;
2941.1Sfvdl	struct sigaction_args sa_args;
2951.1Sfvdl	struct sigaction *osa, *nsa, tmpsa;
2961.1Sfvdl	int error;
2971.1Sfvdl
2981.5Schristos	sg = stackgap_init(p->p_emul);
2991.1Sfvdl	nsa = stackgap_alloc(&sg, sizeof *nsa);
3001.1Sfvdl	osa = stackgap_alloc(&sg, sizeof *osa);
3011.1Sfvdl
3021.1Sfvdl	tmpsa.sa_handler = SCARG(uap, handler);
3031.1Sfvdl	tmpsa.sa_mask = (sigset_t) 0;
3041.6Smycroft	tmpsa.sa_flags = SA_RESETHAND | SA_NODEFER;
3051.1Sfvdl	if ((error = copyout(&tmpsa, nsa, sizeof tmpsa)))
3061.1Sfvdl		return error;
3071.1Sfvdl
3081.6Smycroft	SCARG(&sa_args, signum) = linux_to_bsd_sig[SCARG(uap, sig)];
3091.1Sfvdl	SCARG(&sa_args, osa) = osa;
3101.1Sfvdl	SCARG(&sa_args, nsa) = nsa;
3111.1Sfvdl	if ((error = sigaction(p, &sa_args, retval)))
3121.1Sfvdl		return error;
3131.1Sfvdl
3141.1Sfvdl	if ((error = copyin(osa, &tmpsa, sizeof *osa)))
3151.1Sfvdl		return error;
3161.1Sfvdl	retval[0] = (register_t) tmpsa.sa_handler;
3171.1Sfvdl
3181.1Sfvdl	return 0;
3191.1Sfvdl}
3201.1Sfvdl
3211.1Sfvdl/*
3221.1Sfvdl * This is just a copy of the svr4 compat one. I feel so creative now.
3231.1Sfvdl */
3241.1Sfvdlint
3251.1Sfvdllinux_sigprocmask(p, uap, retval)
3261.1Sfvdl	register struct proc *p;
3271.6Smycroft	struct linux_sigprocmask_args /* {
3281.1Sfvdl		syscallarg(int) how;
3291.1Sfvdl		syscallarg(linux_sigset_t *) set;
3301.6Smycroft		syscallarg(linux_sigset_t *) oset;
3311.1Sfvdl	} */ *uap;
3321.1Sfvdl	register_t *retval;
3331.1Sfvdl{
3341.1Sfvdl	linux_sigset_t ss;
3351.1Sfvdl	sigset_t bs;
3361.1Sfvdl	int error = 0;
3371.1Sfvdl
3381.1Sfvdl	*retval = 0;
3391.1Sfvdl
3401.1Sfvdl	if (SCARG(uap, oset) != NULL) {
3411.1Sfvdl		/* Fix the return value first if needed */
3421.1Sfvdl		bsd_to_linux_sigset(&p->p_sigmask, &ss);
3431.1Sfvdl		if ((error = copyout(&ss, SCARG(uap, oset), sizeof(ss))) != 0)
3441.1Sfvdl			return error;
3451.1Sfvdl	}
3461.1Sfvdl
3471.1Sfvdl	if (SCARG(uap, set) == NULL)
3481.1Sfvdl		/* Just examine */
3491.1Sfvdl		return 0;
3501.1Sfvdl
3511.1Sfvdl	if ((error = copyin(SCARG(uap, set), &ss, sizeof(ss))) != 0)
3521.1Sfvdl		return error;
3531.1Sfvdl
3541.1Sfvdl	linux_to_bsd_sigset(&ss, &bs);
3551.1Sfvdl
3561.1Sfvdl	(void) splhigh();
3571.1Sfvdl
3581.1Sfvdl	switch (SCARG(uap, how)) {
3591.1Sfvdl	case LINUX_SIG_BLOCK:
3601.1Sfvdl		p->p_sigmask |= bs & ~sigcantmask;
3611.1Sfvdl		break;
3621.1Sfvdl
3631.1Sfvdl	case LINUX_SIG_UNBLOCK:
3641.1Sfvdl		p->p_sigmask &= ~bs;
3651.1Sfvdl		break;
3661.1Sfvdl
3671.1Sfvdl	case LINUX_SIG_SETMASK:
3681.1Sfvdl		p->p_sigmask = bs & ~sigcantmask;
3691.1Sfvdl		break;
3701.1Sfvdl
3711.1Sfvdl	default:
3721.1Sfvdl		error = EINVAL;
3731.1Sfvdl		break;
3741.1Sfvdl	}
3751.1Sfvdl
3761.1Sfvdl	(void) spl0();
3771.1Sfvdl
3781.1Sfvdl	return error;
3791.1Sfvdl}
3801.1Sfvdl
3811.1Sfvdl/*
3821.1Sfvdl * The functions below really make no distinction between an int
3831.1Sfvdl * and [linux_]sigset_t. This is ok for now, but it might break
3841.1Sfvdl * sometime. Then again, sigset_t is trusted to be an int everywhere
3851.1Sfvdl * else in the kernel too.
3861.1Sfvdl */
3871.1Sfvdl/* ARGSUSED */
3881.1Sfvdlint
3891.1Sfvdllinux_siggetmask(p, uap, retval)
3901.6Smycroft	register struct proc *p;
3911.1Sfvdl	void *uap;
3921.1Sfvdl	register_t *retval;
3931.1Sfvdl{
3941.6Smycroft
3951.6Smycroft	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
3961.1Sfvdl	return 0;
3971.1Sfvdl}
3981.1Sfvdl
3991.1Sfvdl/*
4001.1Sfvdl * The following three functions fiddle with a process' signal mask.
4011.1Sfvdl * Convert the signal masks because of the different signal
4021.1Sfvdl * values for Linux. The need for this is the reason why
4031.1Sfvdl * they are here, and have not been mapped directly.
4041.1Sfvdl */
4051.1Sfvdlint
4061.1Sfvdllinux_sigsetmask(p, uap, retval)
4071.6Smycroft	register struct proc *p;
4081.1Sfvdl	struct linux_sigsetmask_args /* {
4091.1Sfvdl		syscallarg(linux_sigset_t) mask;
4101.1Sfvdl	} */ *uap;
4111.1Sfvdl	register_t *retval;
4121.1Sfvdl{
4131.1Sfvdl	linux_sigset_t mask;
4141.1Sfvdl	sigset_t bsdsig;
4151.1Sfvdl
4161.6Smycroft	bsd_to_linux_sigset(&p->p_sigmask, (linux_sigset_t *)retval);
4171.1Sfvdl
4181.1Sfvdl	mask = SCARG(uap, mask);
4191.1Sfvdl	bsd_to_linux_sigset(&mask, &bsdsig);
4201.1Sfvdl
4211.1Sfvdl	splhigh();
4221.1Sfvdl	p->p_sigmask = bsdsig & ~sigcantmask;
4231.1Sfvdl	spl0();
4241.1Sfvdl
4251.1Sfvdl	return 0;
4261.1Sfvdl}
4271.1Sfvdl
4281.1Sfvdlint
4291.1Sfvdllinux_sigpending(p, uap, retval)
4301.6Smycroft	register struct proc *p;
4311.1Sfvdl	struct linux_sigpending_args /* {
4321.1Sfvdl		syscallarg(linux_sigset_t *) mask;
4331.1Sfvdl	} */ *uap;
4341.1Sfvdl	register_t *retval;
4351.1Sfvdl{
4361.6Smycroft	sigset_t bs;
4371.6Smycroft	linux_sigset_t ls;
4381.1Sfvdl
4391.6Smycroft	bs = p->p_siglist & p->p_sigmask;
4401.6Smycroft	bsd_to_linux_sigset(&bs, &ls);
4411.1Sfvdl
4421.6Smycroft	return copyout(&ls, SCARG(uap, mask), sizeof(ls));
4431.1Sfvdl}
4441.1Sfvdl
4451.1Sfvdlint
4461.1Sfvdllinux_sigsuspend(p, uap, retval)
4471.6Smycroft	register struct proc *p;
4481.1Sfvdl	struct linux_sigsuspend_args /* {
4491.3Sfvdl		syscallarg(caddr_t) restart;
4501.3Sfvdl		syscallarg(int) oldmask;
4511.1Sfvdl		syscallarg(int) mask;
4521.1Sfvdl	} */ *uap;
4531.1Sfvdl	register_t *retval;
4541.1Sfvdl{
4551.6Smycroft	struct sigsuspend_args sa;
4561.1Sfvdl
4571.6Smycroft	linux_to_bsd_sigset(&SCARG(uap, mask), &SCARG(&sa, mask));
4581.6Smycroft	return sigsuspend(p, &sa, retval);
4591.3Sfvdl}
4601.3Sfvdl
4611.3Sfvdl/*
4621.3Sfvdl * The deprecated pause(2), which is really just an instance
4631.3Sfvdl * of sigsuspend(2).
4641.3Sfvdl */
4651.3Sfvdlint
4661.3Sfvdllinux_pause(p, uap, retval)
4671.6Smycroft	register struct proc *p;
4681.3Sfvdl	void *uap;
4691.3Sfvdl	register_t *retval;
4701.3Sfvdl{
4711.3Sfvdl	struct sigsuspend_args bsa;
4721.3Sfvdl
4731.3Sfvdl	SCARG(&bsa, mask) = p->p_sigmask;
4741.3Sfvdl	return sigsuspend(p, &bsa, retval);
4751.1Sfvdl}
4761.1Sfvdl
4771.1Sfvdl/*
4781.1Sfvdl * Once more: only a signal conversion is needed.
4791.1Sfvdl */
4801.1Sfvdlint
4811.1Sfvdllinux_kill(p, uap, retval)
4821.6Smycroft	register struct proc *p;
4831.1Sfvdl	struct linux_kill_args /* {
4841.1Sfvdl		syscallarg(int) pid;
4851.1Sfvdl		syscallarg(int) signum;
4861.1Sfvdl	} */ *uap;
4871.1Sfvdl	register_t *retval;
4881.1Sfvdl{
4891.6Smycroft	struct kill_args ka;
4901.6Smycroft
4911.6Smycroft	SCARG(&ka, pid) = SCARG(uap, pid);
4921.6Smycroft	SCARG(&ka, signum) = linux_to_bsd_sig[SCARG(uap, signum)];
4931.6Smycroft	return kill(p, &ka, retval);
4941.1Sfvdl}
495