141486Smckusick /* 241486Smckusick * Copyright (c) 1988 University of Utah. 3*63148Sbostic * Copyright (c) 1990, 1993 4*63148Sbostic * The Regents of the University of California. 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*63148Sbostic * @(#)hpux_sig.c 8.1 (Berkeley) 06/10/93 1541486Smckusick */ 1641486Smckusick 1741486Smckusick /* 1841486Smckusick * Signal related HPUX compatibility routines 1941486Smckusick */ 2041486Smckusick 2141486Smckusick #ifdef HPUXCOMPAT 2241486Smckusick 2356506Sbostic #include <sys/param.h> 2456506Sbostic #include <sys/systm.h> 2556506Sbostic #include <sys/kernel.h> 2656506Sbostic #include <sys/proc.h> 2756506Sbostic #include <sys/signalvar.h> 2841486Smckusick 2956506Sbostic #include <hp/hpux/hpux.h> 3056506Sbostic 3141486Smckusick /* indexed by HPUX signal number - 1 */ 3241486Smckusick char hpuxtobsdsigmap[NSIG] = { 3341486Smckusick /*01*/ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGIOT, SIGEMT, SIGFPE, 3441486Smckusick /*09*/ SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, 3541486Smckusick /*17*/ SIGUSR2, SIGCHLD, 0, SIGVTALRM,SIGPROF, SIGIO, SIGWINCH, SIGSTOP, 3641486Smckusick /*25*/ SIGTSTP, SIGCONT,SIGTTIN, SIGTTOU, SIGURG, 0, 0, 0 3741486Smckusick }; 3841486Smckusick 3941486Smckusick /* indexed by BSD signal number - 1 */ 4041486Smckusick char bsdtohpuxsigmap[NSIG] = { 4141486Smckusick /*01*/ 1, 2, 3, 4, 5, 6, 7, 8, 4241486Smckusick /*09*/ 9, 10, 11, 12, 13, 14, 15, 29, 4341486Smckusick /*17*/ 24, 25, 26, 18, 27, 28, 22, 0, 4441486Smckusick /*25*/ 0, 20, 21, 23, 0, 16, 17, 0 4541486Smckusick }; 4641486Smckusick 4741486Smckusick /* 4841486Smckusick * XXX: In addition to mapping the signal number we also have 4941486Smckusick * to see if the "old" style signal mechinism is needed. 5041486Smckusick * If so, we set the OUSIG flag. This is not really correct 5141486Smckusick * as under HP-UX "old" style handling can be set on a per 5241486Smckusick * signal basis and we are setting it for all signals in one 5341486Smckusick * swell foop. I suspect we can get away with this since I 5441486Smckusick * doubt any program of interest mixes the two semantics. 5541486Smckusick */ 5654914Storek struct hpuxsigvec_args { 5754914Storek int signo; 5854914Storek struct sigvec *nsv; 5954914Storek struct sigvec *osv; 6054914Storek }; 6143453Shibler hpuxsigvec(p, uap, retval) 6243453Shibler struct proc *p; 6354914Storek register struct hpuxsigvec_args *uap; 6443453Shibler int *retval; 6543453Shibler { 6641486Smckusick struct sigvec vec; 6748476Skarels register struct sigacts *ps = p->p_sigacts; 6841486Smckusick register struct sigvec *sv; 6941486Smckusick register int sig; 7043453Shibler int bit, error; 7141486Smckusick 7241486Smckusick sig = hpuxtobsdsig(uap->signo); 7343453Shibler if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 7444421Skarels return (EINVAL); 7541486Smckusick sv = &vec; 7641486Smckusick if (uap->osv) { 7748476Skarels sv->sv_handler = ps->ps_sigact[sig]; 7848476Skarels sv->sv_mask = ps->ps_catchmask[sig]; 7941486Smckusick bit = sigmask(sig); 8041486Smckusick sv->sv_flags = 0; 8148476Skarels if ((ps->ps_sigonstack & bit) != 0) 8241486Smckusick sv->sv_flags |= SV_ONSTACK; 8348476Skarels if ((ps->ps_sigintr & bit) != 0) 8441486Smckusick sv->sv_flags |= SV_INTERRUPT; 8541486Smckusick #if 0 8641486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 8743453Shibler if (p->p_flag & SOUSIG) 8841486Smckusick sv->sv_flags |= HPUXSV_RESET; /* XXX */ 8941486Smckusick #endif 9043453Shibler error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 9143453Shibler if (error) 9244421Skarels return (error); 9341486Smckusick } 9441486Smckusick if (uap->nsv) { 9543453Shibler error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 9643453Shibler if (error) 9744421Skarels return (error); 9843453Shibler if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 9944421Skarels return (EINVAL); 10048476Skarels sv->sv_flags ^= SA_RESTART; 10143453Shibler setsigvec(p, sig, (struct sigaction *)sv); 10241486Smckusick #if 0 10341486Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 10441486Smckusick if (sv->sv_flags & HPUXSV_RESET) 10543453Shibler p->p_flag |= SOUSIG; /* XXX */ 10641486Smckusick #endif 10741486Smckusick } 10844421Skarels return (0); 10941486Smckusick } 11041486Smckusick 11154914Storek struct hpuxsigblock_args { 11254914Storek int mask; 11354914Storek }; 11443453Shibler hpuxsigblock(p, uap, retval) 11543453Shibler register struct proc *p; 11654914Storek struct hpuxsigblock_args *uap; 11743453Shibler int *retval; 11841486Smckusick { 11941486Smckusick 12041486Smckusick (void) splhigh(); 12143453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 12243453Shibler p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask; 12341486Smckusick (void) spl0(); 12444421Skarels return (0); 12541486Smckusick } 12641486Smckusick 12754914Storek struct hpuxsigsetmask_args { 12854914Storek int mask; 12954914Storek }; 13043453Shibler hpuxsigsetmask(p, uap, retval) 13143453Shibler struct proc *p; 13254914Storek struct hpuxsigsetmask_args *uap; 13343453Shibler int *retval; 13441486Smckusick { 13541486Smckusick 13641486Smckusick (void) splhigh(); 13743453Shibler *retval = bsdtohpuxmask(p->p_sigmask); 13843453Shibler p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask; 13941486Smckusick (void) spl0(); 14044421Skarels return (0); 14141486Smckusick } 14241486Smckusick 14354914Storek struct hpuxsigpause_args { 14454914Storek int mask; 14554914Storek }; 14643453Shibler hpuxsigpause(p, uap, retval) 14743453Shibler struct proc *p; 14854914Storek struct hpuxsigpause_args *uap; 14943453Shibler int *retval; 15041486Smckusick { 15141486Smckusick 15241486Smckusick uap->mask = hpuxtobsdmask(uap->mask); 15344421Skarels return (sigsuspend(p, uap, retval)); 15441486Smckusick } 15541486Smckusick 15641486Smckusick /* not totally correct, but close enuf' */ 15754914Storek struct hpuxkill_args { 15854914Storek int pid; 15954914Storek int signo; 16054914Storek }; 16143453Shibler hpuxkill(p, uap, retval) 16243453Shibler struct proc *p; 16354914Storek struct hpuxkill_args *uap; 16443453Shibler int *retval; 16543453Shibler { 16641486Smckusick 16741486Smckusick if (uap->signo) { 16841486Smckusick uap->signo = hpuxtobsdsig(uap->signo); 16941486Smckusick if (uap->signo == 0) 17041486Smckusick uap->signo = NSIG; 17141486Smckusick } 17244421Skarels return (kill(p, uap, retval)); 17341486Smckusick } 17441486Smckusick 17545753Smckusick /* 17645753Smckusick * The following (sigprocmask, sigpending, sigsuspend, sigaction are 17745753Smckusick * POSIX calls. Under BSD, the library routine dereferences the sigset_t 17845753Smckusick * pointers before traping. Not so under HP-UX. 17945753Smckusick */ 18045753Smckusick 18145753Smckusick /* 18245753Smckusick * Manipulate signal mask. 18345753Smckusick * Note that we receive new mask, not pointer, 18445753Smckusick * and return old mask as return value; 18545753Smckusick * the library stub does the rest. 18645753Smckusick */ 18754914Storek struct hpuxsigprocmask_args { 18854914Storek int how; 18954914Storek hpuxsigset_t *set; 19054914Storek hpuxsigset_t *oset; 19154914Storek }; 19245753Smckusick hpuxsigprocmask(p, uap, retval) 19345753Smckusick register struct proc *p; 19454914Storek struct hpuxsigprocmask_args *uap; 19545753Smckusick int *retval; 19645753Smckusick { 19745753Smckusick int mask, error = 0; 19845753Smckusick hpuxsigset_t sigset; 19945753Smckusick 20045753Smckusick /* 20145753Smckusick * Copy out old mask first to ensure no errors. 20245753Smckusick * (proc sigmask should not be changed if call fails for any reason) 20345753Smckusick */ 20445753Smckusick if (uap->oset) { 20545753Smckusick bzero((caddr_t)&sigset, sizeof(sigset)); 20645753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sigmask); 20745753Smckusick if (copyout((caddr_t)&sigset, (caddr_t)uap->oset, sizeof(sigset))) 20845753Smckusick return (EFAULT); 20945753Smckusick } 21045753Smckusick if (uap->set) { 21145753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 21245753Smckusick return (EFAULT); 21345753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 21445753Smckusick (void) splhigh(); 21545753Smckusick switch (uap->how) { 21645753Smckusick case HPUXSIG_BLOCK: 21745753Smckusick p->p_sigmask |= mask &~ sigcantmask; 21845753Smckusick break; 21945753Smckusick case HPUXSIG_UNBLOCK: 22045753Smckusick p->p_sigmask &= ~mask; 22145753Smckusick break; 22245753Smckusick case HPUXSIG_SETMASK: 22345753Smckusick p->p_sigmask = mask &~ sigcantmask; 22445753Smckusick break; 22545753Smckusick default: 22645753Smckusick error = EINVAL; 22745753Smckusick break; 22845753Smckusick } 22945753Smckusick (void) spl0(); 23045753Smckusick } 23145753Smckusick return (error); 23245753Smckusick } 23345753Smckusick 23454914Storek struct hpuxsigpending_args { 23554914Storek hpuxsigset_t *set; 23654914Storek }; 23745753Smckusick hpuxsigpending(p, uap, retval) 23845753Smckusick register struct proc *p; 23954914Storek struct hpuxsigpending_args *uap; 24045753Smckusick int *retval; 24145753Smckusick { 24245753Smckusick hpuxsigset_t sigset; 24345753Smckusick 24445753Smckusick sigset.sigset[0] = bsdtohpuxmask(p->p_sig); 24545753Smckusick return (copyout((caddr_t)&sigset, (caddr_t)uap->set, sizeof(sigset))); 24645753Smckusick } 24745753Smckusick 24854914Storek struct hpuxsigsuspend_args { 24954914Storek hpuxsigset_t *set; 25054914Storek }; 25145753Smckusick hpuxsigsuspend(p, uap, retval) 25245753Smckusick register struct proc *p; 25354914Storek struct hpuxsigsuspend_args *uap; 25445753Smckusick int *retval; 25545753Smckusick { 25648476Skarels register struct sigacts *ps = p->p_sigacts; 25745753Smckusick hpuxsigset_t sigset; 25845753Smckusick int mask; 25945753Smckusick 26045753Smckusick if (copyin((caddr_t)uap->set, (caddr_t)&sigset, sizeof(sigset))) 26145753Smckusick return (EFAULT); 26245753Smckusick mask = hpuxtobsdmask(sigset.sigset[0]); 26348476Skarels ps->ps_oldmask = p->p_sigmask; 26453220Smckusick ps->ps_flags |= SAS_OLDMASK; 26545753Smckusick p->p_sigmask = mask &~ sigcantmask; 26648476Skarels (void) tsleep((caddr_t)ps, PPAUSE | PCATCH, "pause", 0); 26745753Smckusick /* always return EINTR rather than ERESTART... */ 26845753Smckusick return (EINTR); 26945753Smckusick } 27045753Smckusick 27154914Storek struct hpuxsigaction_args { 27254914Storek int signo; 27354914Storek struct hpuxsigaction *nsa; 27454914Storek struct hpuxsigaction *osa; 27554914Storek }; 27645753Smckusick hpuxsigaction(p, uap, retval) 27745753Smckusick struct proc *p; 27854914Storek register struct hpuxsigaction_args *uap; 27945753Smckusick int *retval; 28045753Smckusick { 28145753Smckusick struct hpuxsigaction action; 28248476Skarels register struct sigacts *ps = p->p_sigacts; 28345753Smckusick register struct hpuxsigaction *sa; 28445753Smckusick register int sig; 28545753Smckusick int bit; 28645753Smckusick 28745753Smckusick sig = hpuxtobsdsig(uap->signo); 28845753Smckusick if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 28945753Smckusick return (EINVAL); 29045753Smckusick 29145753Smckusick sa = &action; 29245753Smckusick if (uap->osa) { 29348476Skarels sa->sa_handler = ps->ps_sigact[sig]; 29445753Smckusick bzero((caddr_t)&sa->sa_mask, sizeof(sa->sa_mask)); 29548476Skarels sa->sa_mask.sigset[0] = bsdtohpuxmask(ps->ps_catchmask[sig]); 29645753Smckusick bit = sigmask(sig); 29745753Smckusick sa->sa_flags = 0; 29848476Skarels if ((ps->ps_sigonstack & bit) != 0) 29945753Smckusick sa->sa_flags |= HPUXSA_ONSTACK; 30045753Smckusick #if 0 30145753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 30245753Smckusick if (p->p_flag & SOUSIG) 30345753Smckusick sa->sa_flags |= HPUXSA_RESETHAND; /* XXX */ 30445753Smckusick #endif 30545753Smckusick if (p->p_flag & SNOCLDSTOP) 30645753Smckusick sa->sa_flags |= HPUXSA_NOCLDSTOP; 30745753Smckusick if (copyout((caddr_t)sa, (caddr_t)uap->osa, sizeof (action))) 30845753Smckusick return (EFAULT); 30945753Smckusick } 31045753Smckusick if (uap->nsa) { 31145753Smckusick struct sigaction act; 31245753Smckusick 31345753Smckusick if (copyin((caddr_t)uap->nsa, (caddr_t)sa, sizeof (action))) 31445753Smckusick return (EFAULT); 31545753Smckusick if (sig == SIGCONT && sa->sa_handler == SIG_IGN) 31645753Smckusick return (EINVAL); 31745753Smckusick /* 31845753Smckusick * Create a sigaction struct for setsigvec 31945753Smckusick */ 32045753Smckusick act.sa_handler = sa->sa_handler; 32145753Smckusick act.sa_mask = hpuxtobsdmask(sa->sa_mask.sigset[0]); 32248476Skarels act.sa_flags == SA_RESTART; 32345753Smckusick if (sa->sa_flags & HPUXSA_ONSTACK) 32445753Smckusick act.sa_flags |= SA_ONSTACK; 32545753Smckusick if (sa->sa_flags & HPUXSA_NOCLDSTOP) 32645753Smckusick act.sa_flags |= SA_NOCLDSTOP; 32745753Smckusick setsigvec(p, sig, &act); 32845753Smckusick #if 0 32945753Smckusick /* XXX -- SOUSIG no longer exists, do something here */ 33045753Smckusick if (sa->sa_flags & HPUXSA_RESETHAND) 33145753Smckusick p->p_flag |= SOUSIG; /* XXX */ 33245753Smckusick #endif 33345753Smckusick } 33445753Smckusick return (0); 33545753Smckusick } 33645753Smckusick 33755831Shibler #ifdef COMPAT_OHPUX 33854914Storek struct ohpuxssig_args { 33954914Storek int signo; 34054914Storek sig_t fun; 34154914Storek }; 34243453Shibler ohpuxssig(p, uap, retval) 34343453Shibler struct proc *p; 34454914Storek struct ohpuxssig_args *uap; 34543453Shibler int *retval; 34643453Shibler { 34741486Smckusick register int a; 34848476Skarels struct sigaction vec; 34948476Skarels register struct sigaction *sa = &vec; 35041486Smckusick 35141486Smckusick a = hpuxtobsdsig(uap->signo); 35248476Skarels sa->sa_handler = uap->fun; 35341486Smckusick /* 35441486Smckusick * Kill processes trying to use job control facilities 35541486Smckusick * (this'll help us find any vestiges of the old stuff). 35641486Smckusick */ 35741486Smckusick if ((a &~ 0377) || 35848476Skarels (sa->sa_handler != SIG_DFL && sa->sa_handler != SIG_IGN && 35948476Skarels ((int)sa->sa_handler) & 1)) { 36041486Smckusick psignal(p, SIGSYS); 36144421Skarels return (0); 36241486Smckusick } 36341486Smckusick if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 36448476Skarels a == SIGCONT && sa->sa_handler == SIG_IGN) 36544421Skarels return (EINVAL); 36648476Skarels sa->sa_mask = 0; 36748476Skarels sa->sa_flags = 0; 36848476Skarels *retval = (int)p->p_sigacts->ps_sigact[a]; 36948476Skarels setsigvec(p, a, sa); 37041486Smckusick #if 0 37141486Smckusick p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 37241486Smckusick #endif 37344421Skarels return (0); 37441486Smckusick } 37555831Shibler #endif 37641486Smckusick 37741486Smckusick /* signal numbers: convert from HPUX to BSD */ 37841486Smckusick hpuxtobsdsig(sig) 37941486Smckusick register int sig; 38041486Smckusick { 38141486Smckusick if (--sig < 0 || sig >= NSIG) 38241486Smckusick return(0); 38341486Smckusick return((int)hpuxtobsdsigmap[sig]); 38441486Smckusick } 38541486Smckusick 38641486Smckusick /* signal numbers: convert from BSD to HPUX */ 38741486Smckusick bsdtohpuxsig(sig) 38841486Smckusick register int sig; 38941486Smckusick { 39041486Smckusick if (--sig < 0 || sig >= NSIG) 39141486Smckusick return(0); 39241486Smckusick return((int)bsdtohpuxsigmap[sig]); 39341486Smckusick } 39441486Smckusick 39541486Smckusick /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 39641486Smckusick hpuxtobsdmask(mask) 39741486Smckusick register int mask; 39841486Smckusick { 39941486Smckusick register int nmask, sig, nsig; 40041486Smckusick 40141486Smckusick if (mask == 0 || mask == -1) 40241486Smckusick return(mask); 40341486Smckusick nmask = 0; 40441486Smckusick for (sig = 1; sig < NSIG; sig++) 40541486Smckusick if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 40641486Smckusick nmask |= sigmask(nsig); 40741486Smckusick return(nmask); 40841486Smckusick } 40941486Smckusick 41041486Smckusick bsdtohpuxmask(mask) 41141486Smckusick register int mask; 41241486Smckusick { 41341486Smckusick register int nmask, sig, nsig; 41441486Smckusick 41541486Smckusick if (mask == 0 || mask == -1) 41641486Smckusick return(mask); 41741486Smckusick nmask = 0; 41841486Smckusick for (sig = 1; sig < NSIG; sig++) 41941486Smckusick if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 42041486Smckusick nmask |= sigmask(nsig); 42141486Smckusick return(nmask); 42241486Smckusick } 42341486Smckusick #endif 424