xref: /freebsd/sys/compat/linux/linux_signal.c (revision 1997c537be039b083d9156b1c8685ac9ff25e911)
1c21dee17SSøren Schmidt /*-
2c21dee17SSøren Schmidt  * Copyright (c) 1994-1995 S�ren Schmidt
3c21dee17SSøren Schmidt  * All rights reserved.
4c21dee17SSøren Schmidt  *
5c21dee17SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
6c21dee17SSøren Schmidt  * modification, are permitted provided that the following conditions
7c21dee17SSøren Schmidt  * are met:
8c21dee17SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
9c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer
10c21dee17SSøren Schmidt  *    in this position and unchanged.
11c21dee17SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
12c21dee17SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
13c21dee17SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
14c21dee17SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
1521dc7d4fSJens Schweikhardt  *    derived from this software without specific prior written permission
16c21dee17SSøren Schmidt  *
17c21dee17SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18c21dee17SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19c21dee17SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20c21dee17SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21c21dee17SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22c21dee17SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23c21dee17SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24c21dee17SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25c21dee17SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26c21dee17SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27c21dee17SSøren Schmidt  */
28c21dee17SSøren Schmidt 
2916dbc7f2SDavid E. O'Brien #include <sys/cdefs.h>
3016dbc7f2SDavid E. O'Brien __FBSDID("$FreeBSD$");
3116dbc7f2SDavid E. O'Brien 
32c21dee17SSøren Schmidt #include <sys/param.h>
33c21dee17SSøren Schmidt #include <sys/systm.h>
34fb919e4dSMark Murray #include <sys/lock.h>
35fb919e4dSMark Murray #include <sys/mutex.h>
36c21dee17SSøren Schmidt #include <sys/proc.h>
37c21dee17SSøren Schmidt #include <sys/signalvar.h>
38206a5d3aSIan Dowse #include <sys/syscallsubr.h>
39fb919e4dSMark Murray #include <sys/sysproto.h>
40c21dee17SSøren Schmidt 
414af27623STim J. Robbins #include "opt_compat.h"
424af27623STim J. Robbins 
431997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32
444af27623STim J. Robbins #include <machine/../linux32/linux.h>
454af27623STim J. Robbins #include <machine/../linux32/linux32_proto.h>
461997c537SDavid E. O'Brien #else
471997c537SDavid E. O'Brien #include <machine/../linux/linux.h>
481997c537SDavid E. O'Brien #include <machine/../linux/linux_proto.h>
494af27623STim J. Robbins #endif
50ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_signal.h>
51ba9ef45bSMarcel Moolenaar #include <compat/linux/linux_util.h>
52c21dee17SSøren Schmidt 
53ba9ef45bSMarcel Moolenaar void
545002a60fSMarcel Moolenaar linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss)
55956d3333SMarcel Moolenaar {
56d66a5066SPeter Wemm 	int b, l;
57c21dee17SSøren Schmidt 
58956d3333SMarcel Moolenaar 	SIGEMPTYSET(*bss);
59956d3333SMarcel Moolenaar 	bss->__bits[0] = lss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
60956d3333SMarcel Moolenaar 	bss->__bits[1] = lss->__bits[1];
61956d3333SMarcel Moolenaar 	for (l = 1; l <= LINUX_SIGTBLSZ; l++) {
62956d3333SMarcel Moolenaar 		if (LINUX_SIGISMEMBER(*lss, l)) {
635231fb20SDavid E. O'Brien #ifdef __alpha__
645231fb20SDavid E. O'Brien 			b = _SIG_IDX(l);
655231fb20SDavid E. O'Brien #else
66956d3333SMarcel Moolenaar 			b = linux_to_bsd_signal[_SIG_IDX(l)];
675231fb20SDavid E. O'Brien #endif
68956d3333SMarcel Moolenaar 			if (b)
69956d3333SMarcel Moolenaar 				SIGADDSET(*bss, b);
70d66a5066SPeter Wemm 		}
71d66a5066SPeter Wemm 	}
72c21dee17SSøren Schmidt }
73c21dee17SSøren Schmidt 
7479363394SAndrew Gallatin void
755002a60fSMarcel Moolenaar bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
76956d3333SMarcel Moolenaar {
77d66a5066SPeter Wemm 	int b, l;
78c21dee17SSøren Schmidt 
79956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(*lss);
80956d3333SMarcel Moolenaar 	lss->__bits[0] = bss->__bits[0] & ~((1U << LINUX_SIGTBLSZ) - 1);
81956d3333SMarcel Moolenaar 	lss->__bits[1] = bss->__bits[1];
82956d3333SMarcel Moolenaar 	for (b = 1; b <= LINUX_SIGTBLSZ; b++) {
83956d3333SMarcel Moolenaar 		if (SIGISMEMBER(*bss, b)) {
845231fb20SDavid E. O'Brien #if __alpha__
855231fb20SDavid E. O'Brien 			l = _SIG_IDX(b);
865231fb20SDavid E. O'Brien #else
87956d3333SMarcel Moolenaar 			l = bsd_to_linux_signal[_SIG_IDX(b)];
885231fb20SDavid E. O'Brien #endif
89956d3333SMarcel Moolenaar 			if (l)
90956d3333SMarcel Moolenaar 				LINUX_SIGADDSET(*lss, l);
91d66a5066SPeter Wemm 		}
92d66a5066SPeter Wemm 	}
93c21dee17SSøren Schmidt }
94c21dee17SSøren Schmidt 
95a1ebcbfbSPeter Wemm static void
965002a60fSMarcel Moolenaar linux_to_bsd_sigaction(l_sigaction_t *lsa, struct sigaction *bsa)
97d66a5066SPeter Wemm {
98956d3333SMarcel Moolenaar 
99956d3333SMarcel Moolenaar 	linux_to_bsd_sigset(&lsa->lsa_mask, &bsa->sa_mask);
1004af27623STim J. Robbins 	bsa->sa_handler = PTRIN(lsa->lsa_handler);
101d66a5066SPeter Wemm 	bsa->sa_flags = 0;
1028f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_NOCLDSTOP)
103d66a5066SPeter Wemm 		bsa->sa_flags |= SA_NOCLDSTOP;
10406ebbe77SMarcel Moolenaar 	if (lsa->lsa_flags & LINUX_SA_NOCLDWAIT)
10506ebbe77SMarcel Moolenaar 		bsa->sa_flags |= SA_NOCLDWAIT;
10606ebbe77SMarcel Moolenaar 	if (lsa->lsa_flags & LINUX_SA_SIGINFO)
10706ebbe77SMarcel Moolenaar 		bsa->sa_flags |= SA_SIGINFO;
1088f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_ONSTACK)
109d66a5066SPeter Wemm 		bsa->sa_flags |= SA_ONSTACK;
1108f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_RESTART)
111d66a5066SPeter Wemm 		bsa->sa_flags |= SA_RESTART;
1128f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_ONESHOT)
113d66a5066SPeter Wemm 		bsa->sa_flags |= SA_RESETHAND;
1148f437f44SMartin Cracauer 	if (lsa->lsa_flags & LINUX_SA_NOMASK)
115d66a5066SPeter Wemm 		bsa->sa_flags |= SA_NODEFER;
116d66a5066SPeter Wemm }
117d66a5066SPeter Wemm 
118a1ebcbfbSPeter Wemm static void
1195002a60fSMarcel Moolenaar bsd_to_linux_sigaction(struct sigaction *bsa, l_sigaction_t *lsa)
120d66a5066SPeter Wemm {
121956d3333SMarcel Moolenaar 
122956d3333SMarcel Moolenaar 	bsd_to_linux_sigset(&bsa->sa_mask, &lsa->lsa_mask);
1231997c537SDavid E. O'Brien #ifdef COMPAT_LINUX32
1244af27623STim J. Robbins 	lsa->lsa_handler = (uintptr_t)bsa->sa_handler;
1254af27623STim J. Robbins #else
1268f437f44SMartin Cracauer 	lsa->lsa_handler = bsa->sa_handler;
1274af27623STim J. Robbins #endif
1284af27623STim J. Robbins 	lsa->lsa_restorer = 0;		/* unsupported */
1298f437f44SMartin Cracauer 	lsa->lsa_flags = 0;
130d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_NOCLDSTOP)
1318f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_NOCLDSTOP;
13206ebbe77SMarcel Moolenaar 	if (bsa->sa_flags & SA_NOCLDWAIT)
13306ebbe77SMarcel Moolenaar 		lsa->lsa_flags |= LINUX_SA_NOCLDWAIT;
13406ebbe77SMarcel Moolenaar 	if (bsa->sa_flags & SA_SIGINFO)
13506ebbe77SMarcel Moolenaar 		lsa->lsa_flags |= LINUX_SA_SIGINFO;
136d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_ONSTACK)
1378f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_ONSTACK;
138d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_RESTART)
1398f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_RESTART;
140d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_RESETHAND)
1418f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_ONESHOT;
142d66a5066SPeter Wemm 	if (bsa->sa_flags & SA_NODEFER)
1438f437f44SMartin Cracauer 		lsa->lsa_flags |= LINUX_SA_NOMASK;
144d66a5066SPeter Wemm }
145c21dee17SSøren Schmidt 
146ba9ef45bSMarcel Moolenaar int
147b40ce416SJulian Elischer linux_do_sigaction(struct thread *td, int linux_sig, l_sigaction_t *linux_nsa,
1485002a60fSMarcel Moolenaar 		   l_sigaction_t *linux_osa)
14906ebbe77SMarcel Moolenaar {
150206a5d3aSIan Dowse 	struct sigaction act, oact, *nsa, *osa;
151206a5d3aSIan Dowse 	int error, sig;
15206ebbe77SMarcel Moolenaar 
153956d3333SMarcel Moolenaar 	if (linux_sig <= 0 || linux_sig > LINUX_NSIG)
154956d3333SMarcel Moolenaar 		return (EINVAL);
15506ebbe77SMarcel Moolenaar 
156206a5d3aSIan Dowse 	osa = (linux_osa != NULL) ? &oact : NULL;
157956d3333SMarcel Moolenaar 	if (linux_nsa != NULL) {
158206a5d3aSIan Dowse 		nsa = &act;
159ec99e322SMarcel Moolenaar 		linux_to_bsd_sigaction(linux_nsa, nsa);
160206a5d3aSIan Dowse 	} else
16106ebbe77SMarcel Moolenaar 		nsa = NULL;
16206ebbe77SMarcel Moolenaar 
1635231fb20SDavid E. O'Brien #ifndef __alpha__
164956d3333SMarcel Moolenaar 	if (linux_sig <= LINUX_SIGTBLSZ)
165206a5d3aSIan Dowse 		sig = linux_to_bsd_signal[_SIG_IDX(linux_sig)];
166956d3333SMarcel Moolenaar 	else
1675231fb20SDavid E. O'Brien #endif
168206a5d3aSIan Dowse 		sig = linux_sig;
169956d3333SMarcel Moolenaar 
170206a5d3aSIan Dowse 	error = kern_sigaction(td, sig, nsa, osa, 0);
17106ebbe77SMarcel Moolenaar 	if (error)
172956d3333SMarcel Moolenaar 		return (error);
17306ebbe77SMarcel Moolenaar 
174ec99e322SMarcel Moolenaar 	if (linux_osa != NULL)
175ec99e322SMarcel Moolenaar 		bsd_to_linux_sigaction(osa, linux_osa);
17606ebbe77SMarcel Moolenaar 
177956d3333SMarcel Moolenaar 	return (0);
17806ebbe77SMarcel Moolenaar }
17906ebbe77SMarcel Moolenaar 
1805231fb20SDavid E. O'Brien 
1815231fb20SDavid E. O'Brien #ifndef __alpha__
182c21dee17SSøren Schmidt int
183b40ce416SJulian Elischer linux_signal(struct thread *td, struct linux_signal_args *args)
184d66a5066SPeter Wemm {
1855002a60fSMarcel Moolenaar 	l_sigaction_t nsa, osa;
186d66a5066SPeter Wemm 	int error;
187d66a5066SPeter Wemm 
188d66a5066SPeter Wemm #ifdef DEBUG
18924593369SJonathan Lemon 	if (ldebug(signal))
19024593369SJonathan Lemon 		printf(ARGS(signal, "%d, %p"),
191b61c60d4SDavid E. O'Brien 		    args->sig, (void *)(uintptr_t)args->handler);
192d66a5066SPeter Wemm #endif
193d66a5066SPeter Wemm 
19406ebbe77SMarcel Moolenaar 	nsa.lsa_handler = args->handler;
19506ebbe77SMarcel Moolenaar 	nsa.lsa_flags = LINUX_SA_ONESHOT | LINUX_SA_NOMASK;
196956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(nsa.lsa_mask);
197d66a5066SPeter Wemm 
198b40ce416SJulian Elischer 	error = linux_do_sigaction(td, args->sig, &nsa, &osa);
1994af27623STim J. Robbins 	td->td_retval[0] = (int)(intptr_t)osa.lsa_handler;
200d66a5066SPeter Wemm 
201956d3333SMarcel Moolenaar 	return (error);
202d66a5066SPeter Wemm }
2035231fb20SDavid E. O'Brien #endif	/*!__alpha__*/
204d66a5066SPeter Wemm 
205c21dee17SSøren Schmidt int
206b40ce416SJulian Elischer linux_rt_sigaction(struct thread *td, struct linux_rt_sigaction_args *args)
207c21dee17SSøren Schmidt {
2085002a60fSMarcel Moolenaar 	l_sigaction_t nsa, osa;
20906ebbe77SMarcel Moolenaar 	int error;
210c21dee17SSøren Schmidt 
211c21dee17SSøren Schmidt #ifdef DEBUG
21224593369SJonathan Lemon 	if (ldebug(rt_sigaction))
21324593369SJonathan Lemon 		printf(ARGS(rt_sigaction, "%ld, %p, %p, %ld"),
21424593369SJonathan Lemon 		    (long)args->sig, (void *)args->act,
2155231fb20SDavid E. O'Brien 		    (void *)args->oact, (long)args->sigsetsize);
216c21dee17SSøren Schmidt #endif
217d66a5066SPeter Wemm 
2185002a60fSMarcel Moolenaar 	if (args->sigsetsize != sizeof(l_sigset_t))
219956d3333SMarcel Moolenaar 		return (EINVAL);
22006ebbe77SMarcel Moolenaar 
221956d3333SMarcel Moolenaar 	if (args->act != NULL) {
2225002a60fSMarcel Moolenaar 		error = copyin(args->act, &nsa, sizeof(l_sigaction_t));
22306ebbe77SMarcel Moolenaar 		if (error)
224956d3333SMarcel Moolenaar 			return (error);
22506ebbe77SMarcel Moolenaar 	}
22606ebbe77SMarcel Moolenaar 
227b40ce416SJulian Elischer 	error = linux_do_sigaction(td, args->sig,
22806ebbe77SMarcel Moolenaar 				   args->act ? &nsa : NULL,
22906ebbe77SMarcel Moolenaar 				   args->oact ? &osa : NULL);
23006ebbe77SMarcel Moolenaar 
231956d3333SMarcel Moolenaar 	if (args->oact != NULL && !error) {
2325002a60fSMarcel Moolenaar 		error = copyout(&osa, args->oact, sizeof(l_sigaction_t));
23306ebbe77SMarcel Moolenaar 	}
23406ebbe77SMarcel Moolenaar 
235956d3333SMarcel Moolenaar 	return (error);
23606ebbe77SMarcel Moolenaar }
23706ebbe77SMarcel Moolenaar 
23806ebbe77SMarcel Moolenaar static int
239b40ce416SJulian Elischer linux_do_sigprocmask(struct thread *td, int how, l_sigset_t *new,
2405002a60fSMarcel Moolenaar 		     l_sigset_t *old)
24106ebbe77SMarcel Moolenaar {
242fe8cdcaeSJohn Baldwin 	sigset_t omask, nmask;
243fe8cdcaeSJohn Baldwin 	sigset_t *nmaskp;
244216af822SJohn Baldwin 	int error;
24506ebbe77SMarcel Moolenaar 
246b40ce416SJulian Elischer 	td->td_retval[0] = 0;
247d66a5066SPeter Wemm 
24819dde5cdSJohn Baldwin 	switch (how) {
24919dde5cdSJohn Baldwin 	case LINUX_SIG_BLOCK:
25019dde5cdSJohn Baldwin 		how = SIG_BLOCK;
25119dde5cdSJohn Baldwin 		break;
25219dde5cdSJohn Baldwin 	case LINUX_SIG_UNBLOCK:
25319dde5cdSJohn Baldwin 		how = SIG_UNBLOCK;
25419dde5cdSJohn Baldwin 		break;
25519dde5cdSJohn Baldwin 	case LINUX_SIG_SETMASK:
25619dde5cdSJohn Baldwin 		how = SIG_SETMASK;
25719dde5cdSJohn Baldwin 		break;
25819dde5cdSJohn Baldwin 	default:
25919dde5cdSJohn Baldwin 		return (EINVAL);
26019dde5cdSJohn Baldwin 	}
26106ebbe77SMarcel Moolenaar 	if (new != NULL) {
262fe8cdcaeSJohn Baldwin 		linux_to_bsd_sigset(new, &nmask);
263fe8cdcaeSJohn Baldwin 		nmaskp = &nmask;
264fe8cdcaeSJohn Baldwin 	} else
265fe8cdcaeSJohn Baldwin 		nmaskp = NULL;
26619dde5cdSJohn Baldwin 	error = kern_sigprocmask(td, how, nmaskp, &omask, 0);
2672f7ed219SJohn Baldwin 	if (error == 0 && old != NULL)
268fe8cdcaeSJohn Baldwin 		bsd_to_linux_sigset(&omask, old);
26906ebbe77SMarcel Moolenaar 
270956d3333SMarcel Moolenaar 	return (error);
27106ebbe77SMarcel Moolenaar }
27206ebbe77SMarcel Moolenaar 
2735231fb20SDavid E. O'Brien #ifndef __alpha__
27406ebbe77SMarcel Moolenaar int
275b40ce416SJulian Elischer linux_sigprocmask(struct thread *td, struct linux_sigprocmask_args *args)
27606ebbe77SMarcel Moolenaar {
2775002a60fSMarcel Moolenaar 	l_osigset_t mask;
2785002a60fSMarcel Moolenaar 	l_sigset_t set, oset;
27906ebbe77SMarcel Moolenaar 	int error;
28006ebbe77SMarcel Moolenaar 
28106ebbe77SMarcel Moolenaar #ifdef DEBUG
28224593369SJonathan Lemon 	if (ldebug(sigprocmask))
28324593369SJonathan Lemon 		printf(ARGS(sigprocmask, "%d, *, *"), args->how);
28406ebbe77SMarcel Moolenaar #endif
28506ebbe77SMarcel Moolenaar 
28606ebbe77SMarcel Moolenaar 	if (args->mask != NULL) {
2875002a60fSMarcel Moolenaar 		error = copyin(args->mask, &mask, sizeof(l_osigset_t));
28806ebbe77SMarcel Moolenaar 		if (error)
289956d3333SMarcel Moolenaar 			return (error);
290956d3333SMarcel Moolenaar 		LINUX_SIGEMPTYSET(set);
291956d3333SMarcel Moolenaar 		set.__bits[0] = mask;
29206ebbe77SMarcel Moolenaar 	}
29306ebbe77SMarcel Moolenaar 
294b40ce416SJulian Elischer 	error = linux_do_sigprocmask(td, args->how,
295956d3333SMarcel Moolenaar 				     args->mask ? &set : NULL,
296956d3333SMarcel Moolenaar 				     args->omask ? &oset : NULL);
29706ebbe77SMarcel Moolenaar 
298956d3333SMarcel Moolenaar 	if (args->omask != NULL && !error) {
299956d3333SMarcel Moolenaar 		mask = oset.__bits[0];
3005002a60fSMarcel Moolenaar 		error = copyout(&mask, args->omask, sizeof(l_osigset_t));
30106ebbe77SMarcel Moolenaar 	}
30206ebbe77SMarcel Moolenaar 
303956d3333SMarcel Moolenaar 	return (error);
30406ebbe77SMarcel Moolenaar }
3055231fb20SDavid E. O'Brien #endif	/*!__alpha__*/
30606ebbe77SMarcel Moolenaar 
30706ebbe77SMarcel Moolenaar int
308b40ce416SJulian Elischer linux_rt_sigprocmask(struct thread *td, struct linux_rt_sigprocmask_args *args)
30906ebbe77SMarcel Moolenaar {
3105002a60fSMarcel Moolenaar 	l_sigset_t set, oset;
31106ebbe77SMarcel Moolenaar 	int error;
31206ebbe77SMarcel Moolenaar 
31306ebbe77SMarcel Moolenaar #ifdef DEBUG
31424593369SJonathan Lemon 	if (ldebug(rt_sigprocmask))
31524593369SJonathan Lemon 		printf(ARGS(rt_sigprocmask, "%d, %p, %p, %ld"),
31624593369SJonathan Lemon 		    args->how, (void *)args->mask,
3175231fb20SDavid E. O'Brien 		    (void *)args->omask, (long)args->sigsetsize);
31806ebbe77SMarcel Moolenaar #endif
31906ebbe77SMarcel Moolenaar 
3205002a60fSMarcel Moolenaar 	if (args->sigsetsize != sizeof(l_sigset_t))
32106ebbe77SMarcel Moolenaar 		return EINVAL;
32206ebbe77SMarcel Moolenaar 
32306ebbe77SMarcel Moolenaar 	if (args->mask != NULL) {
3245002a60fSMarcel Moolenaar 		error = copyin(args->mask, &set, sizeof(l_sigset_t));
32506ebbe77SMarcel Moolenaar 		if (error)
326956d3333SMarcel Moolenaar 			return (error);
32706ebbe77SMarcel Moolenaar 	}
32806ebbe77SMarcel Moolenaar 
329b40ce416SJulian Elischer 	error = linux_do_sigprocmask(td, args->how,
330956d3333SMarcel Moolenaar 				     args->mask ? &set : NULL,
331956d3333SMarcel Moolenaar 				     args->omask ? &oset : NULL);
33206ebbe77SMarcel Moolenaar 
333956d3333SMarcel Moolenaar 	if (args->omask != NULL && !error) {
3345002a60fSMarcel Moolenaar 		error = copyout(&oset, args->omask, sizeof(l_sigset_t));
33506ebbe77SMarcel Moolenaar 	}
33606ebbe77SMarcel Moolenaar 
337956d3333SMarcel Moolenaar 	return (error);
338c21dee17SSøren Schmidt }
339c21dee17SSøren Schmidt 
3405231fb20SDavid E. O'Brien #ifndef __alpha__
341c21dee17SSøren Schmidt int
342b40ce416SJulian Elischer linux_sgetmask(struct thread *td, struct linux_sgetmask_args *args)
343c21dee17SSøren Schmidt {
344b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
3455002a60fSMarcel Moolenaar 	l_sigset_t mask;
346956d3333SMarcel Moolenaar 
347c21dee17SSøren Schmidt #ifdef DEBUG
3485002a60fSMarcel Moolenaar 	if (ldebug(sgetmask))
3495002a60fSMarcel Moolenaar 		printf(ARGS(sgetmask, ""));
350c21dee17SSøren Schmidt #endif
351956d3333SMarcel Moolenaar 
352216af822SJohn Baldwin 	PROC_LOCK(p);
3534093529dSJeff Roberson 	bsd_to_linux_sigset(&td->td_sigmask, &mask);
354216af822SJohn Baldwin 	PROC_UNLOCK(p);
355b40ce416SJulian Elischer 	td->td_retval[0] = mask.__bits[0];
356956d3333SMarcel Moolenaar 	return (0);
357c21dee17SSøren Schmidt }
358c21dee17SSøren Schmidt 
359c21dee17SSøren Schmidt int
360b40ce416SJulian Elischer linux_ssetmask(struct thread *td, struct linux_ssetmask_args *args)
361c21dee17SSøren Schmidt {
362b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
3635002a60fSMarcel Moolenaar 	l_sigset_t lset;
364956d3333SMarcel Moolenaar 	sigset_t bset;
365c21dee17SSøren Schmidt 
366c21dee17SSøren Schmidt #ifdef DEBUG
3675002a60fSMarcel Moolenaar 	if (ldebug(ssetmask))
3685002a60fSMarcel Moolenaar 		printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask);
369c21dee17SSøren Schmidt #endif
370d66a5066SPeter Wemm 
371216af822SJohn Baldwin 	PROC_LOCK(p);
3724093529dSJeff Roberson 	bsd_to_linux_sigset(&td->td_sigmask, &lset);
373b40ce416SJulian Elischer 	td->td_retval[0] = lset.__bits[0];
374956d3333SMarcel Moolenaar 	LINUX_SIGEMPTYSET(lset);
375956d3333SMarcel Moolenaar 	lset.__bits[0] = args->mask;
376956d3333SMarcel Moolenaar 	linux_to_bsd_sigset(&lset, &bset);
3774093529dSJeff Roberson 	td->td_sigmask = bset;
3784093529dSJeff Roberson 	SIG_CANTMASK(td->td_sigmask);
3794093529dSJeff Roberson 	signotify(td);
380216af822SJohn Baldwin 	PROC_UNLOCK(p);
381956d3333SMarcel Moolenaar 	return (0);
382c21dee17SSøren Schmidt }
383c21dee17SSøren Schmidt 
3845d58e285STim J. Robbins /*
3855d58e285STim J. Robbins  * MPSAFE
3865d58e285STim J. Robbins  */
387c21dee17SSøren Schmidt int
388b40ce416SJulian Elischer linux_sigpending(struct thread *td, struct linux_sigpending_args *args)
389c21dee17SSøren Schmidt {
390b40ce416SJulian Elischer 	struct proc *p = td->td_proc;
391956d3333SMarcel Moolenaar 	sigset_t bset;
3925002a60fSMarcel Moolenaar 	l_sigset_t lset;
3935002a60fSMarcel Moolenaar 	l_osigset_t mask;
394c21dee17SSøren Schmidt 
395c21dee17SSøren Schmidt #ifdef DEBUG
39624593369SJonathan Lemon 	if (ldebug(sigpending))
39724593369SJonathan Lemon 		printf(ARGS(sigpending, "*"));
398c21dee17SSøren Schmidt #endif
399956d3333SMarcel Moolenaar 
400216af822SJohn Baldwin 	PROC_LOCK(p);
4011d9c5696SJuli Mallett 	bset = p->p_siglist;
4024093529dSJeff Roberson 	SIGSETOR(bset, td->td_siglist);
4034093529dSJeff Roberson 	SIGSETAND(bset, td->td_sigmask);
404216af822SJohn Baldwin 	PROC_UNLOCK(p);
4059d8643ecSJohn Baldwin 	bsd_to_linux_sigset(&bset, &lset);
406956d3333SMarcel Moolenaar 	mask = lset.__bits[0];
407956d3333SMarcel Moolenaar 	return (copyout(&mask, args->mask, sizeof(mask)));
408c21dee17SSøren Schmidt }
4095231fb20SDavid E. O'Brien #endif	/*!__alpha__*/
410c21dee17SSøren Schmidt 
411c21dee17SSøren Schmidt int
412b40ce416SJulian Elischer linux_kill(struct thread *td, struct linux_kill_args *args)
413c21dee17SSøren Schmidt {
414ef04503dSPeter Wemm 	struct kill_args /* {
415c21dee17SSøren Schmidt 	    int pid;
416c21dee17SSøren Schmidt 	    int signum;
417ef04503dSPeter Wemm 	} */ tmp;
418c21dee17SSøren Schmidt 
419c21dee17SSøren Schmidt #ifdef DEBUG
42024593369SJonathan Lemon 	if (ldebug(kill))
42124593369SJonathan Lemon 		printf(ARGS(kill, "%d, %d"), args->pid, args->signum);
422c21dee17SSøren Schmidt #endif
423956d3333SMarcel Moolenaar 
424956d3333SMarcel Moolenaar 	/*
425956d3333SMarcel Moolenaar 	 * Allow signal 0 as a means to check for privileges
426956d3333SMarcel Moolenaar 	 */
427956d3333SMarcel Moolenaar 	if (args->signum < 0 || args->signum > LINUX_NSIG)
4282116e6abSJohn Polstra 		return EINVAL;
429956d3333SMarcel Moolenaar 
4305231fb20SDavid E. O'Brien #ifndef __alpha__
431956d3333SMarcel Moolenaar 	if (args->signum > 0 && args->signum <= LINUX_SIGTBLSZ)
432956d3333SMarcel Moolenaar 		tmp.signum = linux_to_bsd_signal[_SIG_IDX(args->signum)];
433956d3333SMarcel Moolenaar 	else
4345231fb20SDavid E. O'Brien #endif
435956d3333SMarcel Moolenaar 		tmp.signum = args->signum;
436956d3333SMarcel Moolenaar 
437c21dee17SSøren Schmidt 	tmp.pid = args->pid;
438b40ce416SJulian Elischer 	return (kill(td, &tmp));
439c21dee17SSøren Schmidt }
440