1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: Utah $Hdr: hpux_compat.c 1.33 89/08/23$ 13 * 14 * @(#)hpux_sig.c 7.3 (Berkeley) 06/22/90 15 */ 16 17 /* 18 * Signal related HPUX compatibility routines 19 */ 20 21 #ifdef HPUXCOMPAT 22 23 #include "param.h" 24 #include "systm.h" 25 #include "syscontext.h" 26 #include "kernel.h" 27 #include "proc.h" 28 #include "hpux.h" 29 30 /* indexed by HPUX signal number - 1 */ 31 char hpuxtobsdsigmap[NSIG] = { 32 /*01*/ SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGIOT, SIGEMT, SIGFPE, 33 /*09*/ SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, 34 /*17*/ SIGUSR2, SIGCHLD, 0, SIGVTALRM,SIGPROF, SIGIO, SIGWINCH, SIGSTOP, 35 /*25*/ SIGTSTP, SIGCONT,SIGTTIN, SIGTTOU, SIGURG, 0, 0, 0 36 }; 37 38 /* indexed by BSD signal number - 1 */ 39 char bsdtohpuxsigmap[NSIG] = { 40 /*01*/ 1, 2, 3, 4, 5, 6, 7, 8, 41 /*09*/ 9, 10, 11, 12, 13, 14, 15, 29, 42 /*17*/ 24, 25, 26, 18, 27, 28, 22, 0, 43 /*25*/ 0, 20, 21, 23, 0, 16, 17, 0 44 }; 45 46 /* 47 * XXX: In addition to mapping the signal number we also have 48 * to see if the "old" style signal mechinism is needed. 49 * If so, we set the OUSIG flag. This is not really correct 50 * as under HP-UX "old" style handling can be set on a per 51 * signal basis and we are setting it for all signals in one 52 * swell foop. I suspect we can get away with this since I 53 * doubt any program of interest mixes the two semantics. 54 */ 55 hpuxsigvec(p, uap, retval) 56 struct proc *p; 57 register struct args { 58 int signo; 59 struct sigvec *nsv; 60 struct sigvec *osv; 61 } *uap; 62 int *retval; 63 { 64 struct sigvec vec; 65 register struct sigvec *sv; 66 register int sig; 67 int bit, error; 68 69 sig = hpuxtobsdsig(uap->signo); 70 if (sig <= 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP) 71 RETURN (EINVAL); 72 sv = &vec; 73 if (uap->osv) { 74 sv->sv_handler = u.u_signal[sig]; 75 sv->sv_mask = u.u_sigmask[sig]; 76 bit = sigmask(sig); 77 sv->sv_flags = 0; 78 if ((u.u_sigonstack & bit) != 0) 79 sv->sv_flags |= SV_ONSTACK; 80 if ((u.u_sigintr & bit) != 0) 81 sv->sv_flags |= SV_INTERRUPT; 82 #if 0 83 /* XXX -- SOUSIG no longer exists, do something here */ 84 if (p->p_flag & SOUSIG) 85 sv->sv_flags |= HPUXSV_RESET; /* XXX */ 86 #endif 87 error = copyout((caddr_t)sv, (caddr_t)uap->osv, sizeof (vec)); 88 if (error) 89 RETURN (error); 90 } 91 if (uap->nsv) { 92 error = copyin((caddr_t)uap->nsv, (caddr_t)sv, sizeof (vec)); 93 if (error) 94 RETURN (error); 95 if (sig == SIGCONT && sv->sv_handler == SIG_IGN) 96 RETURN (EINVAL); 97 setsigvec(p, sig, (struct sigaction *)sv); 98 #if 0 99 /* XXX -- SOUSIG no longer exists, do something here */ 100 if (sv->sv_flags & HPUXSV_RESET) 101 p->p_flag |= SOUSIG; /* XXX */ 102 #endif 103 } 104 RETURN (0); 105 } 106 107 hpuxsigblock(p, uap, retval) 108 register struct proc *p; 109 struct args { 110 int mask; 111 } *uap; 112 int *retval; 113 { 114 115 (void) splhigh(); 116 *retval = bsdtohpuxmask(p->p_sigmask); 117 p->p_sigmask |= hpuxtobsdmask(uap->mask) &~ sigcantmask; 118 (void) spl0(); 119 RETURN (0); 120 } 121 122 hpuxsigsetmask(p, uap, retval) 123 struct proc *p; 124 struct args { 125 int mask; 126 } *uap; 127 int *retval; 128 { 129 130 (void) splhigh(); 131 *retval = bsdtohpuxmask(p->p_sigmask); 132 p->p_sigmask = hpuxtobsdmask(uap->mask) &~ sigcantmask; 133 (void) spl0(); 134 RETURN (0); 135 } 136 137 hpuxsigpause(p, uap, retval) 138 struct proc *p; 139 struct args { 140 int mask; 141 } *uap; 142 int *retval; 143 { 144 145 uap->mask = hpuxtobsdmask(uap->mask); 146 RETURN (sigsuspend(p, uap, retval)); 147 } 148 149 /* not totally correct, but close enuf' */ 150 hpuxkill(p, uap, retval) 151 struct proc *p; 152 struct args { 153 int pid; 154 int signo; 155 } *uap; 156 int *retval; 157 { 158 159 if (uap->signo) { 160 uap->signo = hpuxtobsdsig(uap->signo); 161 if (uap->signo == 0) 162 uap->signo = NSIG; 163 } 164 RETURN (kill(p, uap, retval)); 165 } 166 167 ohpuxssig(p, uap, retval) 168 struct proc *p; 169 struct args { 170 int signo; 171 sig_t fun; 172 } *uap; 173 int *retval; 174 { 175 register int a; 176 struct sigvec vec; 177 register struct sigvec *sv = &vec; 178 179 a = hpuxtobsdsig(uap->signo); 180 sv->sv_handler = uap->fun; 181 /* 182 * Kill processes trying to use job control facilities 183 * (this'll help us find any vestiges of the old stuff). 184 */ 185 if ((a &~ 0377) || 186 (sv->sv_handler != SIG_DFL && sv->sv_handler != SIG_IGN && 187 ((int)sv->sv_handler) & 1)) { 188 psignal(p, SIGSYS); 189 RETURN (0); 190 } 191 if (a <= 0 || a >= NSIG || a == SIGKILL || a == SIGSTOP || 192 a == SIGCONT && sv->sv_handler == SIG_IGN) 193 RETURN (EINVAL); 194 sv->sv_mask = 0; 195 sv->sv_flags = SV_INTERRUPT; 196 *retval = (int)u.u_signal[a]; 197 setsigvec(p, a, (struct sigaction *)sv); 198 #if 0 199 p->p_flag |= SOUSIG; /* mark as simulating old stuff */ 200 #endif 201 RETURN (0); 202 } 203 204 /* signal numbers: convert from HPUX to BSD */ 205 hpuxtobsdsig(sig) 206 register int sig; 207 { 208 if (--sig < 0 || sig >= NSIG) 209 return(0); 210 return((int)hpuxtobsdsigmap[sig]); 211 } 212 213 /* signal numbers: convert from BSD to HPUX */ 214 bsdtohpuxsig(sig) 215 register int sig; 216 { 217 if (--sig < 0 || sig >= NSIG) 218 return(0); 219 return((int)bsdtohpuxsigmap[sig]); 220 } 221 222 /* signal masks: convert from HPUX to BSD (not pretty or fast) */ 223 hpuxtobsdmask(mask) 224 register int mask; 225 { 226 register int nmask, sig, nsig; 227 228 if (mask == 0 || mask == -1) 229 return(mask); 230 nmask = 0; 231 for (sig = 1; sig < NSIG; sig++) 232 if ((mask & sigmask(sig)) && (nsig = hpuxtobsdsig(sig))) 233 nmask |= sigmask(nsig); 234 return(nmask); 235 } 236 237 bsdtohpuxmask(mask) 238 register int mask; 239 { 240 register int nmask, sig, nsig; 241 242 if (mask == 0 || mask == -1) 243 return(mask); 244 nmask = 0; 245 for (sig = 1; sig < NSIG; sig++) 246 if ((mask & sigmask(sig)) && (nsig = bsdtohpuxsig(sig))) 247 nmask |= sigmask(nsig); 248 return(nmask); 249 } 250 #endif 251