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 * 1253922Shibler * from: Utah $Hdr: hpux_sig.c 1.4 92/01/20$ 1341486Smckusick * 14*55831Shibler * @(#)hpux_sig.c 7.12 (Berkeley) 08/03/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 */ 5554914Storek struct hpuxsigvec_args { 5654914Storek int signo; 5754914Storek struct sigvec *nsv; 5854914Storek struct sigvec *osv; 5954914Storek }; 6043453Shibler hpuxsigvec(p, uap, retval) 6143453Shibler struct proc *p; 6254914Storek register struct hpuxsigvec_args *uap; 6343453Shibler int *retval; 6443453Shibler { 6541486Smckusick struct sigvec vec; 6648476Skarels register struct sigacts *ps = p->p_sigacts; 6741486Smckusick register struct sigvec *sv; 6841486Smckusick register int sig; 6943453Shibler int bit, error; 7041486Smckusick 7141486Smckusick sig = hpuxtobsdsig(uap->signo); 7243453Shibler if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 7344421Skarels return (EINVAL); 7441486Smckusick sv = &vec; 7541486Smckusick if (uap->osv) { 7648476Skarels sv->sv_handler = ps->ps_sigact[sig]; 7748476Skarels sv->sv_mask = ps->ps_catchmask[sig]; 7841486Smckusick bit = sigmask(sig); 7941486Smckusick sv->sv_flags = 0; 8048476Skarels if ((ps->ps_sigonstack & bit) != 0) 8141486Smckusick sv->sv_flags |= SV_ONSTACK; 8248476Skarels if ((ps->ps_sigintr & bit) != 0) 8341486Smckusick sv->sv_flags |= SV_INTERRUPT; 8441486Smckusick #if 0 8541486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 8643453Shibler if (p->p_flag & SOUSIG) 8741486Smckusick sv->sv_flags |= HPUXSV_RESET; /* XXX */ 8841486Smckusick #endif 8943453Shibler error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 9043453Shibler if (error) 9144421Skarels return (error); 9241486Smckusick } 9341486Smckusick if (uap->nsv) { 9443453Shibler error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 9543453Shibler if (error) 9644421Skarels return (error); 9743453Shibler if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 9844421Skarels return (EINVAL); 9948476Skarels sv->sv_flags ^= SA_RESTART; 10043453Shibler setsigvec(p, sig, (struct sigaction *)sv); 10141486Smckusick #if 0 10241486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 10341486Smckusick if (sv->sv_flags & HPUXSV_RESET) 10443453Shibler p->p_flag |= SOUSIG; /* XXX */ 10541486Smckusick #endif 10641486Smckusick } 10744421Skarels return (0); 10841486Smckusick } 10941486Smckusick 11054914Storek struct hpuxsigblock_args { 11154914Storek int mask; 11254914Storek }; 11343453Shibler hpuxsigblock(p, uap, retval) 11443453Shibler register struct proc *p; 11554914Storek struct hpuxsigblock_args *uap; 11643453Shibler int *retval; 11741486Smckusick { 11841486Smckusick 11941486Smckusick (void) splhigh(); 12043453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 12143453Shibler p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask; 12241486Smckusick (void) spl0(); 12344421Skarels return (0); 12441486Smckusick } 12541486Smckusick 12654914Storek struct hpuxsigsetmask_args { 12754914Storek int mask; 12854914Storek }; 12943453Shibler hpuxsigsetmask(p, uap, retval) 13043453Shibler struct proc *p; 13154914Storek struct hpuxsigsetmask_args *uap; 13243453Shibler int *retval; 13341486Smckusick { 13441486Smckusick 13541486Smckusick (void) splhigh(); 13643453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 13743453Shibler p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask; 13841486Smckusick (void) spl0(); 13944421Skarels return (0); 14041486Smckusick } 14141486Smckusick 14254914Storek struct hpuxsigpause_args { 14354914Storek int mask; 14454914Storek }; 14543453Shibler hpuxsigpause(p, uap, retval) 14643453Shibler struct proc *p; 14754914Storek struct hpuxsigpause_args *uap; 14843453Shibler int *retval; 14941486Smckusick { 15041486Smckusick 15141486Smckusick uap->mask = hpuxtobsdmask(uap->mask); 15244421Skarels return (sigsuspend(p, uap, retval)); 15341486Smckusick } 15441486Smckusick 15541486Smckusick /* not totally correct, but close enuf' */ 15654914Storek struct hpuxkill_args { 15754914Storek int pid; 15854914Storek int signo; 15954914Storek }; 16043453Shibler hpuxkill(p, uap, retval) 16143453Shibler struct proc *p; 16254914Storek struct hpuxkill_args *uap; 16343453Shibler int *retval; 16443453Shibler { 16541486Smckusick 16641486Smckusick if (uap->signo) { 16741486Smckusick uap->signo = hpuxtobsdsig(uap->signo); 16841486Smckusick if (uap->signo == 0) 16941486Smckusick uap->signo = NSIG; 17041486Smckusick } 17144421Skarels return (kill(p, uap, retval)); 17241486Smckusick } 17341486Smckusick 17445753Smckusick /* 17545753Smckusick * The following (sigprocmask, sigpending, sigsuspend, sigaction are 17645753Smckusick * POSIX calls. Under BSD, the library routine dereferences the sigset_t 17745753Smckusick * pointers before traping. Not so under HP-UX. 17845753Smckusick */ 17945753Smckusick 18045753Smckusick /* 18145753Smckusick * Manipulate signal mask. 18245753Smckusick * Note that we receive new mask, not pointer, 18345753Smckusick * and return old mask as return value; 18445753Smckusick * the library stub does the rest. 18545753Smckusick */ 18654914Storek struct hpuxsigprocmask_args { 18754914Storek int how; 18854914Storek hpuxsigset_t *set; 18954914Storek hpuxsigset_t *oset; 19054914Storek }; 19145753Smckusick hpuxsigprocmask(p, uap, retval) 19245753Smckusick register struct proc *p; 19354914Storek struct hpuxsigprocmask_args *uap; 19445753Smckusick int *retval; 19545753Smckusick { 19645753Smckusick int mask, error = 0; 19745753Smckusick hpuxsigset_t sigset; 19845753Smckusick 19945753Smckusick /* 20045753Smckusick * Copy out old mask first to ensure no errors. 20145753Smckusick * (proc sigmask should not be changed if call fails for any reason) 20245753Smckusick */ 20345753Smckusick if (uap->oset) { 20445753Smckusick bzero((caddr_t)&sigset, sizeof(sigset)); 20545753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask); 20645753Smckusick if (copyout((caddr_t)&sigset, (caddr_t)uap->oset, sizeof(sigset))) 20745753Smckusick return (EFAULT); 20845753Smckusick } 20945753Smckusick if (uap->set) { 21045753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 21145753Smckusick return (EFAULT); 21245753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 21345753Smckusick (void) splhigh(); 21445753Smckusick switch (uap->how) { 21545753Smckusick case HPUXSIG_BLOCK: 21645753Smckusick p->p_sigmask |= mask &~ sigcantmask; 21745753Smckusick break; 21845753Smckusick case HPUXSIG_UNBLOCK: 21945753Smckusick p->p_sigmask &= ~mask; 22045753Smckusick break; 22145753Smckusick case HPUXSIG_SETMASK: 22245753Smckusick p->p_sigmask = mask &~ sigcantmask; 22345753Smckusick break; 22445753Smckusick default: 22545753Smckusick error = EINVAL; 22645753Smckusick break; 22745753Smckusick } 22845753Smckusick (void) spl0(); 22945753Smckusick } 23045753Smckusick return (error); 23145753Smckusick } 23245753Smckusick 23354914Storek struct hpuxsigpending_args { 23454914Storek hpuxsigset_t *set; 23554914Storek }; 23645753Smckusick hpuxsigpending(p, uap, retval) 23745753Smckusick register struct proc *p; 23854914Storek struct hpuxsigpending_args *uap; 23945753Smckusick int *retval; 24045753Smckusick { 24145753Smckusick hpuxsigset_t sigset; 24245753Smckusick 24345753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sig); 24445753Smckusick return (copyout((caddr_t)&sigset, (caddr_t)uap->set, sizeof(sigset))); 24545753Smckusick } 24645753Smckusick 24754914Storek struct hpuxsigsuspend_args { 24854914Storek hpuxsigset_t *set; 24954914Storek }; 25045753Smckusick hpuxsigsuspend(p, uap, retval) 25145753Smckusick register struct proc *p; 25254914Storek struct hpuxsigsuspend_args *uap; 25345753Smckusick int *retval; 25445753Smckusick { 25548476Skarels register struct sigacts *ps = p->p_sigacts; 25645753Smckusick hpuxsigset_t sigset; 25745753Smckusick int mask; 25845753Smckusick 25945753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 26045753Smckusick return (EFAULT); 26145753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 26248476Skarels ps->ps_oldmask = p->p_sigmask; 26353220Smckusick ps->ps_flags |= SAS_OLDMASK; 26445753Smckusick p->p_sigmask = mask &~ sigcantmask; 26548476Skarels (void) tsleep((caddr_t)ps, PPAUSE | PCATCH, "pause", 0); 26645753Smckusick /* always return EINTR rather than ERESTART... */ 26745753Smckusick return (EINTR); 26845753Smckusick } 26945753Smckusick 27054914Storek struct hpuxsigaction_args { 27154914Storek int signo; 27254914Storek struct hpuxsigaction *nsa; 27354914Storek struct hpuxsigaction *osa; 27454914Storek }; 27545753Smckusick hpuxsigaction(p, uap, retval) 27645753Smckusick struct proc *p; 27754914Storek register struct hpuxsigaction_args *uap; 27845753Smckusick int *retval; 27945753Smckusick { 28045753Smckusick struct hpuxsigaction action; 28148476Skarels register struct sigacts *ps = p->p_sigacts; 28245753Smckusick register struct hpuxsigaction *sa; 28345753Smckusick register int sig; 28445753Smckusick int bit; 28545753Smckusick 28645753Smckusick sig = hpuxtobsdsig(uap->signo); 28745753Smckusick if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 28845753Smckusick return (EINVAL); 28945753Smckusick 29045753Smckusick sa = &action; 29145753Smckusick if (uap->osa) { 29248476Skarels sa->sa_handler = ps->ps_sigact[sig]; 29345753Smckusick bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask)); 29448476Skarels sa->sa_mask.sigset[0] = bsdtohpuxmask(ps->ps_catchmask[sig]); 29545753Smckusick bit = sigmask(sig); 29645753Smckusick sa->sa_flags = 0; 29748476Skarels if ((ps->ps_sigonstack & bit) != 0) 29845753Smckusick sa->sa_flags |= HPUXSA_ONSTACK; 29945753Smckusick #if 0 30045753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 30145753Smckusick if (p->p_flag & SOUSIG) 30245753Smckusick sa->sa_flags |= HPUXSA_RESETHAND; /* XXX */ 30345753Smckusick #endif 30445753Smckusick if (p->p_flag & SNOCLDSTOP) 30545753Smckusick sa->sa_flags |= HPUXSA_NOCLDSTOP; 30645753Smckusick if (copyout((caddr_t)sa, (caddr_t)uap->osa, sizeof (action))) 30745753Smckusick return (EFAULT); 30845753Smckusick } 30945753Smckusick if (uap->nsa) { 31045753Smckusick struct sigaction act; 31145753Smckusick 31245753Smckusick if (copyin((caddr_t)uap->nsa, (caddr_t)sa, sizeof (action))) 31345753Smckusick return (EFAULT); 31445753Smckusick if (sig == SIGCONT && sa->sa_handler == SIG_IGN) 31545753Smckusick return (EINVAL); 31645753Smckusick /* 31745753Smckusick * Create a sigaction struct for setsigvec 31845753Smckusick */ 31945753Smckusick act.sa_handler = sa->sa_handler; 32045753Smckusick act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]); 32148476Skarels act.sa_flags == SA_RESTART; 32245753Smckusick if (sa->sa_flags & HPUXSA_ONSTACK) 32345753Smckusick act.sa_flags |= SA_ONSTACK; 32445753Smckusick if (sa->sa_flags & HPUXSA_NOCLDSTOP) 32545753Smckusick act.sa_flags |= SA_NOCLDSTOP; 32645753Smckusick setsigvec(p, sig, &act); 32745753Smckusick #if 0 32845753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 32945753Smckusick if (sa->sa_flags & HPUXSA_RESETHAND) 33045753Smckusick p->p_flag |= SOUSIG; /* XXX */ 33145753Smckusick #endif 33245753Smckusick } 33345753Smckusick return (0); 33445753Smckusick } 33545753Smckusick 336*55831Shibler #ifdef COMPAT_OHPUX 33754914Storek struct ohpuxssig_args { 33854914Storek int signo; 33954914Storek sig_t fun; 34054914Storek }; 34143453Shibler ohpuxssig(p, uap, retval) 34243453Shibler struct proc *p; 34354914Storek struct ohpuxssig_args *uap; 34443453Shibler int *retval; 34543453Shibler { 34641486Smckusick register int a; 34748476Skarels struct sigaction vec; 34848476Skarels register struct sigaction *sa = &vec; 34941486Smckusick 35041486Smckusick a = hpuxtobsdsig(uap->signo); 35148476Skarels sa->sa_handler = uap->fun; 35241486Smckusick /* 35341486Smckusick * Kill processes trying to use job control facilities 35441486Smckusick * (this'll help us find any vestiges of the old stuff). 35541486Smckusick */ 35641486Smckusick if ((a &~ 0377) || 35748476Skarels (sa->sa_handler != SIG_DFL && sa->sa_handler != SIG_IGN && 35848476Skarels ((int)sa->sa_handler) & 1)) { 35941486Smckusick psignal(p, SIGSYS); 36044421Skarels return (0); 36141486Smckusick } 36241486Smckusick if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 36348476Skarels a == SIGCONT && sa->sa_handler == SIG_IGN) 36444421Skarels return (EINVAL); 36548476Skarels sa->sa_mask = 0; 36648476Skarels sa->sa_flags = 0; 36748476Skarels *retval = (int)p->p_sigacts->ps_sigact[a]; 36848476Skarels setsigvec(p, a, sa); 36941486Smckusick #if 0 37041486Smckusick p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 37141486Smckusick #endif 37244421Skarels return (0); 37341486Smckusick } 374*55831Shibler #endif 37541486Smckusick 37641486Smckusick /* signal numbers: convert from HPUX to BSD */ 37741486Smckusick hpuxtobsdsig(sig) 37841486Smckusick register int sig; 37941486Smckusick { 38041486Smckusick if (--sig < 0 || sig >= NSIG) 38141486Smckusick return(0); 38241486Smckusick return((int)hpuxtobsdsigmap[sig]); 38341486Smckusick } 38441486Smckusick 38541486Smckusick /* signal numbers: convert from BSD to HPUX */ 38641486Smckusick bsdtohpuxsig(sig) 38741486Smckusick register int sig; 38841486Smckusick { 38941486Smckusick if (--sig < 0 || sig >= NSIG) 39041486Smckusick return(0); 39141486Smckusick return((int)bsdtohpuxsigmap[sig]); 39241486Smckusick } 39341486Smckusick 39441486Smckusick /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 39541486Smckusick hpuxtobsdmask(mask) 39641486Smckusick register int mask; 39741486Smckusick { 39841486Smckusick register int nmask, sig, nsig; 39941486Smckusick 40041486Smckusick if (mask == 0 || mask == -1) 40141486Smckusick return(mask); 40241486Smckusick nmask = 0; 40341486Smckusick for (sig = 1; sig < NSIG; sig++) 40441486Smckusick if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 40541486Smckusick nmask |= sigmask(nsig); 40641486Smckusick return(nmask); 40741486Smckusick } 40841486Smckusick 40941486Smckusick bsdtohpuxmask(mask) 41041486Smckusick register int mask; 41141486Smckusick { 41241486Smckusick register int nmask, sig, nsig; 41341486Smckusick 41441486Smckusick if (mask == 0 || mask == -1) 41541486Smckusick return(mask); 41641486Smckusick nmask = 0; 41741486Smckusick for (sig = 1; sig < NSIG; sig++) 41841486Smckusick if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 41941486Smckusick nmask |= sigmask(nsig); 42041486Smckusick return(nmask); 42141486Smckusick } 42241486Smckusick #endif 423