xref: /original-bsd/sys/hp/hpux/hpux_sig.c (revision c829ecf6)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: hpux_compat.c 1.33 89/08/23$
13  *
14  *	@(#)hpux_sig.c	7.2 (Berkeley) 06/08/90
15  */
16 
17 /*
18  * Signal related HPUX compatibility routines
19  */
20 
21 #ifdef HPUXCOMPAT
22 
23 #include "param.h"
24 #include "systm.h"
25 #include "user.h"
26 #include "kernel.h"
27 #include "proc.h"
28 #include "hpux.h"
29 
30 /* indexed by HPUX signal number - 1 */
31 char hpuxtobsdsigmap[NSIG] = {
32 /*01*/	SIGHUP,  SIGINT, SIGQUIT, SIGILL,   SIGTRAP, SIGIOT,  SIGEMT,   SIGFPE,
33 /*09*/  SIGKILL, SIGBUS, SIGSEGV, SIGSYS,   SIGPIPE, SIGALRM, SIGTERM,  SIGUSR1,
34 /*17*/  SIGUSR2, SIGCHLD, 0,      SIGVTALRM,SIGPROF, SIGIO,   SIGWINCH, SIGSTOP,
35 /*25*/	SIGTSTP, SIGCONT,SIGTTIN, SIGTTOU,  SIGURG,  0,       0,        0
36 };
37 
38 /* indexed by BSD signal number - 1 */
39 char bsdtohpuxsigmap[NSIG] = {
40 /*01*/	 1,  2,  3,  4,  5,  6,  7,  8,
41 /*09*/   9, 10, 11, 12, 13, 14, 15, 29,
42 /*17*/  24, 25, 26, 18, 27, 28, 22,  0,
43 /*25*/	 0, 20, 21, 23,  0, 16, 17,  0
44 };
45 
46 /*
47  * XXX: In addition to mapping the signal number we also have
48  * to see if the "old" style signal mechinism is needed.
49  * If so, we set the OUSIG flag.  This is not really correct
50  * as under HP-UX "old" style handling can be set on a per
51  * signal basis and we are setting it for all signals in one
52  * swell foop.  I suspect we can get away with this since I
53  * doubt any program of interest mixes the two semantics.
54  */
55 hpuxsigvec()
56 {
57 	register struct a {
58 		int	signo;
59 		struct	sigvec *nsv;
60 		struct	sigvec *osv;
61 	} *uap = (struct a  *)u.u_ap;
62 	struct sigvec vec;
63 	register struct sigvec *sv;
64 	register int sig;
65 	int bit;
66 
67 	sig = hpuxtobsdsig(uap->signo);
68 	if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) {
69 		u.u_error = EINVAL;
70 		return;
71 	}
72 	sv = &vec;
73 	if (uap->osv) {
74 		sv->sv_handler = u.u_signal[sig];
75 		sv->sv_mask = u.u_sigmask[sig];
76 		bit = sigmask(sig);
77 		sv->sv_flags = 0;
78 		if ((u.u_sigonstack & bit) != 0)
79 			sv->sv_flags |= SV_ONSTACK;
80 		if ((u.u_sigintr & bit) != 0)
81 			sv->sv_flags |= SV_INTERRUPT;
82 #if 0
83 /* XXX -- SOUSIG no longer exists, do something here */
84 		if (u.u_procp->p_flag & SOUSIG)
85 			sv->sv_flags |= HPUXSV_RESET;		/* XXX */
86 #endif
87 		u.u_error =
88 		    copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec));
89 		if (u.u_error)
90 			return;
91 	}
92 	if (uap->nsv) {
93 		u.u_error =
94 		    copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec));
95 		if (u.u_error)
96 			return;
97 		if (sig == SIGCONT && sv->sv_handler == SIG_IGN) {
98 			u.u_error = EINVAL;
99 			return;
100 		}
101 		setsigvec(u.u_procp, sig, (struct sigaction *)sv);
102 #if 0
103 /* XXX -- SOUSIG no longer exists, do something here */
104 		if (sv->sv_flags & HPUXSV_RESET)
105 			u.u_procp->p_flag |= SOUSIG;		/* XXX */
106 #endif
107 	}
108 }
109 
110 hpuxsigblock()
111 {
112 	struct a {
113 		int	mask;
114 	} *uap = (struct a *)u.u_ap;
115 
116 	(void) splhigh();
117 	u.u_r.r_val1 = bsdtohpuxmask(u.u_procp->p_sigmask);
118 	u.u_procp->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask;
119 	(void) spl0();
120 }
121 
122 hpuxsigsetmask()
123 {
124 	struct a {
125 		int	mask;
126 	} *uap = (struct a *)u.u_ap;
127 
128 	(void) splhigh();
129 	u.u_r.r_val1 = bsdtohpuxmask(u.u_procp->p_sigmask);
130 	u.u_procp->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask;
131 	(void) spl0();
132 }
133 
134 hpuxsigpause()
135 {
136 	struct a {
137 		int	mask;
138 	} *uap = (struct a *)u.u_ap;
139 
140 	uap->mask = hpuxtobsdmask(uap->mask);
141 	sigsuspend();
142 }
143 
144 /* not totally correct, but close enuf' */
145 hpuxkill()
146 {
147 	struct a {
148 		int	pid;
149 		int	signo;
150 	} *uap = (struct a *)u.u_ap;
151 
152 	if (uap->signo) {
153 		uap->signo = hpuxtobsdsig(uap->signo);
154 		if (uap->signo == 0)
155 			uap->signo = NSIG;
156 	}
157 	kill();
158 }
159 
160 ohpuxssig()
161 {
162 	struct a {
163 		int	signo;
164 		sig_t	fun;
165 	} *uap = (struct a *)u.u_ap;
166 	register int a;
167 	struct sigvec vec;
168 	register struct sigvec *sv = &vec;
169 	struct proc *p = u.u_procp;
170 
171 	a = hpuxtobsdsig(uap->signo);
172 	sv->sv_handler = uap->fun;
173 	/*
174 	 * Kill processes trying to use job control facilities
175 	 * (this'll help us find any vestiges of the old stuff).
176 	 */
177 	if ((a &~ 0377) ||
178 	    (sv->sv_handler != SIG_DFL && sv->sv_handler != SIG_IGN &&
179 	     ((int)sv->sv_handler) & 1)) {
180 		psignal(p, SIGSYS);
181 		return;
182 	}
183 	if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP ||
184 	    a == SIGCONT && sv->sv_handler == SIG_IGN) {
185 		u.u_error = EINVAL;
186 		return;
187 	}
188 	sv->sv_mask = 0;
189 	sv->sv_flags = SV_INTERRUPT;
190 	u.u_r.r_val1 = (int)u.u_signal[a];
191 	setsigvec(u.u_procp, a, (struct sigaction *)sv);
192 #if 0
193 	p->p_flag |= SOUSIG;		/* mark as simulating old stuff */
194 #endif
195 }
196 
197 /* signal numbers: convert from HPUX to BSD */
198 hpuxtobsdsig(sig)
199 	register int sig;
200 {
201 	if (--sig < 0 || sig >= NSIG)
202 		return(0);
203 	return((int)hpuxtobsdsigmap[sig]);
204 }
205 
206 /* signal numbers: convert from BSD to HPUX */
207 bsdtohpuxsig(sig)
208 	register int sig;
209 {
210 	if (--sig < 0 || sig >= NSIG)
211 		return(0);
212 	return((int)bsdtohpuxsigmap[sig]);
213 }
214 
215 /* signal masks: convert from HPUX to BSD (not pretty or fast) */
216 hpuxtobsdmask(mask)
217 	register int mask;
218 {
219 	register int nmask, sig, nsig;
220 
221 	if (mask == 0 || mask == -1)
222 		return(mask);
223 	nmask = 0;
224 	for (sig = 1; sig < NSIG; sig++)
225 		if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig)))
226 			nmask |= sigmask(nsig);
227 	return(nmask);
228 }
229 
230 bsdtohpuxmask(mask)
231 	register int mask;
232 {
233 	register int nmask, sig, nsig;
234 
235 	if (mask == 0 || mask == -1)
236 		return(mask);
237 	nmask = 0;
238 	for (sig = 1; sig < NSIG; sig++)
239 		if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig)))
240 			nmask |= sigmask(nsig);
241 	return(nmask);
242 }
243 #endif
244