Annotation of sys/compat/hpux/hpux_sig.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: hpux_sig.c,v 1.9 2004/09/19 21:56:18 mickey Exp $ */
2: /* $NetBSD: hpux_sig.c,v 1.16 1997/04/01 19:59:02 scottr Exp $ */
3:
4: /*
5: * Copyright (c) 1988 University of Utah.
6: * Copyright (c) 1990, 1993
7: * The Regents of the University of California. All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * the Systems Programming Group of the University of Utah Computer
11: * Science Department.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * from: Utah $Hdr: hpux_sig.c 1.4 92/01/20$
38: *
39: * @(#)hpux_sig.c 8.2 (Berkeley) 9/23/93
40: */
41:
42: /*
43: * Signal related HPUX compatibility routines
44: */
45:
46: #include <sys/param.h>
47: #include <sys/systm.h>
48: #include <sys/kernel.h>
49: #include <sys/mount.h>
50: #include <sys/proc.h>
51: #include <sys/signalvar.h>
52: #include <sys/syscallargs.h>
53:
54: #include <compat/hpux/hpux.h>
55: #include <compat/hpux/hpux_sig.h>
56: #include <compat/hpux/hpux_syscallargs.h>
57:
58: /* indexed by HPUX signal number - 1 */
59: char hpuxtobsdsigmap[NSIG] = {
60: /*01*/ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGIOT, SIGEMT, SIGFPE,
61: /*09*/ SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1,
62: /*17*/ SIGUSR2, SIGCHLD, 0, SIGVTALRM,SIGPROF, SIGIO, SIGWINCH, SIGSTOP,
63: /*25*/ SIGTSTP, SIGCONT,SIGTTIN, SIGTTOU, SIGURG, 0, 0, 0
64: };
65:
66: /* indexed by BSD signal number - 1 */
67: char bsdtohpuxsigmap[NSIG] = {
68: /*01*/ 1, 2, 3, 4, 5, 6, 7, 8,
69: /*09*/ 9, 10, 11, 12, 13, 14, 15, 29,
70: /*17*/ 24, 25, 26, 18, 27, 28, 22, 0,
71: /*25*/ 0, 20, 21, 23, 0, 16, 17, 0
72: };
73:
74: /*
75: * XXX: In addition to mapping the signal number we also have
76: * to see if the "old" style signal mechinism is needed.
77: * If so, we set the OUSIG flag. This is not really correct
78: * as under HP-UX "old" style handling can be set on a per
79: * signal basis and we are setting it for all signals in one
80: * swell foop. I suspect we can get away with this since I
81: * doubt any program of interest mixes the two semantics.
82: */
83: int
84: hpux_sys_sigvec(p, v, retval)
85: struct proc *p;
86: void *v;
87: register_t *retval;
88: {
89: struct hpux_sys_sigvec_args *uap = v;
90: struct sigvec vec;
91: struct sigacts *ps = p->p_sigacts;
92: struct sigvec *sv;
93: int sig;
94: int bit, error;
95:
96: sig = hpuxtobsdsig(SCARG(uap, signo));
97: if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
98: return (EINVAL);
99: sv = &vec;
100: if (SCARG(uap, osv)) {
101: sv->sv_handler = ps->ps_sigact[sig];
102: sv->sv_mask = ps->ps_catchmask[sig];
103: bit = sigmask(sig);
104: sv->sv_flags = 0;
105: if ((ps->ps_sigonstack & bit) != 0)
106: sv->sv_flags |= SV_ONSTACK;
107: if ((ps->ps_sigintr & bit) != 0)
108: sv->sv_flags |= SV_INTERRUPT;
109: if ((ps->ps_sigreset & bit) != 0)
110: sv->sv_flags |= HPUXSV_RESET;
111: sv->sv_mask &= ~bit;
112: error = copyout((caddr_t)sv, (caddr_t)SCARG(uap, osv),
113: sizeof (vec));
114: if (error)
115: return (error);
116: }
117: if (SCARG(uap, nsv)) {
118: error = copyin((caddr_t)SCARG(uap, nsv), (caddr_t)sv,
119: sizeof (vec));
120: if (error)
121: return (error);
122: if (sig == SIGCONT && sv->sv_handler == SIG_IGN)
123: return (EINVAL);
124: sv->sv_flags ^= SA_RESTART;
125: setsigvec(p, sig, (struct sigaction *)sv);
126: #if 0
127: /* XXX -- SOUSIG no longer exists, do something here */
128: if (sv->sv_flags & HPUXSV_RESET)
129: p->p_flag |= SOUSIG; /* XXX */
130: #endif
131: }
132: return (0);
133: }
134:
135: int
136: hpux_sys_sigblock(p, v, retval)
137: struct proc *p;
138: void *v;
139: register_t *retval;
140: {
141: struct hpux_sys_sigblock_args *uap = v;
142:
143: (void) splhigh();
144: *retval = bsdtohpuxmask(p->p_sigmask);
145: p->p_sigmask |= hpuxtobsdmask(SCARG(uap, mask)) &~ sigcantmask;
146: (void) spl0();
147: return (0);
148: }
149:
150: int
151: hpux_sys_sigsetmask(p, v, retval)
152: struct proc *p;
153: void *v;
154: register_t *retval;
155: {
156: struct hpux_sys_sigsetmask_args *uap = v;
157:
158: (void) splhigh();
159: *retval = bsdtohpuxmask(p->p_sigmask);
160: p->p_sigmask = hpuxtobsdmask(SCARG(uap, mask)) &~ sigcantmask;
161: (void) spl0();
162: return (0);
163: }
164:
165: int
166: hpux_sys_sigpause(p, v, retval)
167: struct proc *p;
168: void *v;
169: register_t *retval;
170: {
171: struct hpux_sys_sigpause_args *uap = v;
172:
173: SCARG(uap, mask) = hpuxtobsdmask(SCARG(uap, mask));
174: return (sys_sigsuspend(p, uap, retval));
175: }
176:
177: /* not totally correct, but close enuf' */
178: int
179: hpux_sys_kill(p, v, retval)
180: struct proc *p;
181: void *v;
182: register_t *retval;
183: {
184: struct hpux_sys_kill_args *uap = v;
185:
186: if (SCARG(uap, signo)) {
187: SCARG(uap, signo) = hpuxtobsdsig(SCARG(uap, signo));
188: if (SCARG(uap, signo) == 0)
189: SCARG(uap, signo) = NSIG;
190: }
191: return (sys_kill(p, uap, retval));
192: }
193:
194: /*
195: * The following (sigprocmask, sigpending, sigsuspend, sigaction are
196: * POSIX calls. Under BSD, the library routine dereferences the sigset_t
197: * pointers before traping. Not so under HP-UX.
198: */
199:
200: /*
201: * Manipulate signal mask.
202: * Note that we receive new mask, not pointer,
203: * and return old mask as return value;
204: * the library stub does the rest.
205: */
206: int
207: hpux_sys_sigprocmask(p, v, retval)
208: struct proc *p;
209: void *v;
210: register_t *retval;
211: {
212: struct hpux_sys_sigprocmask_args *uap = v;
213: int mask, error = 0;
214: hpux_sigset_t sigset;
215:
216: /*
217: * Copy out old mask first to ensure no errors.
218: * (proc sigmask should not be changed if call fails for any reason)
219: */
220: if (SCARG(uap, oset)) {
221: bzero((caddr_t)&sigset, sizeof(sigset));
222: sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask);
223: if (copyout((caddr_t)&sigset, (caddr_t)SCARG(uap, oset),
224: sizeof(sigset)))
225: return (EFAULT);
226: }
227: if (SCARG(uap, set)) {
228: if (copyin((caddr_t)SCARG(uap, set), (caddr_t)&sigset,
229: sizeof(sigset)))
230: return (EFAULT);
231: mask = hpuxtobsdmask(sigset.sigset[0]);
232: (void) splhigh();
233: switch (SCARG(uap, how)) {
234: case HPUXSIG_BLOCK:
235: p->p_sigmask |= mask &~ sigcantmask;
236: break;
237: case HPUXSIG_UNBLOCK:
238: p->p_sigmask &= ~mask;
239: break;
240: case HPUXSIG_SETMASK:
241: p->p_sigmask = mask &~ sigcantmask;
242: break;
243: default:
244: error = EINVAL;
245: break;
246: }
247: (void) spl0();
248: }
249: return (error);
250: }
251:
252: int
253: hpux_sys_sigpending(p, v, retval)
254: struct proc *p;
255: void *v;
256: register_t *retval;
257: {
258: struct hpux_sys_sigpending_args *uap = v;
259: hpux_sigset_t sigset;
260:
261: sigset.sigset[0] = bsdtohpuxmask(p->p_siglist);
262: return (copyout((caddr_t)&sigset, (caddr_t)SCARG(uap, set),
263: sizeof(sigset)));
264: }
265:
266: int
267: hpux_sys_sigsuspend(p, v, retval)
268: struct proc *p;
269: void *v;
270: register_t *retval;
271: {
272: struct hpux_sys_sigsuspend_args *uap = v;
273: struct sigacts *ps = p->p_sigacts;
274: hpux_sigset_t sigset;
275: int mask;
276:
277: if (copyin((caddr_t)SCARG(uap, set), (caddr_t)&sigset, sizeof(sigset)))
278: return (EFAULT);
279: mask = hpuxtobsdmask(sigset.sigset[0]);
280: ps->ps_oldmask = p->p_sigmask;
281: ps->ps_flags |= SAS_OLDMASK;
282: p->p_sigmask = mask &~ sigcantmask;
283: (void) tsleep((caddr_t)ps, PPAUSE | PCATCH, "pause", 0);
284: /* always return EINTR rather than ERESTART... */
285: return (EINTR);
286: }
287:
288: int
289: hpux_sys_sigaction(p, v, retval)
290: struct proc *p;
291: void *v;
292: register_t *retval;
293: {
294: struct hpux_sys_sigaction_args *uap = v;
295: struct hpux_sigaction action;
296: struct sigacts *ps = p->p_sigacts;
297: struct hpux_sigaction *sa;
298: int sig;
299: int bit;
300:
301: sig = hpuxtobsdsig(SCARG(uap, signo));
302: if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
303: return (EINVAL);
304:
305: sa = &action;
306: if (SCARG(uap, osa)) {
307: sa->sa__handler = ps->ps_sigact[sig];
308: bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask));
309: sa->sa_mask.sigset[0] = bsdtohpuxmask(ps->ps_catchmask[sig]);
310: bit = sigmask(sig);
311: sa->sa_flags = 0;
312: if ((ps->ps_sigonstack & bit) != 0)
313: sa->sa_flags |= HPUXSA_ONSTACK;
314: if ((ps->ps_sigreset & bit) != 0)
315: sa->sa_flags |= HPUXSA_RESETHAND;
316: if (p->p_flag & P_NOCLDSTOP)
317: sa->sa_flags |= HPUXSA_NOCLDSTOP;
318: if (p->p_flag & P_NOCLDWAIT)
319: sa->sa_flags |= HPUXSA_NOCLDWAIT;
320: if (copyout((caddr_t)sa, (caddr_t)SCARG(uap, osa),
321: sizeof (action)))
322: return (EFAULT);
323: }
324: if (SCARG(uap, nsa)) {
325: struct sigaction act;
326:
327: if (copyin((caddr_t)SCARG(uap, nsa), (caddr_t)sa,
328: sizeof (action)))
329: return (EFAULT);
330: if (sig == SIGCONT && sa->sa__handler == SIG_IGN)
331: return (EINVAL);
332: /*
333: * Create a sigaction struct for setsigvec
334: */
335: act.sa_handler = sa->sa__handler;
336: act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]);
337: act.sa_flags = SA_RESTART;
338: if (sa->sa_flags & HPUXSA_ONSTACK)
339: act.sa_flags |= SA_ONSTACK;
340: if (sa->sa_flags & HPUXSA_NOCLDSTOP)
341: act.sa_flags |= SA_NOCLDSTOP;
342: if (sa->sa_flags & HPUXSA_NOCLDWAIT)
343: act.sa_flags |= SA_NOCLDWAIT;
344: setsigvec(p, sig, &act);
345: #if 0
346: /* XXX -- SOUSIG no longer exists, do something here */
347: if (sa->sa_flags & HPUXSA_RESETHAND)
348: p->p_flag |= SOUSIG; /* XXX */
349: #endif
350: }
351: return (0);
352: }
353:
354: /* signal numbers: convert from HPUX to BSD */
355: int
356: hpuxtobsdsig(sig)
357: int sig;
358: {
359: if (--sig < 0 || sig >= NSIG)
360: return(0);
361: return((int)hpuxtobsdsigmap[sig]);
362: }
363:
364: /* signal numbers: convert from BSD to HPUX */
365: int
366: bsdtohpuxsig(sig)
367: int sig;
368: {
369: if (--sig < 0 || sig >= NSIG)
370: return(0);
371: return((int)bsdtohpuxsigmap[sig]);
372: }
373:
374: /* signal masks: convert from HPUX to BSD (not pretty or fast) */
375: int
376: hpuxtobsdmask(mask)
377: int mask;
378: {
379: int nmask, sig, nsig;
380:
381: if (mask == 0 || mask == -1)
382: return(mask);
383: nmask = 0;
384: for (sig = 1; sig < NSIG; sig++)
385: if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig)))
386: nmask |= sigmask(nsig);
387: return(nmask);
388: }
389:
390: int
391: bsdtohpuxmask(mask)
392: int mask;
393: {
394: int nmask, sig, nsig;
395:
396: if (mask == 0 || mask == -1)
397: return(mask);
398: nmask = 0;
399: for (sig = 1; sig < NSIG; sig++)
400: if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig)))
401: nmask |= sigmask(nsig);
402: return(nmask);
403: }
CVSweb