ibcs2_signal.c revision 11397
11539Srgrimes/*	$NetBSD: ibcs2_signal.c,v 1.6 1995/09/19 22:19:07 thorpej Exp $	*/
21539Srgrimes
31539Srgrimes/*
41539Srgrimes * Copyright (c) 1995 Scott Bartram
51539Srgrimes * All rights reserved.
61539Srgrimes *
71539Srgrimes * Redistribution and use in source and binary forms, with or without
81539Srgrimes * modification, are permitted provided that the following conditions
91539Srgrimes * are met:
101539Srgrimes * 1. Redistributions of source code must retain the above copyright
111539Srgrimes *    notice, this list of conditions and the following disclaimer.
121539Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
13203964Simp *    notice, this list of conditions and the following disclaimer in the
141539Srgrimes *    documentation and/or other materials provided with the distribution.
151539Srgrimes * 3. The name of the author may not be used to endorse or promote products
161539Srgrimes *    derived from this software without specific prior written permission
171539Srgrimes *
181539Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
191539Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
201539Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
211539Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
221539Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
231539Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
241539Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251539Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
261539Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
271539Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
281539Srgrimes */
291539Srgrimes
3069793Sobrien#include <sys/param.h>
311539Srgrimes#include <sys/systm.h>
321539Srgrimes#include <sys/namei.h>
331539Srgrimes#include <sys/proc.h>
341539Srgrimes#include <sys/filedesc.h>
351539Srgrimes#include <sys/ioctl.h>
363041Swollman#include <sys/mount.h>
373041Swollman#include <sys/kernel.h>
381539Srgrimes#include <sys/signal.h>
391539Srgrimes#include <sys/signalvar.h>
401539Srgrimes#include <sys/malloc.h>
41201258Sjilles#include <sys/sysproto.h>
42187969Sobrien
43187969Sobrien#include <i386/ibcs2/ibcs2_types.h>
441539Srgrimes#include <i386/ibcs2/ibcs2_signal.h>
4587136Srwatson#include <i386/ibcs2/ibcs2_proto.h>
461539Srgrimes#include <i386/ibcs2/ibcs2_xenix.h>
4787135Srwatson#include <i386/ibcs2/ibcs2_util.h>
4887135Srwatson
491539Srgrimes#define sigemptyset(s)		bzero((s), sizeof(*(s)))
5096194Sdes#define sigismember(s, n)	(*(s) & sigmask(n))
511539Srgrimes#define sigaddset(s, n)		(*(s) |= sigmask(n))
52219019Sgabor
5373986Sobrien#define	ibcs2_sigmask(n)	(1 << ((n) - 1))
541539Srgrimes#define ibcs2_sigemptyset(s)	bzero((s), sizeof(*(s)))
5569793Sobrien#define ibcs2_sigismember(s, n)	(*(s) & ibcs2_sigmask(n))
561539Srgrimes#define ibcs2_sigaddset(s, n)	(*(s) |= ibcs2_sigmask(n))
57219019Sgabor
5896194Sdesstatic void ibcs2_to_bsd_sigset    __P((const ibcs2_sigset_t *, sigset_t *));
593189Spststatic void bsd_to_ibcs2_sigset    __P((const sigset_t *, ibcs2_sigset_t *));
60170527Ssimokawastatic void ibcs2_to_bsd_sigaction __P((struct ibcs2_sigaction *,
61114763Sobrien					struct sigaction *));
62219019Sgaborstatic void bsd_to_ibcs2_sigaction __P((struct sigaction *,
63219019Sgabor					struct ibcs2_sigaction *));
64219019Sgabor
65219019Sgaborint bsd_to_ibcs2_sig[] = {
66219019Sgabor	0,			/* 0 */
67114763Sobrien	IBCS2_SIGHUP,		/* 1 */
681539Srgrimes	IBCS2_SIGINT,		/* 2 */
69113229Smdodd	IBCS2_SIGQUIT,		/* 3 */
70116844Sphantom	IBCS2_SIGILL,		/* 4 */
7196194Sdes	IBCS2_SIGTRAP,		/* 5 */
721539Srgrimes	IBCS2_SIGABRT,		/* 6 */
731539Srgrimes	IBCS2_SIGEMT,		/* 7 */
74117033Sgordon	IBCS2_SIGFPE,		/* 8 */
751539Srgrimes	IBCS2_SIGKILL,		/* 9 */
76124132Siedowse	IBCS2_SIGBUS,		/* 10 */
77117033Sgordon	IBCS2_SIGSEGV,		/* 11 */
78117033Sgordon	IBCS2_SIGSYS,		/* 12 */
7942515Sasami	IBCS2_SIGPIPE,		/* 13 */
8099958Ssobomax	IBCS2_SIGALRM,		/* 14 */
81114763Sobrien	IBCS2_SIGTERM,		/* 15 */
8296194Sdes	0,			/* 16 - SIGURG */
83114763Sobrien	IBCS2_SIGSTOP,		/* 17 */
8496194Sdes	IBCS2_SIGTSTP,		/* 18 */
851539Srgrimes	IBCS2_SIGCONT,		/* 19 */
861539Srgrimes	IBCS2_SIGCLD,		/* 20 */
871539Srgrimes	IBCS2_SIGTTIN,		/* 21 */
883041Swollman	IBCS2_SIGTTOU,		/* 22 */
891539Srgrimes	IBCS2_SIGPOLL,		/* 23 */
9096807Sjmallett	0,			/* 24 - SIGXCPU */
911539Srgrimes	0,			/* 25 - SIGXFSZ */
921539Srgrimes	IBCS2_SIGVTALRM,	/* 26 */
931539Srgrimes	IBCS2_SIGPROF,		/* 27 */
941539Srgrimes	IBCS2_SIGWINCH,		/* 28 */
951539Srgrimes	0,			/* 29 */
961539Srgrimes	IBCS2_SIGUSR1,		/* 30 */
971539Srgrimes	IBCS2_SIGUSR2,		/* 31 */
986083Swpaul};
9910975Sache
1001539Srgrimesstatic int ibcs2_to_bsd_sig[] = {
1013041Swollman	0,			/* 0 */
1023041Swollman	SIGHUP,			/* 1 */
10393032Simp	SIGINT,			/* 2 */
1043041Swollman	SIGQUIT,		/* 3 */
1053041Swollman	SIGILL,			/* 4 */
106117035Sgordon	SIGTRAP,		/* 5 */
107117035Sgordon	SIGABRT,		/* 6 */
108117035Sgordon	SIGEMT,			/* 7 */
109117035Sgordon	SIGFPE,			/* 8 */
110117035Sgordon	SIGKILL,		/* 9 */
111117035Sgordon	SIGBUS,			/* 10 */
112117035Sgordon	SIGSEGV,		/* 11 */
113117035Sgordon	SIGSYS,			/* 12 */
114117035Sgordon	SIGPIPE,		/* 13 */
115117035Sgordon	SIGALRM,		/* 14 */
116117035Sgordon	SIGTERM,		/* 15 */
117117035Sgordon	SIGUSR1,		/* 16 */
118117035Sgordon	SIGUSR2,		/* 17 */
119117035Sgordon	SIGCHLD,		/* 18 */
120117035Sgordon	0,			/* 19 - SIGPWR */
121117035Sgordon	SIGWINCH,		/* 20 */
122117035Sgordon	0,			/* 21 */
123117035Sgordon	SIGIO,			/* 22 */
124117035Sgordon	SIGSTOP,		/* 23 */
125117035Sgordon	SIGTSTP,		/* 24 */
126117035Sgordon	SIGCONT,		/* 25 */
127117035Sgordon	SIGTTIN,		/* 26 */
128117035Sgordon	SIGTTOU,		/* 27 */
129117035Sgordon	SIGVTALRM,		/* 28 */
130117035Sgordon	SIGPROF,		/* 29 */
131117035Sgordon	0,			/* 30 */
132117035Sgordon	0,			/* 31 */
133117035Sgordon};
134117035Sgordon
135117035Sgordonvoid
136117035Sgordonibcs2_to_bsd_sigset(iss, bss)
137117035Sgordon	const ibcs2_sigset_t *iss;
138117035Sgordon	sigset_t *bss;
139117035Sgordon{
140117035Sgordon	int i, newsig;
1411539Srgrimes
142	sigemptyset(bss);
143	for (i = 1; i < IBCS2_NSIG; i++) {
144		if (ibcs2_sigismember(iss, i)) {
145			newsig = ibcs2_to_bsd_sig[i];
146			if (newsig)
147				sigaddset(bss, newsig);
148		}
149	}
150}
151
152static void
153bsd_to_ibcs2_sigset(bss, iss)
154	const sigset_t *bss;
155	ibcs2_sigset_t *iss;
156{
157	int i, newsig;
158
159	ibcs2_sigemptyset(iss);
160	for (i = 1; i < NSIG; i++) {
161		if (sigismember(bss, i)) {
162			newsig = bsd_to_ibcs2_sig[i];
163			if (newsig)
164				ibcs2_sigaddset(iss, newsig);
165		}
166	}
167}
168
169static void
170ibcs2_to_bsd_sigaction(isa, bsa)
171	struct ibcs2_sigaction *isa;
172	struct sigaction *bsa;
173{
174
175	bsa->sa_handler = isa->sa_handler;
176	ibcs2_to_bsd_sigset(&isa->sa_mask, &bsa->sa_mask);
177	bsa->sa_flags = 0;
178	if ((isa->sa_flags & IBCS2_SA_NOCLDSTOP) != 0)
179		bsa->sa_flags |= SA_NOCLDSTOP;
180}
181
182static void
183bsd_to_ibcs2_sigaction(bsa, isa)
184	struct sigaction *bsa;
185	struct ibcs2_sigaction *isa;
186{
187
188	isa->sa_handler = bsa->sa_handler;
189	bsd_to_ibcs2_sigset(&bsa->sa_mask, &isa->sa_mask);
190	isa->sa_flags = 0;
191	if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
192		isa->sa_flags |= SA_NOCLDSTOP;
193}
194
195int
196ibcs2_sigaction(p, uap, retval)
197	register struct proc *p;
198	struct ibcs2_sigaction_args *uap;
199	int *retval;
200{
201	struct ibcs2_sigaction *nisa, *oisa, tmpisa;
202	struct sigaction *nbsa, *obsa, tmpbsa;
203	struct sigaction_args sa;
204	caddr_t sg;
205	int error;
206
207	sg = stackgap_init();
208	nisa = SCARG(uap, act);
209	oisa = SCARG(uap, oact);
210
211	if (oisa != NULL)
212		obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
213	else
214		obsa = NULL;
215
216	if (nisa != NULL) {
217		nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
218		if ((error = copyin(nisa, &tmpisa, sizeof(tmpisa))) != 0)
219			return error;
220		ibcs2_to_bsd_sigaction(&tmpisa, &tmpbsa);
221		if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
222			return error;
223	} else
224		nbsa = NULL;
225
226	SCARG(&sa, signum) = ibcs2_to_bsd_sig[SCARG(uap, sig)];
227	SCARG(&sa, nsa) = nbsa;
228	SCARG(&sa, osa) = obsa;
229
230	if ((error = sigaction(p, &sa, retval)) != 0)
231		return error;
232
233	if (oisa != NULL) {
234		if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
235			return error;
236		bsd_to_ibcs2_sigaction(&tmpbsa, &tmpisa);
237		if ((error = copyout(&tmpisa, oisa, sizeof(tmpisa))) != 0)
238			return error;
239	}
240
241	return 0;
242}
243
244int
245ibcs2_sigsys(p, uap, retval)
246	register struct proc *p;
247	struct ibcs2_sigsys_args *uap;
248	int *retval;
249{
250	int signum = ibcs2_to_bsd_sig[IBCS2_SIGNO(SCARG(uap, sig))];
251	int error;
252	caddr_t sg = stackgap_init();
253
254	if (signum <= 0 || signum >= IBCS2_NSIG) {
255		if (IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGNAL_MASK ||
256		    IBCS2_SIGCALL(SCARG(uap, sig)) == IBCS2_SIGSET_MASK)
257			*retval = (int)IBCS2_SIG_ERR;
258		return EINVAL;
259	}
260
261	switch (IBCS2_SIGCALL(SCARG(uap, sig))) {
262	/*
263	 * sigset is identical to signal() except that SIG_HOLD is allowed as
264	 * an action.
265	 */
266	case IBCS2_SIGSET_MASK:
267		/*
268		 * sigset is identical to signal() except
269		 * that SIG_HOLD is allowed as
270		 * an action.
271		 */
272		if (SCARG(uap, fp) == IBCS2_SIG_HOLD) {
273			struct sigprocmask_args sa;
274
275			SCARG(&sa, how) = SIG_BLOCK;
276			SCARG(&sa, mask) = sigmask(signum);
277			return sigprocmask(p, &sa, retval);
278		}
279		/* FALLTHROUGH */
280
281	case IBCS2_SIGNAL_MASK:
282		{
283			struct sigaction_args sa_args;
284			struct sigaction *nbsa, *obsa, sa;
285
286			nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
287			obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
288			SCARG(&sa_args, signum) = signum;
289			SCARG(&sa_args, nsa) = nbsa;
290			SCARG(&sa_args, osa) = obsa;
291
292			sa.sa_handler = SCARG(uap, fp);
293			sigemptyset(&sa.sa_mask);
294			sa.sa_flags = 0;
295#if 0
296			if (signum != SIGALRM)
297				sa.sa_flags = SA_RESTART;
298#endif
299			if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
300				return error;
301			if ((error = sigaction(p, &sa_args, retval)) != 0) {
302				DPRINTF(("signal: sigaction failed: %d\n",
303					 error));
304				*retval = (int)IBCS2_SIG_ERR;
305				return error;
306			}
307			if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
308				return error;
309			*retval = (int)sa.sa_handler;
310			return 0;
311		}
312
313	case IBCS2_SIGHOLD_MASK:
314		{
315			struct sigprocmask_args sa;
316
317			SCARG(&sa, how) = SIG_BLOCK;
318			SCARG(&sa, mask) = sigmask(signum);
319			return sigprocmask(p, &sa, retval);
320		}
321
322	case IBCS2_SIGRELSE_MASK:
323		{
324			struct sigprocmask_args sa;
325
326			SCARG(&sa, how) = SIG_UNBLOCK;
327			SCARG(&sa, mask) = sigmask(signum);
328			return sigprocmask(p, &sa, retval);
329		}
330
331	case IBCS2_SIGIGNORE_MASK:
332		{
333			struct sigaction_args sa_args;
334			struct sigaction *bsa, sa;
335
336			bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
337			SCARG(&sa_args, signum) = signum;
338			SCARG(&sa_args, nsa) = bsa;
339			SCARG(&sa_args, osa) = NULL;
340
341			sa.sa_handler = SIG_IGN;
342			sigemptyset(&sa.sa_mask);
343			sa.sa_flags = 0;
344			if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
345				return error;
346			if ((error = sigaction(p, &sa_args, retval)) != 0) {
347				DPRINTF(("sigignore: sigaction failed\n"));
348				return error;
349			}
350			return 0;
351		}
352
353	case IBCS2_SIGPAUSE_MASK:
354		{
355			struct sigsuspend_args sa;
356
357			SCARG(&sa, mask) = p->p_sigmask &~ sigmask(signum);
358			return sigsuspend(p, &sa, retval);
359		}
360
361	default:
362		return ENOSYS;
363	}
364}
365
366int
367ibcs2_sigprocmask(p, uap, retval)
368	register struct proc *p;
369	struct ibcs2_sigprocmask_args *uap;
370	int *retval;
371{
372	ibcs2_sigset_t iss;
373	sigset_t bss;
374	int error = 0;
375
376	if (SCARG(uap, oset) != NULL) {
377		/* Fix the return value first if needed */
378		bsd_to_ibcs2_sigset(&p->p_sigmask, &iss);
379		if ((error = copyout(&iss, SCARG(uap, oset), sizeof(iss))) != 0)
380			return error;
381	}
382
383	if (SCARG(uap, set) == NULL)
384		/* Just examine */
385		return 0;
386
387	if ((error = copyin(SCARG(uap, set), &iss, sizeof(iss))) != 0)
388		return error;
389
390	ibcs2_to_bsd_sigset(&iss, &bss);
391
392	(void) splhigh();
393
394	switch (SCARG(uap, how)) {
395	case IBCS2_SIG_BLOCK:
396		p->p_sigmask |= bss & ~sigcantmask;
397		break;
398
399	case IBCS2_SIG_UNBLOCK:
400		p->p_sigmask &= ~bss;
401		break;
402
403	case IBCS2_SIG_SETMASK:
404		p->p_sigmask = bss & ~sigcantmask;
405		break;
406
407	default:
408		error = EINVAL;
409		break;
410	}
411
412	(void) spl0();
413
414	return error;
415}
416
417int
418ibcs2_sigpending(p, uap, retval)
419	register struct proc *p;
420	struct ibcs2_sigpending_args *uap;
421	int *retval;
422{
423	sigset_t bss;
424	ibcs2_sigset_t iss;
425
426	bss = p->p_siglist & p->p_sigmask;
427	bsd_to_ibcs2_sigset(&bss, &iss);
428
429	return copyout(&iss, SCARG(uap, mask), sizeof(iss));
430}
431
432int
433ibcs2_sigsuspend(p, uap, retval)
434	register struct proc *p;
435	struct ibcs2_sigsuspend_args *uap;
436	int *retval;
437{
438	ibcs2_sigset_t sss;
439	sigset_t bss;
440	struct sigsuspend_args sa;
441	int error;
442
443	if ((error = copyin(SCARG(uap, mask), &sss, sizeof(sss))) != 0)
444		return error;
445
446	ibcs2_to_bsd_sigset(&sss, &bss);
447
448	SCARG(&sa, mask) = bss;
449	return sigsuspend(p, &sa, retval);
450}
451
452int
453ibcs2_pause(p, uap, retval)
454	register struct proc *p;
455	struct ibcs2_pause_args *uap;
456	int *retval;
457{
458	struct sigsuspend_args bsa;
459
460	SCARG(&bsa, mask) = p->p_sigmask;
461	return sigsuspend(p, &bsa, retval);
462}
463
464int
465ibcs2_kill(p, uap, retval)
466	register struct proc *p;
467	struct ibcs2_kill_args *uap;
468	int *retval;
469{
470	struct kill_args ka;
471
472	SCARG(&ka, pid) = SCARG(uap, pid);
473	SCARG(&ka, signum) = ibcs2_to_bsd_sig[SCARG(uap, signo)];
474	return kill(p, &ka, retval);
475}
476