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