Annotation of sys/compat/hpux/hpux_sig.c, Revision 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