1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28*0Sstevel@tonic-gate /* All Rights Reserved */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate /* 31*0Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 4.3 BSD 32*0Sstevel@tonic-gate * under license from the Regents of the University of California. 33*0Sstevel@tonic-gate */ 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate /* 36*0Sstevel@tonic-gate * 4.3BSD signal compatibility functions 37*0Sstevel@tonic-gate * 38*0Sstevel@tonic-gate * the implementation interprets signal masks equal to -1 as "all of the 39*0Sstevel@tonic-gate * signals in the signal set", thereby allowing signals with numbers 40*0Sstevel@tonic-gate * above 32 to be blocked when referenced in code such as: 41*0Sstevel@tonic-gate * 42*0Sstevel@tonic-gate * for (i = 0; i < NSIG; i++) 43*0Sstevel@tonic-gate * mask |= sigmask(i) 44*0Sstevel@tonic-gate */ 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate #include <sys/types.h> 49*0Sstevel@tonic-gate #include <ucontext.h> 50*0Sstevel@tonic-gate #include <signal.h> 51*0Sstevel@tonic-gate #include <errno.h> 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate #undef BUS_OBJERR /* namespace conflict */ 54*0Sstevel@tonic-gate #include <sys/siginfo.h> 55*0Sstevel@tonic-gate #include "libc.h" 56*0Sstevel@tonic-gate 57*0Sstevel@tonic-gate #pragma weak sigvechandler = _sigvechandler 58*0Sstevel@tonic-gate #pragma weak sigsetmask = _sigsetmask 59*0Sstevel@tonic-gate #pragma weak sigblock = _sigblock 60*0Sstevel@tonic-gate #pragma weak sigpause = usigpause 61*0Sstevel@tonic-gate #pragma weak sigvec = _sigvec 62*0Sstevel@tonic-gate #pragma weak sigstack = _sigstack 63*0Sstevel@tonic-gate #pragma weak signal = usignal 64*0Sstevel@tonic-gate #pragma weak siginterrupt = _siginterrupt 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate #define set2mask(setp) ((setp)->__sigbits[0]) 67*0Sstevel@tonic-gate #define mask2set(mask, setp) \ 68*0Sstevel@tonic-gate ((mask) == -1 ? sigfillset(setp) : \ 69*0Sstevel@tonic-gate (sigemptyset(setp), (((setp)->__sigbits[0]) = (int)(mask)))) 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate void (*_siguhandler[NSIG])() = { 0 }; 72*0Sstevel@tonic-gate 73*0Sstevel@tonic-gate /* forward declarations */ 74*0Sstevel@tonic-gate int ucbsigsetmask(int); 75*0Sstevel@tonic-gate int ucbsigblock(int); 76*0Sstevel@tonic-gate int ucbsigvec(int, struct sigvec *, struct sigvec *); 77*0Sstevel@tonic-gate int ucbsigpause(int); 78*0Sstevel@tonic-gate int ucbsiginterrupt(int, int); 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate /* 81*0Sstevel@tonic-gate * sigvechandler is the real signal handler installed for all 82*0Sstevel@tonic-gate * signals handled in the 4.3BSD compatibility interface - it translates 83*0Sstevel@tonic-gate * SVR4 signal hander arguments into 4.3BSD signal handler arguments 84*0Sstevel@tonic-gate * and then calls the real handler 85*0Sstevel@tonic-gate */ 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate void 88*0Sstevel@tonic-gate _sigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp) 89*0Sstevel@tonic-gate { 90*0Sstevel@tonic-gate static void ucbsigvechandler(); 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate ucbsigvechandler(sig, sip, ucp); 93*0Sstevel@tonic-gate } 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate static void 96*0Sstevel@tonic-gate ucbsigvechandler(int sig, siginfo_t *sip, ucontext_t *ucp) 97*0Sstevel@tonic-gate { 98*0Sstevel@tonic-gate struct sigcontext sc; 99*0Sstevel@tonic-gate int code; 100*0Sstevel@tonic-gate char *addr; 101*0Sstevel@tonic-gate int i, j; 102*0Sstevel@tonic-gate int gwinswitch = 0; 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate sc.sc_onstack = ((ucp->uc_stack.ss_flags & SS_ONSTACK) != 0); 105*0Sstevel@tonic-gate sc.sc_mask = set2mask(&ucp->uc_sigmask); 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate #if defined(__amd64) 108*0Sstevel@tonic-gate sc.sc_sp = (long)ucp->uc_mcontext.gregs[REG_RSP]; 109*0Sstevel@tonic-gate sc.sc_pc = (long)ucp->uc_mcontext.gregs[REG_RIP]; 110*0Sstevel@tonic-gate sc.sc_ps = (long)ucp->uc_mcontext.gregs[REG_RFL]; 111*0Sstevel@tonic-gate sc.sc_r0 = (long)ucp->uc_mcontext.gregs[REG_RAX]; 112*0Sstevel@tonic-gate sc.sc_r1 = (long)ucp->uc_mcontext.gregs[REG_RDX]; 113*0Sstevel@tonic-gate #else 114*0Sstevel@tonic-gate sc.sc_sp = (int)ucp->uc_mcontext.gregs[UESP]; 115*0Sstevel@tonic-gate sc.sc_pc = (int)ucp->uc_mcontext.gregs[EIP]; 116*0Sstevel@tonic-gate sc.sc_ps = (int)ucp->uc_mcontext.gregs[EFL]; 117*0Sstevel@tonic-gate sc.sc_r0 = (int)ucp->uc_mcontext.gregs[EAX]; 118*0Sstevel@tonic-gate sc.sc_r1 = (int)ucp->uc_mcontext.gregs[EDX]; 119*0Sstevel@tonic-gate #endif 120*0Sstevel@tonic-gate 121*0Sstevel@tonic-gate /* 122*0Sstevel@tonic-gate * Translate signal codes from new to old. 123*0Sstevel@tonic-gate * /usr/include/sys/siginfo.h contains new codes. 124*0Sstevel@tonic-gate * /usr/ucbinclude/sys/signal.h contains old codes. 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate code = 0; 127*0Sstevel@tonic-gate addr = SIG_NOADDR; 128*0Sstevel@tonic-gate if (sip != NULL && SI_FROMKERNEL(sip)) { 129*0Sstevel@tonic-gate addr = sip->si_addr; 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate switch (sig) { 132*0Sstevel@tonic-gate case SIGILL: 133*0Sstevel@tonic-gate case SIGFPE: 134*0Sstevel@tonic-gate code = ILL_ILLINSTR_FAULT; 135*0Sstevel@tonic-gate break; 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate case SIGBUS: 138*0Sstevel@tonic-gate switch (sip->si_code) { 139*0Sstevel@tonic-gate case BUS_ADRALN: 140*0Sstevel@tonic-gate code = BUS_ALIGN; 141*0Sstevel@tonic-gate break; 142*0Sstevel@tonic-gate case BUS_ADRERR: 143*0Sstevel@tonic-gate code = BUS_HWERR; 144*0Sstevel@tonic-gate break; 145*0Sstevel@tonic-gate default: /* BUS_OBJERR */ 146*0Sstevel@tonic-gate code = FC_MAKE_ERR(sip->si_errno); 147*0Sstevel@tonic-gate break; 148*0Sstevel@tonic-gate } 149*0Sstevel@tonic-gate break; 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate case SIGSEGV: 152*0Sstevel@tonic-gate switch (sip->si_code) { 153*0Sstevel@tonic-gate case SEGV_MAPERR: 154*0Sstevel@tonic-gate code = SEGV_NOMAP; 155*0Sstevel@tonic-gate break; 156*0Sstevel@tonic-gate case SEGV_ACCERR: 157*0Sstevel@tonic-gate code = SEGV_PROT; 158*0Sstevel@tonic-gate break; 159*0Sstevel@tonic-gate default: 160*0Sstevel@tonic-gate code = FC_MAKE_ERR(sip->si_errno); 161*0Sstevel@tonic-gate break; 162*0Sstevel@tonic-gate } 163*0Sstevel@tonic-gate break; 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate default: 166*0Sstevel@tonic-gate addr = SIG_NOADDR; 167*0Sstevel@tonic-gate break; 168*0Sstevel@tonic-gate } 169*0Sstevel@tonic-gate } 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate (*_siguhandler[sig])(sig, code, &sc, addr); 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate if (sc.sc_onstack) 174*0Sstevel@tonic-gate ucp->uc_stack.ss_flags |= SS_ONSTACK; 175*0Sstevel@tonic-gate else 176*0Sstevel@tonic-gate ucp->uc_stack.ss_flags &= ~SS_ONSTACK; 177*0Sstevel@tonic-gate mask2set(sc.sc_mask, &ucp->uc_sigmask); 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate #if defined(__amd64) 180*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_RSP] = (long)sc.sc_sp; 181*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_RIP] = (long)sc.sc_pc; 182*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_RFL] = (long)sc.sc_ps; 183*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_RAX] = (long)sc.sc_r0; 184*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[REG_RDX] = (long)sc.sc_r1; 185*0Sstevel@tonic-gate #else 186*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[UESP] = (int)sc.sc_sp; 187*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[EIP] = (int)sc.sc_pc; 188*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[EFL] = (int)sc.sc_ps; 189*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[EAX] = (int)sc.sc_r0; 190*0Sstevel@tonic-gate ucp->uc_mcontext.gregs[EDX] = (int)sc.sc_r1; 191*0Sstevel@tonic-gate #endif 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate setcontext(ucp); 194*0Sstevel@tonic-gate } 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate int 197*0Sstevel@tonic-gate _sigsetmask(int mask) 198*0Sstevel@tonic-gate { 199*0Sstevel@tonic-gate return (ucbsigsetmask(mask)); 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate int 203*0Sstevel@tonic-gate ucbsigsetmask(int mask) 204*0Sstevel@tonic-gate { 205*0Sstevel@tonic-gate sigset_t oset; 206*0Sstevel@tonic-gate sigset_t nset; 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate (void) sigprocmask(0, (sigset_t *)0, &nset); 209*0Sstevel@tonic-gate mask2set(mask, &nset); 210*0Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &nset, &oset); 211*0Sstevel@tonic-gate return (set2mask(&oset)); 212*0Sstevel@tonic-gate } 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate int 215*0Sstevel@tonic-gate _sigblock(int mask) 216*0Sstevel@tonic-gate { 217*0Sstevel@tonic-gate return (ucbsigblock(mask)); 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate int 221*0Sstevel@tonic-gate ucbsigblock(int mask) 222*0Sstevel@tonic-gate { 223*0Sstevel@tonic-gate sigset_t oset; 224*0Sstevel@tonic-gate sigset_t nset; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate (void) sigprocmask(0, (sigset_t *)0, &nset); 227*0Sstevel@tonic-gate mask2set(mask, &nset); 228*0Sstevel@tonic-gate (void) sigprocmask(SIG_BLOCK, &nset, &oset); 229*0Sstevel@tonic-gate return (set2mask(&oset)); 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate int 233*0Sstevel@tonic-gate usigpause(int mask) 234*0Sstevel@tonic-gate { 235*0Sstevel@tonic-gate return (ucbsigpause(mask)); 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate int 239*0Sstevel@tonic-gate ucbsigpause(int mask) 240*0Sstevel@tonic-gate { 241*0Sstevel@tonic-gate sigset_t set, oset; 242*0Sstevel@tonic-gate int ret; 243*0Sstevel@tonic-gate 244*0Sstevel@tonic-gate (void) sigprocmask(0, (sigset_t *)0, &set); 245*0Sstevel@tonic-gate oset = set; 246*0Sstevel@tonic-gate mask2set(mask, &set); 247*0Sstevel@tonic-gate ret = sigsuspend(&set); 248*0Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &oset, (sigset_t *)0); 249*0Sstevel@tonic-gate return (ret); 250*0Sstevel@tonic-gate } 251*0Sstevel@tonic-gate 252*0Sstevel@tonic-gate int 253*0Sstevel@tonic-gate _sigvec(int sig, struct sigvec *nvec, struct sigvec *ovec) 254*0Sstevel@tonic-gate { 255*0Sstevel@tonic-gate return (ucbsigvec(sig, nvec, ovec)); 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate int 259*0Sstevel@tonic-gate ucbsigvec(int sig, struct sigvec *nvec, struct sigvec *ovec) 260*0Sstevel@tonic-gate { 261*0Sstevel@tonic-gate struct sigaction nact; 262*0Sstevel@tonic-gate struct sigaction oact; 263*0Sstevel@tonic-gate struct sigaction *nactp; 264*0Sstevel@tonic-gate void (*ohandler)(), (*nhandler)(); 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate if (sig <= 0 || sig >= NSIG) { 267*0Sstevel@tonic-gate errno = EINVAL; 268*0Sstevel@tonic-gate return (-1); 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate if ((intptr_t)ovec == -1 || (intptr_t)nvec == -1) { 272*0Sstevel@tonic-gate errno = EFAULT; 273*0Sstevel@tonic-gate return (-1); 274*0Sstevel@tonic-gate } 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate ohandler = _siguhandler[sig]; 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate if (nvec) { 279*0Sstevel@tonic-gate _sigaction(sig, (struct sigaction *)0, &nact); 280*0Sstevel@tonic-gate nhandler = nvec->sv_handler; 281*0Sstevel@tonic-gate /* 282*0Sstevel@tonic-gate * To be compatible with the behavior of SunOS 4.x: 283*0Sstevel@tonic-gate * If the new signal handler is SIG_IGN or SIG_DFL, 284*0Sstevel@tonic-gate * do not change the signal's entry in the handler array. 285*0Sstevel@tonic-gate * This allows a child of vfork(2) to set signal handlers 286*0Sstevel@tonic-gate * to SIG_IGN or SIG_DFL without affecting the parent. 287*0Sstevel@tonic-gate */ 288*0Sstevel@tonic-gate if (nhandler != SIG_DFL && nhandler != SIG_IGN) { 289*0Sstevel@tonic-gate _siguhandler[sig] = nhandler; 290*0Sstevel@tonic-gate nact.sa_handler = (void (*)())ucbsigvechandler; 291*0Sstevel@tonic-gate } else { 292*0Sstevel@tonic-gate nact.sa_handler = nhandler; 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate mask2set(nvec->sv_mask, &nact.sa_mask); 295*0Sstevel@tonic-gate if (sig == SIGKILL || sig == SIGSTOP) 296*0Sstevel@tonic-gate nact.sa_handler = SIG_DFL; 297*0Sstevel@tonic-gate nact.sa_flags = SA_SIGINFO; 298*0Sstevel@tonic-gate if (!(nvec->sv_flags & SV_INTERRUPT)) 299*0Sstevel@tonic-gate nact.sa_flags |= SA_RESTART; 300*0Sstevel@tonic-gate if (nvec->sv_flags & SV_RESETHAND) 301*0Sstevel@tonic-gate nact.sa_flags |= SA_RESETHAND; 302*0Sstevel@tonic-gate if (nvec->sv_flags & SV_ONSTACK) 303*0Sstevel@tonic-gate nact.sa_flags |= SA_ONSTACK; 304*0Sstevel@tonic-gate nactp = &nact; 305*0Sstevel@tonic-gate } else 306*0Sstevel@tonic-gate nactp = (struct sigaction *)0; 307*0Sstevel@tonic-gate 308*0Sstevel@tonic-gate if (_sigaction(sig, nactp, &oact) < 0) { 309*0Sstevel@tonic-gate _siguhandler[sig] = ohandler; 310*0Sstevel@tonic-gate return (-1); 311*0Sstevel@tonic-gate } 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate if (ovec) { 314*0Sstevel@tonic-gate if (oact.sa_handler == SIG_DFL || oact.sa_handler == SIG_IGN) 315*0Sstevel@tonic-gate ovec->sv_handler = oact.sa_handler; 316*0Sstevel@tonic-gate else 317*0Sstevel@tonic-gate ovec->sv_handler = ohandler; 318*0Sstevel@tonic-gate ovec->sv_mask = set2mask(&oact.sa_mask); 319*0Sstevel@tonic-gate ovec->sv_flags = 0; 320*0Sstevel@tonic-gate if (oact.sa_flags & SA_ONSTACK) 321*0Sstevel@tonic-gate ovec->sv_flags |= SV_ONSTACK; 322*0Sstevel@tonic-gate if (oact.sa_flags & SA_RESETHAND) 323*0Sstevel@tonic-gate ovec->sv_flags |= SV_RESETHAND; 324*0Sstevel@tonic-gate if (!(oact.sa_flags & SA_RESTART)) 325*0Sstevel@tonic-gate ovec->sv_flags |= SV_INTERRUPT; 326*0Sstevel@tonic-gate } 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate return (0); 329*0Sstevel@tonic-gate } 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate int 332*0Sstevel@tonic-gate _sigstack(struct sigstack *nss, struct sigstack *oss) 333*0Sstevel@tonic-gate { 334*0Sstevel@tonic-gate struct sigaltstack nalt; 335*0Sstevel@tonic-gate struct sigaltstack oalt; 336*0Sstevel@tonic-gate struct sigaltstack *naltp; 337*0Sstevel@tonic-gate 338*0Sstevel@tonic-gate if (nss) { 339*0Sstevel@tonic-gate /* 340*0Sstevel@tonic-gate * assumes stack growth is down (like sparc and x86) 341*0Sstevel@tonic-gate */ 342*0Sstevel@tonic-gate nalt.ss_sp = nss->ss_sp - SIGSTKSZ; 343*0Sstevel@tonic-gate nalt.ss_size = SIGSTKSZ; 344*0Sstevel@tonic-gate nalt.ss_flags = 0; 345*0Sstevel@tonic-gate naltp = &nalt; 346*0Sstevel@tonic-gate } else 347*0Sstevel@tonic-gate naltp = (struct sigaltstack *)0; 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate if (sigaltstack(naltp, &oalt) < 0) 350*0Sstevel@tonic-gate return (-1); 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate if (oss) { 353*0Sstevel@tonic-gate /* 354*0Sstevel@tonic-gate * assumes stack growth is down (like sparc and x86) 355*0Sstevel@tonic-gate */ 356*0Sstevel@tonic-gate oss->ss_sp = oalt.ss_sp + oalt.ss_size; 357*0Sstevel@tonic-gate oss->ss_onstack = ((oalt.ss_flags & SS_ONSTACK) != 0); 358*0Sstevel@tonic-gate } 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate return (0); 361*0Sstevel@tonic-gate } 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate void (* 364*0Sstevel@tonic-gate ucbsignal(int s, void (*a)()))() 365*0Sstevel@tonic-gate { 366*0Sstevel@tonic-gate struct sigvec osv; 367*0Sstevel@tonic-gate struct sigvec nsv; 368*0Sstevel@tonic-gate static int mask[NSIG]; 369*0Sstevel@tonic-gate static int flags[NSIG]; 370*0Sstevel@tonic-gate 371*0Sstevel@tonic-gate nsv.sv_handler = a; 372*0Sstevel@tonic-gate nsv.sv_mask = mask[s]; 373*0Sstevel@tonic-gate nsv.sv_flags = flags[s]; 374*0Sstevel@tonic-gate if (ucbsigvec(s, &nsv, &osv) < 0) 375*0Sstevel@tonic-gate return (SIG_ERR); 376*0Sstevel@tonic-gate if (nsv.sv_mask != osv.sv_mask || nsv.sv_flags != osv.sv_flags) { 377*0Sstevel@tonic-gate mask[s] = nsv.sv_mask = osv.sv_mask; 378*0Sstevel@tonic-gate flags[s] = nsv.sv_flags = 379*0Sstevel@tonic-gate osv.sv_flags & ~(SV_RESETHAND|SV_INTERRUPT); 380*0Sstevel@tonic-gate if (ucbsigvec(s, &nsv, (struct sigvec *)0) < 0) 381*0Sstevel@tonic-gate return (SIG_ERR); 382*0Sstevel@tonic-gate } 383*0Sstevel@tonic-gate return (osv.sv_handler); 384*0Sstevel@tonic-gate } 385*0Sstevel@tonic-gate 386*0Sstevel@tonic-gate void (* 387*0Sstevel@tonic-gate usignal(int s, void (*a)()))() 388*0Sstevel@tonic-gate { 389*0Sstevel@tonic-gate return (ucbsignal(s, a)); 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate /* 393*0Sstevel@tonic-gate * Set signal state to prevent restart of system calls 394*0Sstevel@tonic-gate * after an instance of the indicated signal. 395*0Sstevel@tonic-gate */ 396*0Sstevel@tonic-gate int 397*0Sstevel@tonic-gate _siginterrupt(int sig, int flag) 398*0Sstevel@tonic-gate { 399*0Sstevel@tonic-gate return (ucbsiginterrupt(sig, flag)); 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate int 403*0Sstevel@tonic-gate ucbsiginterrupt(int sig, int flag) 404*0Sstevel@tonic-gate { 405*0Sstevel@tonic-gate struct sigvec sv; 406*0Sstevel@tonic-gate int ret; 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gate if ((ret = ucbsigvec(sig, 0, &sv)) < 0) 409*0Sstevel@tonic-gate return (ret); 410*0Sstevel@tonic-gate if (flag) 411*0Sstevel@tonic-gate sv.sv_flags |= SV_INTERRUPT; 412*0Sstevel@tonic-gate else 413*0Sstevel@tonic-gate sv.sv_flags &= ~SV_INTERRUPT; 414*0Sstevel@tonic-gate return (ucbsigvec(sig, &sv, 0)); 415*0Sstevel@tonic-gate } 416