1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7 /* All Rights Reserved */ 8 9 /* 10 * Copyright (c) 1980 Regents of the University of California. 11 * All rights reserved. The Berkeley Software License Agreement 12 * specifies the terms and conditions for redistribution. 13 */ 14 15 /* 16 * 4.3BSD signal compatibility functions 17 * 18 * the implementation interprets signal masks equal to -1 as "all of the 19 * signals in the signal set", thereby allowing signals with numbers 20 * above 32 to be blocked when referenced in code such as: 21 * 22 * for (i = 0; i < NSIG; i++) 23 * mask |= sigmask(i) 24 */ 25 26 #include <sys/types.h> 27 #include <sys/siginfo.h> 28 #include <ucontext.h> 29 #include <signal.h> 30 #include "signal.h" 31 #include <errno.h> 32 #include <stdio.h> 33 34 #define set2mask(setp) ((setp)->__sigbits[0]) 35 #define mask2set(mask, setp) \ 36 ((mask) == -1 ? sigfillset(setp) : sigemptyset(setp), (((setp)->__sigbits[0]) = (mask))) 37 38 void (*_siguhandler[NSIG])() = { 0 }; 39 40 /* 41 * sigstack is emulated with sigaltstack by guessing an appropriate 42 * value for the stack size - on machines that have stacks that grow 43 * upwards, the ss_sp arguments for both functions mean the same thing, 44 * (the initial stack pointer sigstack() is also the stack base 45 * sigaltstack()), so a "very large" value should be chosen for the 46 * stack size - on machines that have stacks that grow downwards, the 47 * ss_sp arguments mean opposite things, so 0 should be used (hopefully 48 * these machines don't have hardware stack bounds registers that pay 49 * attention to sigaltstack()'s size argument. 50 */ 51 52 #ifdef sun 53 #define SIGSTACKSIZE 0 54 #endif 55 56 57 /* 58 * sigvechandler is the real signal handler installed for all 59 * signals handled in the 4.3BSD compatibility interface - it translates 60 * SVR4 signal hander arguments into 4.3BSD signal handler arguments 61 * and then calls the real handler 62 */ 63 64 static void 65 sigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp) 66 { 67 struct sigcontext sc; 68 int code; 69 char *addr; 70 int i, j; 71 int gwinswitch = 0; 72 73 sc.sc_onstack = ((ucp->uc_stack.ss_flags & SS_ONSTACK) != 0); 74 sc.sc_mask = set2mask(&ucp->uc_sigmask); 75 76 /* 77 * Machine dependent code begins 78 */ 79 sc.sc_sp = ucp->uc_mcontext.gregs[REG_O6]; 80 sc.sc_pc = ucp->uc_mcontext.gregs[REG_PC]; 81 sc.sc_npc = ucp->uc_mcontext.gregs[REG_nPC]; 82 sc.sc_psr = ucp->uc_mcontext.gregs[REG_PSR]; 83 sc.sc_g1 = ucp->uc_mcontext.gregs[REG_G1]; 84 sc.sc_o0 = ucp->uc_mcontext.gregs[REG_O0]; 85 if (ucp->uc_mcontext.gwins != (gwindows_t *)0) { 86 gwinswitch = 1; 87 sc.sc_wbcnt = ucp->uc_mcontext.gwins->wbcnt; 88 for (i = 0; i < MAXWINDOW; i++) { 89 for (j = 0; j < 16; j++) 90 sc.sc_spbuf[i][j] = (int)ucp->uc_mcontext.gwins->spbuf[j]; 91 for (j = 0; j < 8; j++) 92 sc.sc_wbuf[i][j] = ucp->uc_mcontext.gwins->wbuf[i].rw_local[j]; 93 for (j = 0; j < 8; j++) 94 sc.sc_wbuf[i][j+8] = ucp->uc_mcontext.gwins->wbuf[i].rw_in[j]; 95 } 96 } 97 /* 98 * Machine dependent code ends 99 */ 100 101 if (sip != NULL) 102 if ((code = sip->si_code) == BUS_OBJERR) 103 code = SEGV_MAKE_ERR(sip->si_errno); 104 105 if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) 106 if (sip != NULL) 107 addr = (char *)sip->si_addr; 108 else 109 addr = SIG_NOADDR; 110 111 (*_siguhandler[sig])(sig, code, &sc, addr); 112 113 if (sc.sc_onstack) 114 ucp->uc_stack.ss_flags |= SS_ONSTACK; 115 else 116 ucp->uc_stack.ss_flags &= ~SS_ONSTACK; 117 mask2set(sc.sc_mask, &ucp->uc_sigmask); 118 119 /* 120 * Machine dependent code begins 121 */ 122 ucp->uc_mcontext.gregs[REG_O6] = sc.sc_sp; 123 ucp->uc_mcontext.gregs[REG_PC] = sc.sc_pc; 124 ucp->uc_mcontext.gregs[REG_nPC] = sc.sc_npc; 125 ucp->uc_mcontext.gregs[REG_PSR] = sc.sc_psr; 126 ucp->uc_mcontext.gregs[REG_G1] = sc.sc_g1; 127 ucp->uc_mcontext.gregs[REG_O0] = sc.sc_o0; 128 if (gwinswitch == 1) { 129 ucp->uc_mcontext.gwins->wbcnt = sc.sc_wbcnt; 130 for (i = 0; i < MAXWINDOW; i++) { 131 for (j = 0; j < 16; j++) 132 ucp->uc_mcontext.gwins->spbuf[j] = (greg_t *)sc.sc_spbuf[i][j]; 133 for (j = 0; j < 8; j++) 134 ucp->uc_mcontext.gwins->wbuf[i].rw_local[j] = sc.sc_wbuf[i][j]; 135 for (j = 0; j < 8; j++) 136 ucp->uc_mcontext.gwins->wbuf[i].rw_in[j] = sc.sc_wbuf[i][j+8]; 137 } 138 } 139 /* 140 * Machine dependent code ends 141 */ 142 143 setcontext (ucp); 144 } 145 146 int 147 sigsetmask(int mask) 148 { 149 sigset_t oset; 150 sigset_t nset; 151 152 (void) sigprocmask(0, (sigset_t *)0, &nset); 153 mask2set(mask, &nset); 154 (void) sigprocmask(SIG_SETMASK, &nset, &oset); 155 return set2mask(&oset); 156 } 157 158 int 159 sigblock(int mask) 160 { 161 sigset_t oset; 162 sigset_t nset; 163 164 (void) sigprocmask(0, (sigset_t *)0, &nset); 165 mask2set(mask, &nset); 166 (void) sigprocmask(SIG_BLOCK, &nset, &oset); 167 return set2mask(&oset); 168 } 169 170 int 171 sigpause(int mask) 172 { 173 sigset_t set; 174 175 (void) sigprocmask(0, (sigset_t *)0, &set); 176 mask2set(mask, &set); 177 return (sigsuspend(&set)); 178 } 179 180 int 181 sigvec(int sig, struct sigvec *nvec, struct sigvec *ovec) 182 { 183 struct sigaction nact; 184 struct sigaction oact; 185 struct sigaction *nactp; 186 void (*ohandler)(), (*nhandler)(); 187 188 if (sig <= 0 || sig >= NSIG) { 189 errno = EINVAL; 190 return -1; 191 } 192 193 ohandler = _siguhandler[sig]; 194 195 if (nvec) { 196 _sigaction(sig, (struct sigaction *)0, &nact); 197 nhandler = nvec->sv_handler; 198 _siguhandler[sig] = nhandler; 199 if (nhandler != SIG_DFL && nhandler != SIG_IGN) 200 nact.sa_handler = (void (*)())sigvechandler; 201 else 202 nact.sa_handler = nhandler; 203 mask2set(nvec->sv_mask, &nact.sa_mask); 204 /* 205 if ( sig == SIGTSTP || sig == SIGSTOP ) 206 nact.sa_handler = SIG_DFL; */ 207 nact.sa_flags = SA_SIGINFO; 208 if (!(nvec->sv_flags & SV_INTERRUPT)) 209 nact.sa_flags |= SA_RESTART; 210 if (nvec->sv_flags & SV_RESETHAND) 211 nact.sa_flags |= SA_RESETHAND; 212 if (nvec->sv_flags & SV_ONSTACK) 213 nact.sa_flags |= SA_ONSTACK; 214 nactp = &nact; 215 } else 216 nactp = (struct sigaction *)0; 217 218 if (_sigaction(sig, nactp, &oact) < 0) { 219 _siguhandler[sig] = ohandler; 220 return -1; 221 } 222 223 if (ovec) { 224 if (oact.sa_handler == SIG_DFL || oact.sa_handler == SIG_IGN) 225 ovec->sv_handler = oact.sa_handler; 226 else 227 ovec->sv_handler = ohandler; 228 ovec->sv_mask = set2mask(&oact.sa_mask); 229 ovec->sv_flags = 0; 230 if (oact.sa_flags & SA_ONSTACK) 231 ovec->sv_flags |= SV_ONSTACK; 232 if (oact.sa_flags & SA_RESETHAND) 233 ovec->sv_flags |= SV_RESETHAND; 234 if (!(oact.sa_flags & SA_RESTART)) 235 ovec->sv_flags |= SV_INTERRUPT; 236 } 237 238 return 0; 239 } 240 241 242 void (* 243 signal(int s, void (*a)()))() 244 { 245 struct sigvec osv; 246 struct sigvec nsv; 247 static int mask[NSIG]; 248 static int flags[NSIG]; 249 250 nsv.sv_handler = a; 251 nsv.sv_mask = mask[s]; 252 nsv.sv_flags = flags[s]; 253 if (sigvec(s, &nsv, &osv) < 0) 254 return (SIG_ERR); 255 if (nsv.sv_mask != osv.sv_mask || nsv.sv_flags != osv.sv_flags) { 256 mask[s] = nsv.sv_mask = osv.sv_mask; 257 flags[s] = nsv.sv_flags = osv.sv_flags & ~SV_RESETHAND; 258 if (sigvec(s, &nsv, (struct sigvec *)0) < 0) 259 return (SIG_ERR); 260 } 261 return (osv.sv_handler); 262 } 263