10Sstevel@tonic-gate /* 2*356Smuffin * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 70Sstevel@tonic-gate /* All Rights Reserved */ 80Sstevel@tonic-gate 90Sstevel@tonic-gate /* 100Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 110Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement 120Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 130Sstevel@tonic-gate */ 140Sstevel@tonic-gate 150Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 160Sstevel@tonic-gate 170Sstevel@tonic-gate /* 180Sstevel@tonic-gate * 4.3BSD signal compatibility functions 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * the implementation interprets signal masks equal to -1 as "all of the 210Sstevel@tonic-gate * signals in the signal set", thereby allowing signals with numbers 220Sstevel@tonic-gate * above 32 to be blocked when referenced in code such as: 230Sstevel@tonic-gate * 240Sstevel@tonic-gate * for (i = 0; i < NSIG; i++) 250Sstevel@tonic-gate * mask |= sigmask(i) 260Sstevel@tonic-gate */ 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <sys/types.h> 290Sstevel@tonic-gate #include <sys/siginfo.h> 300Sstevel@tonic-gate #include <sys/ucontext.h> 310Sstevel@tonic-gate #include <signal.h> 320Sstevel@tonic-gate #include "signal.h" 330Sstevel@tonic-gate #include <errno.h> 340Sstevel@tonic-gate #include <stdio.h> 350Sstevel@tonic-gate 360Sstevel@tonic-gate #define set2mask(setp) ((setp)->__sigbits[0]) 370Sstevel@tonic-gate #define mask2set(mask, setp) \ 380Sstevel@tonic-gate ((mask) == -1 ? sigfillset(setp) : sigemptyset(setp), (((setp)->__sigbits[0]) = (mask))) 390Sstevel@tonic-gate 400Sstevel@tonic-gate void (*_siguhandler[NSIG])() = { 0 }; 410Sstevel@tonic-gate 420Sstevel@tonic-gate /* 430Sstevel@tonic-gate * sigstack is emulated with sigaltstack by guessing an appropriate 440Sstevel@tonic-gate * value for the stack size - on machines that have stacks that grow 450Sstevel@tonic-gate * upwards, the ss_sp arguments for both functions mean the same thing, 460Sstevel@tonic-gate * (the initial stack pointer sigstack() is also the stack base 470Sstevel@tonic-gate * sigaltstack()), so a "very large" value should be chosen for the 480Sstevel@tonic-gate * stack size - on machines that have stacks that grow downwards, the 490Sstevel@tonic-gate * ss_sp arguments mean opposite things, so 0 should be used (hopefully 500Sstevel@tonic-gate * these machines don't have hardware stack bounds registers that pay 510Sstevel@tonic-gate * attention to sigaltstack()'s size argument. 520Sstevel@tonic-gate */ 530Sstevel@tonic-gate 540Sstevel@tonic-gate #ifdef sun 550Sstevel@tonic-gate #define SIGSTACKSIZE 0 560Sstevel@tonic-gate #endif 570Sstevel@tonic-gate 580Sstevel@tonic-gate 590Sstevel@tonic-gate /* 600Sstevel@tonic-gate * sigvechandler is the real signal handler installed for all 610Sstevel@tonic-gate * signals handled in the 4.3BSD compatibility interface - it translates 620Sstevel@tonic-gate * SVR4 signal hander arguments into 4.3BSD signal handler arguments 630Sstevel@tonic-gate * and then calls the real handler 640Sstevel@tonic-gate */ 650Sstevel@tonic-gate 660Sstevel@tonic-gate static void 67*356Smuffin sigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp) 680Sstevel@tonic-gate { 690Sstevel@tonic-gate struct sigcontext sc; 700Sstevel@tonic-gate int code; 710Sstevel@tonic-gate char *addr; 72*356Smuffin int i, j; 730Sstevel@tonic-gate int gwinswitch = 0; 740Sstevel@tonic-gate 750Sstevel@tonic-gate sc.sc_onstack = ((ucp->uc_stack.ss_flags & SS_ONSTACK) != 0); 760Sstevel@tonic-gate sc.sc_mask = set2mask(&ucp->uc_sigmask); 770Sstevel@tonic-gate 780Sstevel@tonic-gate /* 790Sstevel@tonic-gate * Machine dependent code begins 800Sstevel@tonic-gate */ 810Sstevel@tonic-gate sc.sc_sp = ucp->uc_mcontext.gregs[REG_O6]; 820Sstevel@tonic-gate sc.sc_pc = ucp->uc_mcontext.gregs[REG_PC]; 830Sstevel@tonic-gate sc.sc_npc = ucp->uc_mcontext.gregs[REG_nPC]; 840Sstevel@tonic-gate sc.sc_psr = ucp->uc_mcontext.gregs[REG_PSR]; 850Sstevel@tonic-gate sc.sc_g1 = ucp->uc_mcontext.gregs[REG_G1]; 860Sstevel@tonic-gate sc.sc_o0 = ucp->uc_mcontext.gregs[REG_O0]; 870Sstevel@tonic-gate if (ucp->uc_mcontext.gwins != (gwindows_t *)0) { 880Sstevel@tonic-gate gwinswitch = 1; 890Sstevel@tonic-gate sc.sc_wbcnt = ucp->uc_mcontext.gwins->wbcnt; 900Sstevel@tonic-gate for (i = 0; i < MAXWINDOW; i++) { 910Sstevel@tonic-gate for (j = 0; j < 16; j++) 920Sstevel@tonic-gate sc.sc_spbuf[i][j] = (int)ucp->uc_mcontext.gwins->spbuf[j]; 930Sstevel@tonic-gate for (j = 0; j < 8; j++) 940Sstevel@tonic-gate sc.sc_wbuf[i][j] = ucp->uc_mcontext.gwins->wbuf[i].rw_local[j]; 950Sstevel@tonic-gate for (j = 0; j < 8; j++) 960Sstevel@tonic-gate sc.sc_wbuf[i][j+8] = ucp->uc_mcontext.gwins->wbuf[i].rw_in[j]; 970Sstevel@tonic-gate } 980Sstevel@tonic-gate } 990Sstevel@tonic-gate /* 1000Sstevel@tonic-gate * Machine dependent code ends 1010Sstevel@tonic-gate */ 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate if (sip != NULL) 1040Sstevel@tonic-gate if ((code = sip->si_code) == BUS_OBJERR) 1050Sstevel@tonic-gate code = SEGV_MAKE_ERR(sip->si_errno); 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) 1080Sstevel@tonic-gate if (sip != NULL) 1090Sstevel@tonic-gate addr = (char *)sip->si_addr; 1100Sstevel@tonic-gate else 1110Sstevel@tonic-gate addr = SIG_NOADDR; 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate (*_siguhandler[sig])(sig, code, &sc, addr); 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate if (sc.sc_onstack) 1160Sstevel@tonic-gate ucp->uc_stack.ss_flags |= SS_ONSTACK; 1170Sstevel@tonic-gate else 1180Sstevel@tonic-gate ucp->uc_stack.ss_flags &= ~SS_ONSTACK; 1190Sstevel@tonic-gate mask2set(sc.sc_mask, &ucp->uc_sigmask); 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate /* 1220Sstevel@tonic-gate * Machine dependent code begins 1230Sstevel@tonic-gate */ 1240Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_O6] = sc.sc_sp; 1250Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_PC] = sc.sc_pc; 1260Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_nPC] = sc.sc_npc; 1270Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_PSR] = sc.sc_psr; 1280Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_G1] = sc.sc_g1; 1290Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_O0] = sc.sc_o0; 1300Sstevel@tonic-gate if (gwinswitch == 1) { 1310Sstevel@tonic-gate ucp->uc_mcontext.gwins->wbcnt = sc.sc_wbcnt; 1320Sstevel@tonic-gate for (i = 0; i < MAXWINDOW; i++) { 1330Sstevel@tonic-gate for (j = 0; j < 16; j++) 1340Sstevel@tonic-gate ucp->uc_mcontext.gwins->spbuf[j] = (greg_t *)sc.sc_spbuf[i][j]; 1350Sstevel@tonic-gate for (j = 0; j < 8; j++) 1360Sstevel@tonic-gate ucp->uc_mcontext.gwins->wbuf[i].rw_local[j] = sc.sc_wbuf[i][j]; 1370Sstevel@tonic-gate for (j = 0; j < 8; j++) 1380Sstevel@tonic-gate ucp->uc_mcontext.gwins->wbuf[i].rw_in[j] = sc.sc_wbuf[i][j+8]; 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate } 1410Sstevel@tonic-gate /* 1420Sstevel@tonic-gate * Machine dependent code ends 1430Sstevel@tonic-gate */ 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate setcontext (ucp); 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate 148*356Smuffin int 149*356Smuffin sigsetmask(int mask) 1500Sstevel@tonic-gate { 1510Sstevel@tonic-gate sigset_t oset; 1520Sstevel@tonic-gate sigset_t nset; 1530Sstevel@tonic-gate 1540Sstevel@tonic-gate (void) sigprocmask(0, (sigset_t *)0, &nset); 1550Sstevel@tonic-gate mask2set(mask, &nset); 1560Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &nset, &oset); 1570Sstevel@tonic-gate return set2mask(&oset); 1580Sstevel@tonic-gate } 1590Sstevel@tonic-gate 160*356Smuffin int 161*356Smuffin sigblock(int mask) 1620Sstevel@tonic-gate { 1630Sstevel@tonic-gate sigset_t oset; 1640Sstevel@tonic-gate sigset_t nset; 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate (void) sigprocmask(0, (sigset_t *)0, &nset); 1670Sstevel@tonic-gate mask2set(mask, &nset); 1680Sstevel@tonic-gate (void) sigprocmask(SIG_BLOCK, &nset, &oset); 1690Sstevel@tonic-gate return set2mask(&oset); 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate 172*356Smuffin int 173*356Smuffin sigpause(int mask) 1740Sstevel@tonic-gate { 1750Sstevel@tonic-gate sigset_t set; 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate (void) sigprocmask(0, (sigset_t *)0, &set); 1780Sstevel@tonic-gate mask2set(mask, &set); 1790Sstevel@tonic-gate return (sigsuspend(&set)); 1800Sstevel@tonic-gate } 1810Sstevel@tonic-gate 182*356Smuffin int 183*356Smuffin sigvec(int sig, struct sigvec *nvec, struct sigvec *ovec) 1840Sstevel@tonic-gate { 1850Sstevel@tonic-gate struct sigaction nact; 1860Sstevel@tonic-gate struct sigaction oact; 1870Sstevel@tonic-gate struct sigaction *nactp; 1880Sstevel@tonic-gate void (*ohandler)(), (*nhandler)(); 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate if (sig <= 0 || sig >= NSIG) { 1910Sstevel@tonic-gate errno = EINVAL; 1920Sstevel@tonic-gate return -1; 1930Sstevel@tonic-gate } 1940Sstevel@tonic-gate 1950Sstevel@tonic-gate ohandler = _siguhandler[sig]; 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate if (nvec) { 1980Sstevel@tonic-gate _sigaction(sig, (struct sigaction *)0, &nact); 1990Sstevel@tonic-gate nhandler = nvec->sv_handler; 2000Sstevel@tonic-gate _siguhandler[sig] = nhandler; 2010Sstevel@tonic-gate if (nhandler != SIG_DFL && nhandler != SIG_IGN) 2020Sstevel@tonic-gate nact.sa_handler = (void (*)())sigvechandler; 2030Sstevel@tonic-gate else 2040Sstevel@tonic-gate nact.sa_handler = nhandler; 2050Sstevel@tonic-gate mask2set(nvec->sv_mask, &nact.sa_mask); 2060Sstevel@tonic-gate /* 2070Sstevel@tonic-gate if ( sig == SIGTSTP || sig == SIGSTOP ) 2080Sstevel@tonic-gate nact.sa_handler = SIG_DFL; */ 2090Sstevel@tonic-gate nact.sa_flags = SA_SIGINFO; 2100Sstevel@tonic-gate if (!(nvec->sv_flags & SV_INTERRUPT)) 2110Sstevel@tonic-gate nact.sa_flags |= SA_RESTART; 2120Sstevel@tonic-gate if (nvec->sv_flags & SV_RESETHAND) 2130Sstevel@tonic-gate nact.sa_flags |= SA_RESETHAND; 2140Sstevel@tonic-gate if (nvec->sv_flags & SV_ONSTACK) 2150Sstevel@tonic-gate nact.sa_flags |= SA_ONSTACK; 2160Sstevel@tonic-gate nactp = &nact; 2170Sstevel@tonic-gate } else 2180Sstevel@tonic-gate nactp = (struct sigaction *)0; 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate if (_sigaction(sig, nactp, &oact) < 0) { 2210Sstevel@tonic-gate _siguhandler[sig] = ohandler; 2220Sstevel@tonic-gate return -1; 2230Sstevel@tonic-gate } 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate if (ovec) { 2260Sstevel@tonic-gate if (oact.sa_handler == SIG_DFL || oact.sa_handler == SIG_IGN) 2270Sstevel@tonic-gate ovec->sv_handler = oact.sa_handler; 2280Sstevel@tonic-gate else 2290Sstevel@tonic-gate ovec->sv_handler = ohandler; 2300Sstevel@tonic-gate ovec->sv_mask = set2mask(&oact.sa_mask); 2310Sstevel@tonic-gate ovec->sv_flags = 0; 2320Sstevel@tonic-gate if (oact.sa_flags & SA_ONSTACK) 2330Sstevel@tonic-gate ovec->sv_flags |= SV_ONSTACK; 2340Sstevel@tonic-gate if (oact.sa_flags & SA_RESETHAND) 2350Sstevel@tonic-gate ovec->sv_flags |= SV_RESETHAND; 2360Sstevel@tonic-gate if (!(oact.sa_flags & SA_RESTART)) 2370Sstevel@tonic-gate ovec->sv_flags |= SV_INTERRUPT; 2380Sstevel@tonic-gate } 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate return 0; 2410Sstevel@tonic-gate } 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate 2440Sstevel@tonic-gate void (* 245*356Smuffin signal(int s, void (*a)()))() 2460Sstevel@tonic-gate { 2470Sstevel@tonic-gate struct sigvec osv; 2480Sstevel@tonic-gate struct sigvec nsv; 2490Sstevel@tonic-gate static int mask[NSIG]; 2500Sstevel@tonic-gate static int flags[NSIG]; 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate nsv.sv_handler = a; 2530Sstevel@tonic-gate nsv.sv_mask = mask[s]; 2540Sstevel@tonic-gate nsv.sv_flags = flags[s]; 2550Sstevel@tonic-gate if (sigvec(s, &nsv, &osv) < 0) 2560Sstevel@tonic-gate return (SIG_ERR); 2570Sstevel@tonic-gate if (nsv.sv_mask != osv.sv_mask || nsv.sv_flags != osv.sv_flags) { 2580Sstevel@tonic-gate mask[s] = nsv.sv_mask = osv.sv_mask; 2590Sstevel@tonic-gate flags[s] = nsv.sv_flags = osv.sv_flags & ~SV_RESETHAND; 2600Sstevel@tonic-gate if (sigvec(s, &nsv, (struct sigvec *)0) < 0) 2610Sstevel@tonic-gate return (SIG_ERR); 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate return (osv.sv_handler); 2640Sstevel@tonic-gate } 265