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