update from Mike Hibler for new VM and other machine support
[unix-history] / usr / src / sys / hp / hpux / hpux_sig.c
CommitLineData
a8fd2d0d
KM
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 *
22d09b27 12 * from: Utah $Hdr: hpux_sig.c 1.1 90/07/09$
a8fd2d0d 13 *
22d09b27 14 * @(#)hpux_sig.c 7.5 (Berkeley) %G%
a8fd2d0d
KM
15 */
16
17/*
18 * Signal related HPUX compatibility routines
19 */
20
21#ifdef HPUXCOMPAT
22
23#include "param.h"
24#include "systm.h"
196c0567 25#include "user.h"
a8fd2d0d
KM
26#include "kernel.h"
27#include "proc.h"
28#include "hpux.h"
29
30/* indexed by HPUX signal number - 1 */
31char 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 */
39char 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 */
d9bd2b96
MH
55hpuxsigvec(p, uap, retval)
56 struct proc *p;
57 register struct args {
a8fd2d0d
KM
58 int signo;
59 struct sigvec *nsv;
60 struct sigvec *osv;
d9bd2b96
MH
61 } *uap;
62 int *retval;
63{
a8fd2d0d
KM
64 struct sigvec vec;
65 register struct sigvec *sv;
66 register int sig;
d9bd2b96 67 int bit, error;
a8fd2d0d
KM
68
69 sig = hpuxtobsdsig(uap->signo);
d9bd2b96 70 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
196c0567 71 return (EINVAL);
a8fd2d0d
KM
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 */
d9bd2b96 84 if (p->p_flag & SOUSIG)
a8fd2d0d
KM
85 sv->sv_flags |= HPUXSV_RESET; /* XXX */
86#endif
d9bd2b96
MH
87 error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec));
88 if (error)
196c0567 89 return (error);
a8fd2d0d
KM
90 }
91 if (uap->nsv) {
d9bd2b96
MH
92 error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec));
93 if (error)
196c0567 94 return (error);
d9bd2b96 95 if (sig == SIGCONT && sv->sv_handler == SIG_IGN)
196c0567 96 return (EINVAL);
d9bd2b96 97 setsigvec(p, sig, (struct sigaction *)sv);
a8fd2d0d
KM
98#if 0
99/* XXX -- SOUSIG no longer exists, do something here */
100 if (sv->sv_flags & HPUXSV_RESET)
d9bd2b96 101 p->p_flag |= SOUSIG; /* XXX */
a8fd2d0d
KM
102#endif
103 }
196c0567 104 return (0);
a8fd2d0d
KM
105}
106
d9bd2b96
MH
107hpuxsigblock(p, uap, retval)
108 register struct proc *p;
109 struct args {
a8fd2d0d 110 int mask;
d9bd2b96
MH
111 } *uap;
112 int *retval;
113{
a8fd2d0d
KM
114
115 (void) splhigh();
d9bd2b96
MH
116 *retval = bsdtohpuxmask(p->p_sigmask);
117 p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask;
a8fd2d0d 118 (void) spl0();
196c0567 119 return (0);
a8fd2d0d
KM
120}
121
d9bd2b96
MH
122hpuxsigsetmask(p, uap, retval)
123 struct proc *p;
124 struct args {
a8fd2d0d 125 int mask;
d9bd2b96
MH
126 } *uap;
127 int *retval;
128{
a8fd2d0d
KM
129
130 (void) splhigh();
d9bd2b96
MH
131 *retval = bsdtohpuxmask(p->p_sigmask);
132 p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask;
a8fd2d0d 133 (void) spl0();
196c0567 134 return (0);
a8fd2d0d
KM
135}
136
d9bd2b96
MH
137hpuxsigpause(p, uap, retval)
138 struct proc *p;
139 struct args {
a8fd2d0d 140 int mask;
d9bd2b96
MH
141 } *uap;
142 int *retval;
143{
a8fd2d0d
KM
144
145 uap->mask = hpuxtobsdmask(uap->mask);
196c0567 146 return (sigsuspend(p, uap, retval));
a8fd2d0d
KM
147}
148
149/* not totally correct, but close enuf' */
d9bd2b96
MH
150hpuxkill(p, uap, retval)
151 struct proc *p;
152 struct args {
a8fd2d0d
KM
153 int pid;
154 int signo;
d9bd2b96
MH
155 } *uap;
156 int *retval;
157{
a8fd2d0d
KM
158
159 if (uap->signo) {
160 uap->signo = hpuxtobsdsig(uap->signo);
161 if (uap->signo == 0)
162 uap->signo = NSIG;
163 }
196c0567 164 return (kill(p, uap, retval));
a8fd2d0d
KM
165}
166
22d09b27
KM
167/*
168 * The following (sigprocmask, sigpending, sigsuspend, sigaction are
169 * POSIX calls. Under BSD, the library routine dereferences the sigset_t
170 * pointers before traping. Not so under HP-UX.
171 */
172
173/*
174 * Manipulate signal mask.
175 * Note that we receive new mask, not pointer,
176 * and return old mask as return value;
177 * the library stub does the rest.
178 */
179hpuxsigprocmask(p, uap, retval)
180 register struct proc *p;
181 struct args {
182 int how;
183 hpuxsigset_t *set;
184 hpuxsigset_t *oset;
185 } *uap;
186 int *retval;
187{
188 int mask, error = 0;
189 hpuxsigset_t sigset;
190
191 /*
192 * Copy out old mask first to ensure no errors.
193 * (proc sigmask should not be changed if call fails for any reason)
194 */
195 if (uap->oset) {
196 bzero((caddr_t)&sigset, sizeof(sigset));
197 sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask);
198 if (copyout((caddr_t)&sigset, (caddr_t)uap->oset, sizeof(sigset)))
199 return (EFAULT);
200 }
201 if (uap->set) {
202 if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset)))
203 return (EFAULT);
204 mask = hpuxtobsdmask(sigset.sigset[0]);
205 (void) splhigh();
206 switch (uap->how) {
207 case HPUXSIG_BLOCK:
208 p->p_sigmask |= mask &~ sigcantmask;
209 break;
210 case HPUXSIG_UNBLOCK:
211 p->p_sigmask &= ~mask;
212 break;
213 case HPUXSIG_SETMASK:
214 p->p_sigmask = mask &~ sigcantmask;
215 break;
216 default:
217 error = EINVAL;
218 break;
219 }
220 (void) spl0();
221 }
222 return (error);
223}
224
225hpuxsigpending(p, uap, retval)
226 register struct proc *p;
227 struct args {
228 hpuxsigset_t *set;
229 } *uap;
230 int *retval;
231{
232 hpuxsigset_t sigset;
233
234 sigset.sigset[0] = bsdtohpuxmask(p->p_sig);
235 return (copyout((caddr_t)&sigset, (caddr_t)uap->set, sizeof(sigset)));
236}
237
238hpuxsigsuspend(p, uap, retval)
239 register struct proc *p;
240 struct args {
241 hpuxsigset_t *set;
242 } *uap;
243 int *retval;
244{
245 hpuxsigset_t sigset;
246 int mask;
247
248 if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset)))
249 return (EFAULT);
250 mask = hpuxtobsdmask(sigset.sigset[0]);
251 u.u_oldmask = p->p_sigmask;
252 p->p_flag |= SOMASK;
253 p->p_sigmask = mask &~ sigcantmask;
254 (void) tsleep((caddr_t)&u, PPAUSE | PCATCH, "pause", 0);
255 /* always return EINTR rather than ERESTART... */
256 return (EINTR);
257}
258
259hpuxsigaction(p, uap, retval)
260 struct proc *p;
261 register struct args {
262 int signo;
263 struct hpuxsigaction *nsa;
264 struct hpuxsigaction *osa;
265 } *uap;
266 int *retval;
267{
268 struct hpuxsigaction action;
269 register struct hpuxsigaction *sa;
270 register int sig;
271 int bit;
272
273 sig = hpuxtobsdsig(uap->signo);
274 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
275 return (EINVAL);
276
277 sa = &action;
278 if (uap->osa) {
279 sa->sa_handler = u.u_signal[sig];
280 bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask));
281 sa->sa_mask.sigset[0] = bsdtohpuxmask(u.u_sigmask[sig]);
282 bit = sigmask(sig);
283 sa->sa_flags = 0;
284 if ((u.u_sigonstack & bit) != 0)
285 sa->sa_flags |= HPUXSA_ONSTACK;
286#if 0
287/* XXX -- SOUSIG no longer exists, do something here */
288 if (p->p_flag & SOUSIG)
289 sa->sa_flags |= HPUXSA_RESETHAND; /* XXX */
290#endif
291 if (p->p_flag & SNOCLDSTOP)
292 sa->sa_flags |= HPUXSA_NOCLDSTOP;
293 if (copyout((caddr_t)sa, (caddr_t)uap->osa, sizeof (action)))
294 return (EFAULT);
295 }
296 if (uap->nsa) {
297 struct sigaction act;
298
299 if (copyin((caddr_t)uap->nsa, (caddr_t)sa, sizeof (action)))
300 return (EFAULT);
301 if (sig == SIGCONT && sa->sa_handler == SIG_IGN)
302 return (EINVAL);
303 /*
304 * Create a sigaction struct for setsigvec
305 */
306 act.sa_handler = sa->sa_handler;
307 act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]);
308 act.sa_flags = 0;
309 if (sa->sa_flags & HPUXSA_ONSTACK)
310 act.sa_flags |= SA_ONSTACK;
311 if (sa->sa_flags & HPUXSA_NOCLDSTOP)
312 act.sa_flags |= SA_NOCLDSTOP;
313 setsigvec(p, sig, &act);
314#if 0
315/* XXX -- SOUSIG no longer exists, do something here */
316 if (sa->sa_flags & HPUXSA_RESETHAND)
317 p->p_flag |= SOUSIG; /* XXX */
318#endif
319 }
320 return (0);
321}
322
d9bd2b96
MH
323ohpuxssig(p, uap, retval)
324 struct proc *p;
325 struct args {
a8fd2d0d
KM
326 int signo;
327 sig_t fun;
d9bd2b96
MH
328 } *uap;
329 int *retval;
330{
a8fd2d0d
KM
331 register int a;
332 struct sigvec vec;
333 register struct sigvec *sv = &vec;
a8fd2d0d
KM
334
335 a = hpuxtobsdsig(uap->signo);
336 sv->sv_handler = uap->fun;
337 /*
338 * Kill processes trying to use job control facilities
339 * (this'll help us find any vestiges of the old stuff).
340 */
341 if ((a &~ 0377) ||
342 (sv->sv_handler != SIG_DFL && sv->sv_handler != SIG_IGN &&
343 ((int)sv->sv_handler) & 1)) {
344 psignal(p, SIGSYS);
196c0567 345 return (0);
a8fd2d0d
KM
346 }
347 if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP ||
d9bd2b96 348 a == SIGCONT && sv->sv_handler == SIG_IGN)
196c0567 349 return (EINVAL);
a8fd2d0d
KM
350 sv->sv_mask = 0;
351 sv->sv_flags = SV_INTERRUPT;
d9bd2b96
MH
352 *retval = (int)u.u_signal[a];
353 setsigvec(p, a, (struct sigaction *)sv);
a8fd2d0d
KM
354#if 0
355 p->p_flag |= SOUSIG; /* mark as simulating old stuff */
356#endif
196c0567 357 return (0);
a8fd2d0d
KM
358}
359
360/* signal numbers: convert from HPUX to BSD */
361hpuxtobsdsig(sig)
362 register int sig;
363{
364 if (--sig < 0 || sig >= NSIG)
365 return(0);
366 return((int)hpuxtobsdsigmap[sig]);
367}
368
369/* signal numbers: convert from BSD to HPUX */
370bsdtohpuxsig(sig)
371 register int sig;
372{
373 if (--sig < 0 || sig >= NSIG)
374 return(0);
375 return((int)bsdtohpuxsigmap[sig]);
376}
377
378/* signal masks: convert from HPUX to BSD (not pretty or fast) */
379hpuxtobsdmask(mask)
380 register int mask;
381{
382 register int nmask, sig, nsig;
383
384 if (mask == 0 || mask == -1)
385 return(mask);
386 nmask = 0;
387 for (sig = 1; sig < NSIG; sig++)
388 if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig)))
389 nmask |= sigmask(nsig);
390 return(nmask);
391}
392
393bsdtohpuxmask(mask)
394 register int mask;
395{
396 register int nmask, sig, nsig;
397
398 if (mask == 0 || mask == -1)
399 return(mask);
400 nmask = 0;
401 for (sig = 1; sig < NSIG; sig++)
402 if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig)))
403 nmask |= sigmask(nsig);
404 return(nmask);
405}
406#endif