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 * 12*45753Smckusick * from: Utah $Hdr: hpux_sig.c 1.1 90/07/09$ 1341486Smckusick * 14*45753Smckusick * @(#)hpux_sig.c 7.5 (Berkeley) 12/05/90 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * Signal related HPUX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 2341486Smckusick #include "param.h" 2441486Smckusick #include "systm.h" 2544421Skarels #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) 7144421Skarels 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) 8944421Skarels return (error); 9041486Smckusick } 9141486Smckusick if (uap->nsv) { 9243453Shibler error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 9343453Shibler if (error) 9444421Skarels return (error); 9543453Shibler if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 9644421Skarels 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 } 10444421Skarels 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(); 11944421Skarels 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(); 13444421Skarels 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); 14644421Skarels 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 } 16444421Skarels return (kill(p, uap, retval)); 16541486Smckusick } 16641486Smckusick 167*45753Smckusick /* 168*45753Smckusick * The following (sigprocmask, sigpending, sigsuspend, sigaction are 169*45753Smckusick * POSIX calls. Under BSD, the library routine dereferences the sigset_t 170*45753Smckusick * pointers before traping. Not so under HP-UX. 171*45753Smckusick */ 172*45753Smckusick 173*45753Smckusick /* 174*45753Smckusick * Manipulate signal mask. 175*45753Smckusick * Note that we receive new mask, not pointer, 176*45753Smckusick * and return old mask as return value; 177*45753Smckusick * the library stub does the rest. 178*45753Smckusick */ 179*45753Smckusick hpuxsigprocmask(p, uap, retval) 180*45753Smckusick register struct proc *p; 181*45753Smckusick struct args { 182*45753Smckusick int how; 183*45753Smckusick hpuxsigset_t *set; 184*45753Smckusick hpuxsigset_t *oset; 185*45753Smckusick } *uap; 186*45753Smckusick int *retval; 187*45753Smckusick { 188*45753Smckusick int mask, error = 0; 189*45753Smckusick hpuxsigset_t sigset; 190*45753Smckusick 191*45753Smckusick /* 192*45753Smckusick * Copy out old mask first to ensure no errors. 193*45753Smckusick * (proc sigmask should not be changed if call fails for any reason) 194*45753Smckusick */ 195*45753Smckusick if (uap->oset) { 196*45753Smckusick bzero((caddr_t)&sigset, sizeof(sigset)); 197*45753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask); 198*45753Smckusick if (copyout((caddr_t)&sigset, (caddr_t)uap->oset, sizeof(sigset))) 199*45753Smckusick return (EFAULT); 200*45753Smckusick } 201*45753Smckusick if (uap->set) { 202*45753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 203*45753Smckusick return (EFAULT); 204*45753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 205*45753Smckusick (void) splhigh(); 206*45753Smckusick switch (uap->how) { 207*45753Smckusick case HPUXSIG_BLOCK: 208*45753Smckusick p->p_sigmask |= mask &~ sigcantmask; 209*45753Smckusick break; 210*45753Smckusick case HPUXSIG_UNBLOCK: 211*45753Smckusick p->p_sigmask &= ~mask; 212*45753Smckusick break; 213*45753Smckusick case HPUXSIG_SETMASK: 214*45753Smckusick p->p_sigmask = mask &~ sigcantmask; 215*45753Smckusick break; 216*45753Smckusick default: 217*45753Smckusick error = EINVAL; 218*45753Smckusick break; 219*45753Smckusick } 220*45753Smckusick (void) spl0(); 221*45753Smckusick } 222*45753Smckusick return (error); 223*45753Smckusick } 224*45753Smckusick 225*45753Smckusick hpuxsigpending(p, uap, retval) 226*45753Smckusick register struct proc *p; 227*45753Smckusick struct args { 228*45753Smckusick hpuxsigset_t *set; 229*45753Smckusick } *uap; 230*45753Smckusick int *retval; 231*45753Smckusick { 232*45753Smckusick hpuxsigset_t sigset; 233*45753Smckusick 234*45753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sig); 235*45753Smckusick return (copyout((caddr_t)&sigset, (caddr_t)uap->set, sizeof(sigset))); 236*45753Smckusick } 237*45753Smckusick 238*45753Smckusick hpuxsigsuspend(p, uap, retval) 239*45753Smckusick register struct proc *p; 240*45753Smckusick struct args { 241*45753Smckusick hpuxsigset_t *set; 242*45753Smckusick } *uap; 243*45753Smckusick int *retval; 244*45753Smckusick { 245*45753Smckusick hpuxsigset_t sigset; 246*45753Smckusick int mask; 247*45753Smckusick 248*45753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 249*45753Smckusick return (EFAULT); 250*45753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 251*45753Smckusick u.u_oldmask = p->p_sigmask; 252*45753Smckusick p->p_flag |= SOMASK; 253*45753Smckusick p->p_sigmask = mask &~ sigcantmask; 254*45753Smckusick (void) tsleep((caddr_t)&u, PPAUSE | PCATCH, "pause", 0); 255*45753Smckusick /* always return EINTR rather than ERESTART... */ 256*45753Smckusick return (EINTR); 257*45753Smckusick } 258*45753Smckusick 259*45753Smckusick hpuxsigaction(p, uap, retval) 260*45753Smckusick struct proc *p; 261*45753Smckusick register struct args { 262*45753Smckusick int signo; 263*45753Smckusick struct hpuxsigaction *nsa; 264*45753Smckusick struct hpuxsigaction *osa; 265*45753Smckusick } *uap; 266*45753Smckusick int *retval; 267*45753Smckusick { 268*45753Smckusick struct hpuxsigaction action; 269*45753Smckusick register struct hpuxsigaction *sa; 270*45753Smckusick register int sig; 271*45753Smckusick int bit; 272*45753Smckusick 273*45753Smckusick sig = hpuxtobsdsig(uap->signo); 274*45753Smckusick if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 275*45753Smckusick return (EINVAL); 276*45753Smckusick 277*45753Smckusick sa = &action; 278*45753Smckusick if (uap->osa) { 279*45753Smckusick sa->sa_handler = u.u_signal[sig]; 280*45753Smckusick bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask)); 281*45753Smckusick sa->sa_mask.sigset[0] = bsdtohpuxmask(u.u_sigmask[sig]); 282*45753Smckusick bit = sigmask(sig); 283*45753Smckusick sa->sa_flags = 0; 284*45753Smckusick if ((u.u_sigonstack & bit) != 0) 285*45753Smckusick sa->sa_flags |= HPUXSA_ONSTACK; 286*45753Smckusick #if 0 287*45753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 288*45753Smckusick if (p->p_flag & SOUSIG) 289*45753Smckusick sa->sa_flags |= HPUXSA_RESETHAND; /* XXX */ 290*45753Smckusick #endif 291*45753Smckusick if (p->p_flag & SNOCLDSTOP) 292*45753Smckusick sa->sa_flags |= HPUXSA_NOCLDSTOP; 293*45753Smckusick if (copyout((caddr_t)sa, (caddr_t)uap->osa, sizeof (action))) 294*45753Smckusick return (EFAULT); 295*45753Smckusick } 296*45753Smckusick if (uap->nsa) { 297*45753Smckusick struct sigaction act; 298*45753Smckusick 299*45753Smckusick if (copyin((caddr_t)uap->nsa, (caddr_t)sa, sizeof (action))) 300*45753Smckusick return (EFAULT); 301*45753Smckusick if (sig == SIGCONT && sa->sa_handler == SIG_IGN) 302*45753Smckusick return (EINVAL); 303*45753Smckusick /* 304*45753Smckusick * Create a sigaction struct for setsigvec 305*45753Smckusick */ 306*45753Smckusick act.sa_handler = sa->sa_handler; 307*45753Smckusick act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]); 308*45753Smckusick act.sa_flags = 0; 309*45753Smckusick if (sa->sa_flags & HPUXSA_ONSTACK) 310*45753Smckusick act.sa_flags |= SA_ONSTACK; 311*45753Smckusick if (sa->sa_flags & HPUXSA_NOCLDSTOP) 312*45753Smckusick act.sa_flags |= SA_NOCLDSTOP; 313*45753Smckusick setsigvec(p, sig, &act); 314*45753Smckusick #if 0 315*45753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 316*45753Smckusick if (sa->sa_flags & HPUXSA_RESETHAND) 317*45753Smckusick p->p_flag |= SOUSIG; /* XXX */ 318*45753Smckusick #endif 319*45753Smckusick } 320*45753Smckusick return (0); 321*45753Smckusick } 322*45753Smckusick 32343453Shibler ohpuxssig(p, uap, retval) 32443453Shibler struct proc *p; 32543453Shibler struct args { 32641486Smckusick int signo; 32741486Smckusick sig_t fun; 32843453Shibler } *uap; 32943453Shibler int *retval; 33043453Shibler { 33141486Smckusick register int a; 33241486Smckusick struct sigvec vec; 33341486Smckusick register struct sigvec *sv = &vec; 33441486Smckusick 33541486Smckusick a = hpuxtobsdsig(uap->signo); 33641486Smckusick sv->sv_handler = uap->fun; 33741486Smckusick /* 33841486Smckusick * Kill processes trying to use job control facilities 33941486Smckusick * (this'll help us find any vestiges of the old stuff). 34041486Smckusick */ 34141486Smckusick if ((a &~ 0377) || 34241486Smckusick (sv->sv_handler != SIG_DFL && sv->sv_handler != SIG_IGN && 34341486Smckusick ((int)sv->sv_handler) & 1)) { 34441486Smckusick psignal(p, SIGSYS); 34544421Skarels return (0); 34641486Smckusick } 34741486Smckusick if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 34843453Shibler a == SIGCONT && sv->sv_handler == SIG_IGN) 34944421Skarels return (EINVAL); 35041486Smckusick sv->sv_mask = 0; 35141486Smckusick sv->sv_flags = SV_INTERRUPT; 35243453Shibler *retval = (int)u.u_signal[a]; 35343453Shibler setsigvec(p, a, (struct sigaction *)sv); 35441486Smckusick #if 0 35541486Smckusick p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 35641486Smckusick #endif 35744421Skarels return (0); 35841486Smckusick } 35941486Smckusick 36041486Smckusick /* signal numbers: convert from HPUX to BSD */ 36141486Smckusick hpuxtobsdsig(sig) 36241486Smckusick register int sig; 36341486Smckusick { 36441486Smckusick if (--sig < 0 || sig >= NSIG) 36541486Smckusick return(0); 36641486Smckusick return((int)hpuxtobsdsigmap[sig]); 36741486Smckusick } 36841486Smckusick 36941486Smckusick /* signal numbers: convert from BSD to HPUX */ 37041486Smckusick bsdtohpuxsig(sig) 37141486Smckusick register int sig; 37241486Smckusick { 37341486Smckusick if (--sig < 0 || sig >= NSIG) 37441486Smckusick return(0); 37541486Smckusick return((int)bsdtohpuxsigmap[sig]); 37641486Smckusick } 37741486Smckusick 37841486Smckusick /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 37941486Smckusick hpuxtobsdmask(mask) 38041486Smckusick register int mask; 38141486Smckusick { 38241486Smckusick register int nmask, sig, nsig; 38341486Smckusick 38441486Smckusick if (mask == 0 || mask == -1) 38541486Smckusick return(mask); 38641486Smckusick nmask = 0; 38741486Smckusick for (sig = 1; sig < NSIG; sig++) 38841486Smckusick if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 38941486Smckusick nmask |= sigmask(nsig); 39041486Smckusick return(nmask); 39141486Smckusick } 39241486Smckusick 39341486Smckusick bsdtohpuxmask(mask) 39441486Smckusick register int mask; 39541486Smckusick { 39641486Smckusick register int nmask, sig, nsig; 39741486Smckusick 39841486Smckusick if (mask == 0 || mask == -1) 39941486Smckusick return(mask); 40041486Smckusick nmask = 0; 40141486Smckusick for (sig = 1; sig < NSIG; sig++) 40241486Smckusick if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 40341486Smckusick nmask |= sigmask(nsig); 40441486Smckusick return(nmask); 40541486Smckusick } 40641486Smckusick #endif 407