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 * 1245753Smckusick * from: Utah $Hdr: hpux_sig.c 1.1 90/07/09$ 1341486Smckusick * 14*53220Smckusick * @(#)hpux_sig.c 7.9 (Berkeley) 04/20/92 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * Signal related HPUX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 2348476Skarels #include "param.h" 2448476Skarels #include "systm.h" 2548476Skarels #include "kernel.h" 2648476Skarels #include "proc.h" 2748476Skarels #include "signalvar.h" 2845816Smckusick #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; 6548476Skarels register struct sigacts *ps = p->p_sigacts; 6641486Smckusick register struct sigvec *sv; 6741486Smckusick register int sig; 6843453Shibler int bit, error; 6941486Smckusick 7041486Smckusick sig = hpuxtobsdsig(uap->signo); 7143453Shibler if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 7244421Skarels return (EINVAL); 7341486Smckusick sv = &vec; 7441486Smckusick if (uap->osv) { 7548476Skarels sv->sv_handler = ps->ps_sigact[sig]; 7648476Skarels sv->sv_mask = ps->ps_catchmask[sig]; 7741486Smckusick bit = sigmask(sig); 7841486Smckusick sv->sv_flags = 0; 7948476Skarels if ((ps->ps_sigonstack & bit) != 0) 8041486Smckusick sv->sv_flags |= SV_ONSTACK; 8148476Skarels if ((ps->ps_sigintr & bit) != 0) 8241486Smckusick sv->sv_flags |= SV_INTERRUPT; 8341486Smckusick #if 0 8441486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 8543453Shibler if (p->p_flag & SOUSIG) 8641486Smckusick sv->sv_flags |= HPUXSV_RESET; /* XXX */ 8741486Smckusick #endif 8843453Shibler error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 8943453Shibler if (error) 9044421Skarels return (error); 9141486Smckusick } 9241486Smckusick if (uap->nsv) { 9343453Shibler error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 9443453Shibler if (error) 9544421Skarels return (error); 9643453Shibler if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 9744421Skarels return (EINVAL); 9848476Skarels sv->sv_flags ^= SA_RESTART; 9943453Shibler setsigvec(p, sig, (struct sigaction *)sv); 10041486Smckusick #if 0 10141486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 10241486Smckusick if (sv->sv_flags & HPUXSV_RESET) 10343453Shibler p->p_flag |= SOUSIG; /* XXX */ 10441486Smckusick #endif 10541486Smckusick } 10644421Skarels return (0); 10741486Smckusick } 10841486Smckusick 10943453Shibler hpuxsigblock(p, uap, retval) 11043453Shibler register struct proc *p; 11143453Shibler struct args { 11243453Shibler int mask; 11343453Shibler } *uap; 11443453Shibler int *retval; 11541486Smckusick { 11641486Smckusick 11741486Smckusick (void) splhigh(); 11843453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 11943453Shibler p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask; 12041486Smckusick (void) spl0(); 12144421Skarels return (0); 12241486Smckusick } 12341486Smckusick 12443453Shibler hpuxsigsetmask(p, uap, retval) 12543453Shibler struct proc *p; 12643453Shibler struct args { 12743453Shibler int mask; 12843453Shibler } *uap; 12943453Shibler int *retval; 13041486Smckusick { 13141486Smckusick 13241486Smckusick (void) splhigh(); 13343453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 13443453Shibler p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask; 13541486Smckusick (void) spl0(); 13644421Skarels return (0); 13741486Smckusick } 13841486Smckusick 13943453Shibler hpuxsigpause(p, uap, retval) 14043453Shibler struct proc *p; 14143453Shibler struct args { 14243453Shibler int mask; 14343453Shibler } *uap; 14443453Shibler int *retval; 14541486Smckusick { 14641486Smckusick 14741486Smckusick uap->mask = hpuxtobsdmask(uap->mask); 14844421Skarels return (sigsuspend(p, uap, retval)); 14941486Smckusick } 15041486Smckusick 15141486Smckusick /* not totally correct, but close enuf' */ 15243453Shibler hpuxkill(p, uap, retval) 15343453Shibler struct proc *p; 15443453Shibler struct args { 15541486Smckusick int pid; 15641486Smckusick int signo; 15743453Shibler } *uap; 15843453Shibler int *retval; 15943453Shibler { 16041486Smckusick 16141486Smckusick if (uap->signo) { 16241486Smckusick uap->signo = hpuxtobsdsig(uap->signo); 16341486Smckusick if (uap->signo == 0) 16441486Smckusick uap->signo = NSIG; 16541486Smckusick } 16644421Skarels return (kill(p, uap, retval)); 16741486Smckusick } 16841486Smckusick 16945753Smckusick /* 17045753Smckusick * The following (sigprocmask, sigpending, sigsuspend, sigaction are 17145753Smckusick * POSIX calls. Under BSD, the library routine dereferences the sigset_t 17245753Smckusick * pointers before traping. Not so under HP-UX. 17345753Smckusick */ 17445753Smckusick 17545753Smckusick /* 17645753Smckusick * Manipulate signal mask. 17745753Smckusick * Note that we receive new mask, not pointer, 17845753Smckusick * and return old mask as return value; 17945753Smckusick * the library stub does the rest. 18045753Smckusick */ 18145753Smckusick hpuxsigprocmask(p, uap, retval) 18245753Smckusick register struct proc *p; 18345753Smckusick struct args { 18445753Smckusick int how; 18545753Smckusick hpuxsigset_t *set; 18645753Smckusick hpuxsigset_t *oset; 18745753Smckusick } *uap; 18845753Smckusick int *retval; 18945753Smckusick { 19045753Smckusick int mask, error = 0; 19145753Smckusick hpuxsigset_t sigset; 19245753Smckusick 19345753Smckusick /* 19445753Smckusick * Copy out old mask first to ensure no errors. 19545753Smckusick * (proc sigmask should not be changed if call fails for any reason) 19645753Smckusick */ 19745753Smckusick if (uap->oset) { 19845753Smckusick bzero((caddr_t)&sigset, sizeof(sigset)); 19945753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask); 20045753Smckusick if (copyout((caddr_t)&sigset, (caddr_t)uap->oset, sizeof(sigset))) 20145753Smckusick return (EFAULT); 20245753Smckusick } 20345753Smckusick if (uap->set) { 20445753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 20545753Smckusick return (EFAULT); 20645753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 20745753Smckusick (void) splhigh(); 20845753Smckusick switch (uap->how) { 20945753Smckusick case HPUXSIG_BLOCK: 21045753Smckusick p->p_sigmask |= mask &~ sigcantmask; 21145753Smckusick break; 21245753Smckusick case HPUXSIG_UNBLOCK: 21345753Smckusick p->p_sigmask &= ~mask; 21445753Smckusick break; 21545753Smckusick case HPUXSIG_SETMASK: 21645753Smckusick p->p_sigmask = mask &~ sigcantmask; 21745753Smckusick break; 21845753Smckusick default: 21945753Smckusick error = EINVAL; 22045753Smckusick break; 22145753Smckusick } 22245753Smckusick (void) spl0(); 22345753Smckusick } 22445753Smckusick return (error); 22545753Smckusick } 22645753Smckusick 22745753Smckusick hpuxsigpending(p, uap, retval) 22845753Smckusick register struct proc *p; 22945753Smckusick struct args { 23045753Smckusick hpuxsigset_t *set; 23145753Smckusick } *uap; 23245753Smckusick int *retval; 23345753Smckusick { 23445753Smckusick hpuxsigset_t sigset; 23545753Smckusick 23645753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sig); 23745753Smckusick return (copyout((caddr_t)&sigset, (caddr_t)uap->set, sizeof(sigset))); 23845753Smckusick } 23945753Smckusick 24045753Smckusick hpuxsigsuspend(p, uap, retval) 24145753Smckusick register struct proc *p; 24245753Smckusick struct args { 24345753Smckusick hpuxsigset_t *set; 24445753Smckusick } *uap; 24545753Smckusick int *retval; 24645753Smckusick { 24748476Skarels register struct sigacts *ps = p->p_sigacts; 24845753Smckusick hpuxsigset_t sigset; 24945753Smckusick int mask; 25045753Smckusick 25145753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 25245753Smckusick return (EFAULT); 25345753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 25448476Skarels ps->ps_oldmask = p->p_sigmask; 255*53220Smckusick ps->ps_flags |= SAS_OLDMASK; 25645753Smckusick p->p_sigmask = mask &~ sigcantmask; 25748476Skarels (void) tsleep((caddr_t)ps, PPAUSE | PCATCH, "pause", 0); 25845753Smckusick /* always return EINTR rather than ERESTART... */ 25945753Smckusick return (EINTR); 26045753Smckusick } 26145753Smckusick 26245753Smckusick hpuxsigaction(p, uap, retval) 26345753Smckusick struct proc *p; 26445753Smckusick register struct args { 26545753Smckusick int signo; 26645753Smckusick struct hpuxsigaction *nsa; 26745753Smckusick struct hpuxsigaction *osa; 26845753Smckusick } *uap; 26945753Smckusick int *retval; 27045753Smckusick { 27145753Smckusick struct hpuxsigaction action; 27248476Skarels register struct sigacts *ps = p->p_sigacts; 27345753Smckusick register struct hpuxsigaction *sa; 27445753Smckusick register int sig; 27545753Smckusick int bit; 27645753Smckusick 27745753Smckusick sig = hpuxtobsdsig(uap->signo); 27845753Smckusick if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 27945753Smckusick return (EINVAL); 28045753Smckusick 28145753Smckusick sa = &action; 28245753Smckusick if (uap->osa) { 28348476Skarels sa->sa_handler = ps->ps_sigact[sig]; 28445753Smckusick bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask)); 28548476Skarels sa->sa_mask.sigset[0] = bsdtohpuxmask(ps->ps_catchmask[sig]); 28645753Smckusick bit = sigmask(sig); 28745753Smckusick sa->sa_flags = 0; 28848476Skarels if ((ps->ps_sigonstack & bit) != 0) 28945753Smckusick sa->sa_flags |= HPUXSA_ONSTACK; 29045753Smckusick #if 0 29145753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 29245753Smckusick if (p->p_flag & SOUSIG) 29345753Smckusick sa->sa_flags |= HPUXSA_RESETHAND; /* XXX */ 29445753Smckusick #endif 29545753Smckusick if (p->p_flag & SNOCLDSTOP) 29645753Smckusick sa->sa_flags |= HPUXSA_NOCLDSTOP; 29745753Smckusick if (copyout((caddr_t)sa, (caddr_t)uap->osa, sizeof (action))) 29845753Smckusick return (EFAULT); 29945753Smckusick } 30045753Smckusick if (uap->nsa) { 30145753Smckusick struct sigaction act; 30245753Smckusick 30345753Smckusick if (copyin((caddr_t)uap->nsa, (caddr_t)sa, sizeof (action))) 30445753Smckusick return (EFAULT); 30545753Smckusick if (sig == SIGCONT && sa->sa_handler == SIG_IGN) 30645753Smckusick return (EINVAL); 30745753Smckusick /* 30845753Smckusick * Create a sigaction struct for setsigvec 30945753Smckusick */ 31045753Smckusick act.sa_handler = sa->sa_handler; 31145753Smckusick act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]); 31248476Skarels act.sa_flags == SA_RESTART; 31345753Smckusick if (sa->sa_flags & HPUXSA_ONSTACK) 31445753Smckusick act.sa_flags |= SA_ONSTACK; 31545753Smckusick if (sa->sa_flags & HPUXSA_NOCLDSTOP) 31645753Smckusick act.sa_flags |= SA_NOCLDSTOP; 31745753Smckusick setsigvec(p, sig, &act); 31845753Smckusick #if 0 31945753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 32045753Smckusick if (sa->sa_flags & HPUXSA_RESETHAND) 32145753Smckusick p->p_flag |= SOUSIG; /* XXX */ 32245753Smckusick #endif 32345753Smckusick } 32445753Smckusick return (0); 32545753Smckusick } 32645753Smckusick 32743453Shibler ohpuxssig(p, uap, retval) 32843453Shibler struct proc *p; 32943453Shibler struct args { 33041486Smckusick int signo; 33141486Smckusick sig_t fun; 33243453Shibler } *uap; 33343453Shibler int *retval; 33443453Shibler { 33541486Smckusick register int a; 33648476Skarels struct sigaction vec; 33748476Skarels register struct sigaction *sa = &vec; 33841486Smckusick 33941486Smckusick a = hpuxtobsdsig(uap->signo); 34048476Skarels sa->sa_handler = uap->fun; 34141486Smckusick /* 34241486Smckusick * Kill processes trying to use job control facilities 34341486Smckusick * (this'll help us find any vestiges of the old stuff). 34441486Smckusick */ 34541486Smckusick if ((a &~ 0377) || 34648476Skarels (sa->sa_handler != SIG_DFL && sa->sa_handler != SIG_IGN && 34748476Skarels ((int)sa->sa_handler) & 1)) { 34841486Smckusick psignal(p, SIGSYS); 34944421Skarels return (0); 35041486Smckusick } 35141486Smckusick if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 35248476Skarels a == SIGCONT && sa->sa_handler == SIG_IGN) 35344421Skarels return (EINVAL); 35448476Skarels sa->sa_mask = 0; 35548476Skarels sa->sa_flags = 0; 35648476Skarels *retval = (int)p->p_sigacts->ps_sigact[a]; 35748476Skarels setsigvec(p, a, sa); 35841486Smckusick #if 0 35941486Smckusick p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 36041486Smckusick #endif 36144421Skarels return (0); 36241486Smckusick } 36341486Smckusick 36441486Smckusick /* signal numbers: convert from HPUX to BSD */ 36541486Smckusick hpuxtobsdsig(sig) 36641486Smckusick register int sig; 36741486Smckusick { 36841486Smckusick if (--sig < 0 || sig >= NSIG) 36941486Smckusick return(0); 37041486Smckusick return((int)hpuxtobsdsigmap[sig]); 37141486Smckusick } 37241486Smckusick 37341486Smckusick /* signal numbers: convert from BSD to HPUX */ 37441486Smckusick bsdtohpuxsig(sig) 37541486Smckusick register int sig; 37641486Smckusick { 37741486Smckusick if (--sig < 0 || sig >= NSIG) 37841486Smckusick return(0); 37941486Smckusick return((int)bsdtohpuxsigmap[sig]); 38041486Smckusick } 38141486Smckusick 38241486Smckusick /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 38341486Smckusick hpuxtobsdmask(mask) 38441486Smckusick register int mask; 38541486Smckusick { 38641486Smckusick register int nmask, sig, nsig; 38741486Smckusick 38841486Smckusick if (mask == 0 || mask == -1) 38941486Smckusick return(mask); 39041486Smckusick nmask = 0; 39141486Smckusick for (sig = 1; sig < NSIG; sig++) 39241486Smckusick if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 39341486Smckusick nmask |= sigmask(nsig); 39441486Smckusick return(nmask); 39541486Smckusick } 39641486Smckusick 39741486Smckusick bsdtohpuxmask(mask) 39841486Smckusick register int mask; 39941486Smckusick { 40041486Smckusick register int nmask, sig, nsig; 40141486Smckusick 40241486Smckusick if (mask == 0 || mask == -1) 40341486Smckusick return(mask); 40441486Smckusick nmask = 0; 40541486Smckusick for (sig = 1; sig < NSIG; sig++) 40641486Smckusick if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 40741486Smckusick nmask |= sigmask(nsig); 40841486Smckusick return(nmask); 40941486Smckusick } 41041486Smckusick #endif 411