141486Smckusick /* 241486Smckusick * Copyright (c) 1988 University of Utah. 341486Smckusick * Copyright (c) 1990 The Regents of the University of California. 441486Smckusick * All rights reserved. 541486Smckusick * 641486Smckusick * This code is derived from software contributed to Berkeley by 741486Smckusick * the Systems Programming Group of the University of Utah Computer 841486Smckusick * Science Department. 941486Smckusick * 1041486Smckusick * %sccs.include.redist.c% 1141486Smckusick * 1241486Smckusick * from: Utah $Hdr: hpux_compat.c 1.33 89/08/23$ 1341486Smckusick * 14*44421Skarels * @(#)hpux_sig.c 7.4 (Berkeley) 06/28/90 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * Signal related HPUX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 2341486Smckusick #include "param.h" 2441486Smckusick #include "systm.h" 25*44421Skarels #include "user.h" 2641486Smckusick #include "kernel.h" 2741486Smckusick #include "proc.h" 2841486Smckusick #include "hpux.h" 2941486Smckusick 3041486Smckusick /* indexed by HPUX signal number - 1 */ 3141486Smckusick char hpuxtobsdsigmap[NSIG] = { 3241486Smckusick /*01*/ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGIOT, SIGEMT, SIGFPE, 3341486Smckusick /*09*/ SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, 3441486Smckusick /*17*/ SIGUSR2, SIGCHLD, 0, SIGVTALRM,SIGPROF, SIGIO, SIGWINCH, SIGSTOP, 3541486Smckusick /*25*/ SIGTSTP, SIGCONT,SIGTTIN, SIGTTOU, SIGURG, 0, 0, 0 3641486Smckusick }; 3741486Smckusick 3841486Smckusick /* indexed by BSD signal number - 1 */ 3941486Smckusick char bsdtohpuxsigmap[NSIG] = { 4041486Smckusick /*01*/ 1, 2, 3, 4, 5, 6, 7, 8, 4141486Smckusick /*09*/ 9, 10, 11, 12, 13, 14, 15, 29, 4241486Smckusick /*17*/ 24, 25, 26, 18, 27, 28, 22, 0, 4341486Smckusick /*25*/ 0, 20, 21, 23, 0, 16, 17, 0 4441486Smckusick }; 4541486Smckusick 4641486Smckusick /* 4741486Smckusick * XXX: In addition to mapping the signal number we also have 4841486Smckusick * to see if the "old" style signal mechinism is needed. 4941486Smckusick * If so, we set the OUSIG flag. This is not really correct 5041486Smckusick * as under HP-UX "old" style handling can be set on a per 5141486Smckusick * signal basis and we are setting it for all signals in one 5241486Smckusick * swell foop. I suspect we can get away with this since I 5341486Smckusick * doubt any program of interest mixes the two semantics. 5441486Smckusick */ 5543453Shibler hpuxsigvec(p, uap, retval) 5643453Shibler struct proc *p; 5743453Shibler register struct args { 5841486Smckusick int signo; 5941486Smckusick struct sigvec *nsv; 6041486Smckusick struct sigvec *osv; 6143453Shibler } *uap; 6243453Shibler int *retval; 6343453Shibler { 6441486Smckusick struct sigvec vec; 6541486Smckusick register struct sigvec *sv; 6641486Smckusick register int sig; 6743453Shibler int bit, error; 6841486Smckusick 6941486Smckusick sig = hpuxtobsdsig(uap->signo); 7043453Shibler if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 71*44421Skarels return (EINVAL); 7241486Smckusick sv = &vec; 7341486Smckusick if (uap->osv) { 7441486Smckusick sv->sv_handler = u.u_signal[sig]; 7541486Smckusick sv->sv_mask = u.u_sigmask[sig]; 7641486Smckusick bit = sigmask(sig); 7741486Smckusick sv->sv_flags = 0; 7841486Smckusick if ((u.u_sigonstack & bit) != 0) 7941486Smckusick sv->sv_flags |= SV_ONSTACK; 8041486Smckusick if ((u.u_sigintr & bit) != 0) 8141486Smckusick sv->sv_flags |= SV_INTERRUPT; 8241486Smckusick #if 0 8341486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 8443453Shibler if (p->p_flag & SOUSIG) 8541486Smckusick sv->sv_flags |= HPUXSV_RESET; /* XXX */ 8641486Smckusick #endif 8743453Shibler error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 8843453Shibler if (error) 89*44421Skarels return (error); 9041486Smckusick } 9141486Smckusick if (uap->nsv) { 9243453Shibler error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 9343453Shibler if (error) 94*44421Skarels return (error); 9543453Shibler if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 96*44421Skarels return (EINVAL); 9743453Shibler setsigvec(p, sig, (struct sigaction *)sv); 9841486Smckusick #if 0 9941486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 10041486Smckusick if (sv->sv_flags & HPUXSV_RESET) 10143453Shibler p->p_flag |= SOUSIG; /* XXX */ 10241486Smckusick #endif 10341486Smckusick } 104*44421Skarels return (0); 10541486Smckusick } 10641486Smckusick 10743453Shibler hpuxsigblock(p, uap, retval) 10843453Shibler register struct proc *p; 10943453Shibler struct args { 11043453Shibler int mask; 11143453Shibler } *uap; 11243453Shibler int *retval; 11341486Smckusick { 11441486Smckusick 11541486Smckusick (void) splhigh(); 11643453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 11743453Shibler p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask; 11841486Smckusick (void) spl0(); 119*44421Skarels return (0); 12041486Smckusick } 12141486Smckusick 12243453Shibler hpuxsigsetmask(p, uap, retval) 12343453Shibler struct proc *p; 12443453Shibler struct args { 12543453Shibler int mask; 12643453Shibler } *uap; 12743453Shibler int *retval; 12841486Smckusick { 12941486Smckusick 13041486Smckusick (void) splhigh(); 13143453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 13243453Shibler p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask; 13341486Smckusick (void) spl0(); 134*44421Skarels return (0); 13541486Smckusick } 13641486Smckusick 13743453Shibler hpuxsigpause(p, uap, retval) 13843453Shibler struct proc *p; 13943453Shibler struct args { 14043453Shibler int mask; 14143453Shibler } *uap; 14243453Shibler int *retval; 14341486Smckusick { 14441486Smckusick 14541486Smckusick uap->mask = hpuxtobsdmask(uap->mask); 146*44421Skarels return (sigsuspend(p, uap, retval)); 14741486Smckusick } 14841486Smckusick 14941486Smckusick /* not totally correct, but close enuf' */ 15043453Shibler hpuxkill(p, uap, retval) 15143453Shibler struct proc *p; 15243453Shibler struct args { 15341486Smckusick int pid; 15441486Smckusick int signo; 15543453Shibler } *uap; 15643453Shibler int *retval; 15743453Shibler { 15841486Smckusick 15941486Smckusick if (uap->signo) { 16041486Smckusick uap->signo = hpuxtobsdsig(uap->signo); 16141486Smckusick if (uap->signo == 0) 16241486Smckusick uap->signo = NSIG; 16341486Smckusick } 164*44421Skarels return (kill(p, uap, retval)); 16541486Smckusick } 16641486Smckusick 16743453Shibler ohpuxssig(p, uap, retval) 16843453Shibler struct proc *p; 16943453Shibler struct args { 17041486Smckusick int signo; 17141486Smckusick sig_t fun; 17243453Shibler } *uap; 17343453Shibler int *retval; 17443453Shibler { 17541486Smckusick register int a; 17641486Smckusick struct sigvec vec; 17741486Smckusick register struct sigvec *sv = &vec; 17841486Smckusick 17941486Smckusick a = hpuxtobsdsig(uap->signo); 18041486Smckusick sv->sv_handler = uap->fun; 18141486Smckusick /* 18241486Smckusick * Kill processes trying to use job control facilities 18341486Smckusick * (this'll help us find any vestiges of the old stuff). 18441486Smckusick */ 18541486Smckusick if ((a &~ 0377) || 18641486Smckusick (sv->sv_handler != SIG_DFL && sv->sv_handler != SIG_IGN && 18741486Smckusick ((int)sv->sv_handler) & 1)) { 18841486Smckusick psignal(p, SIGSYS); 189*44421Skarels return (0); 19041486Smckusick } 19141486Smckusick if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 19243453Shibler a == SIGCONT && sv->sv_handler == SIG_IGN) 193*44421Skarels return (EINVAL); 19441486Smckusick sv->sv_mask = 0; 19541486Smckusick sv->sv_flags = SV_INTERRUPT; 19643453Shibler *retval = (int)u.u_signal[a]; 19743453Shibler setsigvec(p, a, (struct sigaction *)sv); 19841486Smckusick #if 0 19941486Smckusick p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 20041486Smckusick #endif 201*44421Skarels return (0); 20241486Smckusick } 20341486Smckusick 20441486Smckusick /* signal numbers: convert from HPUX to BSD */ 20541486Smckusick hpuxtobsdsig(sig) 20641486Smckusick register int sig; 20741486Smckusick { 20841486Smckusick if (--sig < 0 || sig >= NSIG) 20941486Smckusick return(0); 21041486Smckusick return((int)hpuxtobsdsigmap[sig]); 21141486Smckusick } 21241486Smckusick 21341486Smckusick /* signal numbers: convert from BSD to HPUX */ 21441486Smckusick bsdtohpuxsig(sig) 21541486Smckusick register int sig; 21641486Smckusick { 21741486Smckusick if (--sig < 0 || sig >= NSIG) 21841486Smckusick return(0); 21941486Smckusick return((int)bsdtohpuxsigmap[sig]); 22041486Smckusick } 22141486Smckusick 22241486Smckusick /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 22341486Smckusick hpuxtobsdmask(mask) 22441486Smckusick register int mask; 22541486Smckusick { 22641486Smckusick register int nmask, sig, nsig; 22741486Smckusick 22841486Smckusick if (mask == 0 || mask == -1) 22941486Smckusick return(mask); 23041486Smckusick nmask = 0; 23141486Smckusick for (sig = 1; sig < NSIG; sig++) 23241486Smckusick if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 23341486Smckusick nmask |= sigmask(nsig); 23441486Smckusick return(nmask); 23541486Smckusick } 23641486Smckusick 23741486Smckusick bsdtohpuxmask(mask) 23841486Smckusick register int mask; 23941486Smckusick { 24041486Smckusick register int nmask, sig, nsig; 24141486Smckusick 24241486Smckusick if (mask == 0 || mask == -1) 24341486Smckusick return(mask); 24441486Smckusick nmask = 0; 24541486Smckusick for (sig = 1; sig < NSIG; sig++) 24641486Smckusick if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 24741486Smckusick nmask |= sigmask(nsig); 24841486Smckusick return(nmask); 24941486Smckusick } 25041486Smckusick #endif 251