1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright (c) 1996, by Sun Microsystems, Inc. 28*7c478bd9Sstevel@tonic-gate * All rights reserved. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.13.17.1 */ 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * UNIX shell 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include "defs.h" 37*7c478bd9Sstevel@tonic-gate #include <sys/procset.h> 38*7c478bd9Sstevel@tonic-gate #include <siginfo.h> 39*7c478bd9Sstevel@tonic-gate #include <ucontext.h> 40*7c478bd9Sstevel@tonic-gate #include <errno.h> 41*7c478bd9Sstevel@tonic-gate #include <string.h> 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate static void (*psig0_func)() = SIG_ERR; /* previous signal handler for signal 0 */ 44*7c478bd9Sstevel@tonic-gate static char sigsegv_stack[SIGSTKSZ]; 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate static void sigsegv(int sig, siginfo_t *sip, ucontext_t *uap); 47*7c478bd9Sstevel@tonic-gate static void fault(); 48*7c478bd9Sstevel@tonic-gate static BOOL sleeping = 0; 49*7c478bd9Sstevel@tonic-gate static unsigned char *trapcom[MAXTRAP]; /* array of actions, one per signal */ 50*7c478bd9Sstevel@tonic-gate static BOOL trapflg[MAXTRAP] = 51*7c478bd9Sstevel@tonic-gate { 52*7c478bd9Sstevel@tonic-gate 0, 53*7c478bd9Sstevel@tonic-gate 0, /* hangup */ 54*7c478bd9Sstevel@tonic-gate 0, /* interrupt */ 55*7c478bd9Sstevel@tonic-gate 0, /* quit */ 56*7c478bd9Sstevel@tonic-gate 0, /* illegal instr */ 57*7c478bd9Sstevel@tonic-gate 0, /* trace trap */ 58*7c478bd9Sstevel@tonic-gate 0, /* IOT */ 59*7c478bd9Sstevel@tonic-gate 0, /* EMT */ 60*7c478bd9Sstevel@tonic-gate 0, /* float pt. exp */ 61*7c478bd9Sstevel@tonic-gate 0, /* kill */ 62*7c478bd9Sstevel@tonic-gate 0, /* bus error */ 63*7c478bd9Sstevel@tonic-gate 0, /* memory faults */ 64*7c478bd9Sstevel@tonic-gate 0, /* bad sys call */ 65*7c478bd9Sstevel@tonic-gate 0, /* bad pipe call */ 66*7c478bd9Sstevel@tonic-gate 0, /* alarm */ 67*7c478bd9Sstevel@tonic-gate 0, /* software termination */ 68*7c478bd9Sstevel@tonic-gate 0, /* unassigned */ 69*7c478bd9Sstevel@tonic-gate 0, /* unassigned */ 70*7c478bd9Sstevel@tonic-gate 0, /* death of child */ 71*7c478bd9Sstevel@tonic-gate 0, /* power fail */ 72*7c478bd9Sstevel@tonic-gate 0, /* window size change */ 73*7c478bd9Sstevel@tonic-gate 0, /* urgent IO condition */ 74*7c478bd9Sstevel@tonic-gate 0, /* pollable event occured */ 75*7c478bd9Sstevel@tonic-gate 0, /* stopped by signal */ 76*7c478bd9Sstevel@tonic-gate 0, /* stopped by user */ 77*7c478bd9Sstevel@tonic-gate 0, /* continued */ 78*7c478bd9Sstevel@tonic-gate 0, /* stopped by tty input */ 79*7c478bd9Sstevel@tonic-gate 0, /* stopped by tty output */ 80*7c478bd9Sstevel@tonic-gate 0, /* virtual timer expired */ 81*7c478bd9Sstevel@tonic-gate 0, /* profiling timer expired */ 82*7c478bd9Sstevel@tonic-gate 0, /* exceeded cpu limit */ 83*7c478bd9Sstevel@tonic-gate 0, /* exceeded file size limit */ 84*7c478bd9Sstevel@tonic-gate 0, /* process's lwps are blocked */ 85*7c478bd9Sstevel@tonic-gate 0, /* special signal used by thread library */ 86*7c478bd9Sstevel@tonic-gate 0, /* check point freeze */ 87*7c478bd9Sstevel@tonic-gate 0, /* check point thaw */ 88*7c478bd9Sstevel@tonic-gate }; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate static void (*( 91*7c478bd9Sstevel@tonic-gate sigval[MAXTRAP]))() = 92*7c478bd9Sstevel@tonic-gate { 93*7c478bd9Sstevel@tonic-gate 0, 94*7c478bd9Sstevel@tonic-gate done, /* hangup */ 95*7c478bd9Sstevel@tonic-gate fault, /* interrupt */ 96*7c478bd9Sstevel@tonic-gate fault, /* quit */ 97*7c478bd9Sstevel@tonic-gate done, /* illegal instr */ 98*7c478bd9Sstevel@tonic-gate done, /* trace trap */ 99*7c478bd9Sstevel@tonic-gate done, /* IOT */ 100*7c478bd9Sstevel@tonic-gate done, /* EMT */ 101*7c478bd9Sstevel@tonic-gate done, /* floating pt. exp */ 102*7c478bd9Sstevel@tonic-gate 0, /* kill */ 103*7c478bd9Sstevel@tonic-gate done, /* bus error */ 104*7c478bd9Sstevel@tonic-gate sigsegv, /* memory faults */ 105*7c478bd9Sstevel@tonic-gate done, /* bad sys call */ 106*7c478bd9Sstevel@tonic-gate done, /* bad pipe call */ 107*7c478bd9Sstevel@tonic-gate done, /* alarm */ 108*7c478bd9Sstevel@tonic-gate fault, /* software termination */ 109*7c478bd9Sstevel@tonic-gate done, /* unassigned */ 110*7c478bd9Sstevel@tonic-gate done, /* unassigned */ 111*7c478bd9Sstevel@tonic-gate 0, /* death of child */ 112*7c478bd9Sstevel@tonic-gate done, /* power fail */ 113*7c478bd9Sstevel@tonic-gate 0, /* window size change */ 114*7c478bd9Sstevel@tonic-gate done, /* urgent IO condition */ 115*7c478bd9Sstevel@tonic-gate done, /* pollable event occured */ 116*7c478bd9Sstevel@tonic-gate 0, /* uncatchable stop */ 117*7c478bd9Sstevel@tonic-gate 0, /* foreground stop */ 118*7c478bd9Sstevel@tonic-gate 0, /* stopped process continued */ 119*7c478bd9Sstevel@tonic-gate 0, /* background tty read */ 120*7c478bd9Sstevel@tonic-gate 0, /* background tty write */ 121*7c478bd9Sstevel@tonic-gate done, /* virtual timer expired */ 122*7c478bd9Sstevel@tonic-gate done, /* profiling timer expired */ 123*7c478bd9Sstevel@tonic-gate done, /* exceeded cpu limit */ 124*7c478bd9Sstevel@tonic-gate done, /* exceeded file size limit */ 125*7c478bd9Sstevel@tonic-gate 0, /* process's lwps are blocked */ 126*7c478bd9Sstevel@tonic-gate 0, /* special signal used by thread library */ 127*7c478bd9Sstevel@tonic-gate 0, /* check point freeze */ 128*7c478bd9Sstevel@tonic-gate 0, /* check point thaw */ 129*7c478bd9Sstevel@tonic-gate }; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate static int 132*7c478bd9Sstevel@tonic-gate ignoring(i) 133*7c478bd9Sstevel@tonic-gate register int i; 134*7c478bd9Sstevel@tonic-gate { 135*7c478bd9Sstevel@tonic-gate struct sigaction act; 136*7c478bd9Sstevel@tonic-gate if (trapflg[i] & SIGIGN) 137*7c478bd9Sstevel@tonic-gate return (1); 138*7c478bd9Sstevel@tonic-gate sigaction(i, 0, &act); 139*7c478bd9Sstevel@tonic-gate if (act.sa_handler == SIG_IGN) { 140*7c478bd9Sstevel@tonic-gate trapflg[i] |= SIGIGN; 141*7c478bd9Sstevel@tonic-gate return (1); 142*7c478bd9Sstevel@tonic-gate } 143*7c478bd9Sstevel@tonic-gate return (0); 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate static void 147*7c478bd9Sstevel@tonic-gate clrsig(i) 148*7c478bd9Sstevel@tonic-gate int i; 149*7c478bd9Sstevel@tonic-gate { 150*7c478bd9Sstevel@tonic-gate if (trapcom[i] != 0) { 151*7c478bd9Sstevel@tonic-gate free(trapcom[i]); 152*7c478bd9Sstevel@tonic-gate trapcom[i] = 0; 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate if (trapflg[i] & SIGMOD) { 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * If the signal has been set to SIGIGN and we are now 159*7c478bd9Sstevel@tonic-gate * clearing the disposition of the signal (restoring it 160*7c478bd9Sstevel@tonic-gate * back to its default value) then we need to clear this 161*7c478bd9Sstevel@tonic-gate * bit as well 162*7c478bd9Sstevel@tonic-gate * 163*7c478bd9Sstevel@tonic-gate */ 164*7c478bd9Sstevel@tonic-gate if (trapflg[i] & SIGIGN) 165*7c478bd9Sstevel@tonic-gate trapflg[i] &= ~SIGIGN; 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate trapflg[i] &= ~SIGMOD; 168*7c478bd9Sstevel@tonic-gate handle(i, sigval[i]); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate void 173*7c478bd9Sstevel@tonic-gate done(sig) 174*7c478bd9Sstevel@tonic-gate { 175*7c478bd9Sstevel@tonic-gate register unsigned char *t; 176*7c478bd9Sstevel@tonic-gate int savxit; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate if (t = trapcom[0]) 179*7c478bd9Sstevel@tonic-gate { 180*7c478bd9Sstevel@tonic-gate trapcom[0] = 0; 181*7c478bd9Sstevel@tonic-gate /* Save exit value so trap handler will not change its val */ 182*7c478bd9Sstevel@tonic-gate savxit = exitval; 183*7c478bd9Sstevel@tonic-gate execexp(t, 0); 184*7c478bd9Sstevel@tonic-gate exitval = savxit; /* Restore exit value */ 185*7c478bd9Sstevel@tonic-gate free(t); 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate else 188*7c478bd9Sstevel@tonic-gate chktrap(); 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate rmtemp(0); 191*7c478bd9Sstevel@tonic-gate rmfunctmp(); 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate #ifdef ACCT 194*7c478bd9Sstevel@tonic-gate doacct(); 195*7c478bd9Sstevel@tonic-gate #endif 196*7c478bd9Sstevel@tonic-gate if (flags & subsh) { 197*7c478bd9Sstevel@tonic-gate /* in a subshell, need to wait on foreground job */ 198*7c478bd9Sstevel@tonic-gate collect_fg_job(); 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate (void) endjobs(0); 202*7c478bd9Sstevel@tonic-gate if (sig) { 203*7c478bd9Sstevel@tonic-gate sigset_t set; 204*7c478bd9Sstevel@tonic-gate sigemptyset(&set); 205*7c478bd9Sstevel@tonic-gate sigaddset(&set, sig); 206*7c478bd9Sstevel@tonic-gate sigprocmask(SIG_UNBLOCK, &set, 0); 207*7c478bd9Sstevel@tonic-gate handle(sig, SIG_DFL); 208*7c478bd9Sstevel@tonic-gate kill(mypid, sig); 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate exit(exitval); 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate static void 214*7c478bd9Sstevel@tonic-gate fault(sig) 215*7c478bd9Sstevel@tonic-gate register int sig; 216*7c478bd9Sstevel@tonic-gate { 217*7c478bd9Sstevel@tonic-gate register int flag; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate switch (sig) { 220*7c478bd9Sstevel@tonic-gate case SIGALRM: 221*7c478bd9Sstevel@tonic-gate if (sleeping) 222*7c478bd9Sstevel@tonic-gate return; 223*7c478bd9Sstevel@tonic-gate break; 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate if (trapcom[sig]) 227*7c478bd9Sstevel@tonic-gate flag = TRAPSET; 228*7c478bd9Sstevel@tonic-gate else if (flags & subsh) 229*7c478bd9Sstevel@tonic-gate done(sig); 230*7c478bd9Sstevel@tonic-gate else 231*7c478bd9Sstevel@tonic-gate flag = SIGSET; 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate trapnote |= flag; 234*7c478bd9Sstevel@tonic-gate trapflg[sig] |= flag; 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate int 238*7c478bd9Sstevel@tonic-gate handle(sig, func) 239*7c478bd9Sstevel@tonic-gate int sig; 240*7c478bd9Sstevel@tonic-gate void (*func)(); 241*7c478bd9Sstevel@tonic-gate { 242*7c478bd9Sstevel@tonic-gate int ret; 243*7c478bd9Sstevel@tonic-gate struct sigaction act, oact; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate if (func == SIG_IGN && (trapflg[sig] & SIGIGN)) 246*7c478bd9Sstevel@tonic-gate return (0); 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate /* 249*7c478bd9Sstevel@tonic-gate * Ensure that sigaction is only called with valid signal numbers, 250*7c478bd9Sstevel@tonic-gate * we can get random values back for oact.sa_handler if the signal 251*7c478bd9Sstevel@tonic-gate * number is invalid 252*7c478bd9Sstevel@tonic-gate * 253*7c478bd9Sstevel@tonic-gate */ 254*7c478bd9Sstevel@tonic-gate if (sig > MINTRAP && sig < MAXTRAP) { 255*7c478bd9Sstevel@tonic-gate sigemptyset(&act.sa_mask); 256*7c478bd9Sstevel@tonic-gate act.sa_flags = (sig == SIGSEGV) ? (SA_ONSTACK | SA_SIGINFO) : 0; 257*7c478bd9Sstevel@tonic-gate act.sa_handler = func; 258*7c478bd9Sstevel@tonic-gate sigaction(sig, &act, &oact); 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate if (func == SIG_IGN) 262*7c478bd9Sstevel@tonic-gate trapflg[sig] |= SIGIGN; 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * Special case for signal zero, we can not obtain the previos 266*7c478bd9Sstevel@tonic-gate * action by calling sigaction, instead we save it in the variable 267*7c478bd9Sstevel@tonic-gate * psig0_func, so we can test it next time through this code 268*7c478bd9Sstevel@tonic-gate * 269*7c478bd9Sstevel@tonic-gate */ 270*7c478bd9Sstevel@tonic-gate if (sig == 0) { 271*7c478bd9Sstevel@tonic-gate ret = (psig0_func != func); 272*7c478bd9Sstevel@tonic-gate psig0_func = func; 273*7c478bd9Sstevel@tonic-gate } else { 274*7c478bd9Sstevel@tonic-gate ret = (func != oact.sa_handler); 275*7c478bd9Sstevel@tonic-gate } 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate return (ret); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate void 281*7c478bd9Sstevel@tonic-gate stdsigs() 282*7c478bd9Sstevel@tonic-gate { 283*7c478bd9Sstevel@tonic-gate register int i; 284*7c478bd9Sstevel@tonic-gate stack_t ss; 285*7c478bd9Sstevel@tonic-gate int err = 0; 286*7c478bd9Sstevel@tonic-gate int rtmin = (int)SIGRTMIN; 287*7c478bd9Sstevel@tonic-gate int rtmax = (int)SIGRTMAX; 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate ss.ss_size = SIGSTKSZ; 290*7c478bd9Sstevel@tonic-gate ss.ss_sp = sigsegv_stack; 291*7c478bd9Sstevel@tonic-gate ss.ss_flags = 0; 292*7c478bd9Sstevel@tonic-gate errno = 0; 293*7c478bd9Sstevel@tonic-gate if (sigaltstack(&ss, (stack_t *)NULL) == -1) { 294*7c478bd9Sstevel@tonic-gate err = errno; 295*7c478bd9Sstevel@tonic-gate failure("sigaltstack(2) failed with", strerror(err)); 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate for (i = 1; i < MAXTRAP; i++) { 299*7c478bd9Sstevel@tonic-gate if (i == rtmin) { 300*7c478bd9Sstevel@tonic-gate i = rtmax; 301*7c478bd9Sstevel@tonic-gate continue; 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate if (sigval[i] == 0) 304*7c478bd9Sstevel@tonic-gate continue; 305*7c478bd9Sstevel@tonic-gate if (i != SIGSEGV && ignoring(i)) 306*7c478bd9Sstevel@tonic-gate continue; 307*7c478bd9Sstevel@tonic-gate handle(i, sigval[i]); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate /* 311*7c478bd9Sstevel@tonic-gate * handle all the realtime signals 312*7c478bd9Sstevel@tonic-gate * 313*7c478bd9Sstevel@tonic-gate */ 314*7c478bd9Sstevel@tonic-gate for (i = rtmin; i <= rtmax; i++) { 315*7c478bd9Sstevel@tonic-gate handle(i, done); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate void 320*7c478bd9Sstevel@tonic-gate oldsigs() 321*7c478bd9Sstevel@tonic-gate { 322*7c478bd9Sstevel@tonic-gate register int i; 323*7c478bd9Sstevel@tonic-gate register unsigned char *t; 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate i = MAXTRAP; 326*7c478bd9Sstevel@tonic-gate while (i--) 327*7c478bd9Sstevel@tonic-gate { 328*7c478bd9Sstevel@tonic-gate t = trapcom[i]; 329*7c478bd9Sstevel@tonic-gate if (t == 0 || *t) 330*7c478bd9Sstevel@tonic-gate clrsig(i); 331*7c478bd9Sstevel@tonic-gate trapflg[i] = 0; 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate trapnote = 0; 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate /* 337*7c478bd9Sstevel@tonic-gate * check for traps 338*7c478bd9Sstevel@tonic-gate */ 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate void 341*7c478bd9Sstevel@tonic-gate chktrap() 342*7c478bd9Sstevel@tonic-gate { 343*7c478bd9Sstevel@tonic-gate register int i = MAXTRAP; 344*7c478bd9Sstevel@tonic-gate register unsigned char *t; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate trapnote &= ~TRAPSET; 347*7c478bd9Sstevel@tonic-gate while (--i) 348*7c478bd9Sstevel@tonic-gate { 349*7c478bd9Sstevel@tonic-gate if (trapflg[i] & TRAPSET) 350*7c478bd9Sstevel@tonic-gate { 351*7c478bd9Sstevel@tonic-gate trapflg[i] &= ~TRAPSET; 352*7c478bd9Sstevel@tonic-gate if (t = trapcom[i]) 353*7c478bd9Sstevel@tonic-gate { 354*7c478bd9Sstevel@tonic-gate int savxit = exitval; 355*7c478bd9Sstevel@tonic-gate execexp(t, 0); 356*7c478bd9Sstevel@tonic-gate exitval = savxit; 357*7c478bd9Sstevel@tonic-gate exitset(); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate } 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate systrap(argc, argv) 364*7c478bd9Sstevel@tonic-gate int argc; 365*7c478bd9Sstevel@tonic-gate char **argv; 366*7c478bd9Sstevel@tonic-gate { 367*7c478bd9Sstevel@tonic-gate int sig; 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate if (argc == 1) { 370*7c478bd9Sstevel@tonic-gate /* 371*7c478bd9Sstevel@tonic-gate * print out the current action associated with each signal 372*7c478bd9Sstevel@tonic-gate * handled by the shell 373*7c478bd9Sstevel@tonic-gate * 374*7c478bd9Sstevel@tonic-gate */ 375*7c478bd9Sstevel@tonic-gate for (sig = 0; sig < MAXTRAP; sig++) { 376*7c478bd9Sstevel@tonic-gate if (trapcom[sig]) { 377*7c478bd9Sstevel@tonic-gate prn_buff(sig); 378*7c478bd9Sstevel@tonic-gate prs_buff(colon); 379*7c478bd9Sstevel@tonic-gate prs_buff(trapcom[sig]); 380*7c478bd9Sstevel@tonic-gate prc_buff(NL); 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate } else { 384*7c478bd9Sstevel@tonic-gate /* 385*7c478bd9Sstevel@tonic-gate * set the action for the list of signals 386*7c478bd9Sstevel@tonic-gate * 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate char *cmd = *argv, *a1 = *(argv+1); 389*7c478bd9Sstevel@tonic-gate BOOL noa1; 390*7c478bd9Sstevel@tonic-gate noa1 = (str2sig(a1, &sig) == 0); 391*7c478bd9Sstevel@tonic-gate if (noa1 == 0) 392*7c478bd9Sstevel@tonic-gate ++argv; 393*7c478bd9Sstevel@tonic-gate while (*++argv) { 394*7c478bd9Sstevel@tonic-gate if (str2sig(*argv, &sig) < 0 || 395*7c478bd9Sstevel@tonic-gate sig >= MAXTRAP || sig < MINTRAP || 396*7c478bd9Sstevel@tonic-gate sig == SIGSEGV) { 397*7c478bd9Sstevel@tonic-gate failure(cmd, badtrap); 398*7c478bd9Sstevel@tonic-gate } else if (noa1) { 399*7c478bd9Sstevel@tonic-gate /* 400*7c478bd9Sstevel@tonic-gate * no action specifed so reset the siganl 401*7c478bd9Sstevel@tonic-gate * to its default disposition 402*7c478bd9Sstevel@tonic-gate * 403*7c478bd9Sstevel@tonic-gate */ 404*7c478bd9Sstevel@tonic-gate clrsig(sig); 405*7c478bd9Sstevel@tonic-gate } else if (*a1) { 406*7c478bd9Sstevel@tonic-gate /* 407*7c478bd9Sstevel@tonic-gate * set the action associated with the signal 408*7c478bd9Sstevel@tonic-gate * to a1 409*7c478bd9Sstevel@tonic-gate * 410*7c478bd9Sstevel@tonic-gate */ 411*7c478bd9Sstevel@tonic-gate if (trapflg[sig] & SIGMOD || sig == 0 || 412*7c478bd9Sstevel@tonic-gate !ignoring(sig)) { 413*7c478bd9Sstevel@tonic-gate handle(sig, fault); 414*7c478bd9Sstevel@tonic-gate trapflg[sig] |= SIGMOD; 415*7c478bd9Sstevel@tonic-gate replace(&trapcom[sig], a1); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate } else if (handle(sig, SIG_IGN)) { 418*7c478bd9Sstevel@tonic-gate /* 419*7c478bd9Sstevel@tonic-gate * set the action associated with the signal 420*7c478bd9Sstevel@tonic-gate * to SIG_IGN 421*7c478bd9Sstevel@tonic-gate * 422*7c478bd9Sstevel@tonic-gate */ 423*7c478bd9Sstevel@tonic-gate trapflg[sig] |= SIGMOD; 424*7c478bd9Sstevel@tonic-gate replace(&trapcom[sig], a1); 425*7c478bd9Sstevel@tonic-gate } 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate unsigned int 431*7c478bd9Sstevel@tonic-gate sleep(ticks) 432*7c478bd9Sstevel@tonic-gate unsigned int ticks; 433*7c478bd9Sstevel@tonic-gate { 434*7c478bd9Sstevel@tonic-gate sigset_t set, oset; 435*7c478bd9Sstevel@tonic-gate struct sigaction act, oact; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate /* 439*7c478bd9Sstevel@tonic-gate * add SIGALRM to mask 440*7c478bd9Sstevel@tonic-gate */ 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate sigemptyset(&set); 443*7c478bd9Sstevel@tonic-gate sigaddset(&set, SIGALRM); 444*7c478bd9Sstevel@tonic-gate sigprocmask(SIG_BLOCK, &set, &oset); 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate /* 447*7c478bd9Sstevel@tonic-gate * catch SIGALRM 448*7c478bd9Sstevel@tonic-gate */ 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate sigemptyset(&act.sa_mask); 451*7c478bd9Sstevel@tonic-gate act.sa_flags = 0; 452*7c478bd9Sstevel@tonic-gate act.sa_handler = fault; 453*7c478bd9Sstevel@tonic-gate sigaction(SIGALRM, &act, &oact); 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate /* 456*7c478bd9Sstevel@tonic-gate * start alarm and wait for signal 457*7c478bd9Sstevel@tonic-gate */ 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate alarm(ticks); 460*7c478bd9Sstevel@tonic-gate sleeping = 1; 461*7c478bd9Sstevel@tonic-gate sigsuspend(&oset); 462*7c478bd9Sstevel@tonic-gate sleeping = 0; 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate /* 465*7c478bd9Sstevel@tonic-gate * reset alarm, catcher and mask 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate alarm(0); 469*7c478bd9Sstevel@tonic-gate sigaction(SIGALRM, &oact, NULL); 470*7c478bd9Sstevel@tonic-gate sigprocmask(SIG_SETMASK, &oset, 0); 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate } 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate void 475*7c478bd9Sstevel@tonic-gate sigsegv(int sig, siginfo_t *sip, ucontext_t *uap) 476*7c478bd9Sstevel@tonic-gate { 477*7c478bd9Sstevel@tonic-gate if (sip == (siginfo_t *)NULL) { 478*7c478bd9Sstevel@tonic-gate /* 479*7c478bd9Sstevel@tonic-gate * This should never happen, but if it does this is all we 480*7c478bd9Sstevel@tonic-gate * can do. It can only happen if sigaction(2) for SIGSEGV 481*7c478bd9Sstevel@tonic-gate * has been called without SA_SIGINFO being set. 482*7c478bd9Sstevel@tonic-gate * 483*7c478bd9Sstevel@tonic-gate */ 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate exit(ERROR); 486*7c478bd9Sstevel@tonic-gate } else { 487*7c478bd9Sstevel@tonic-gate if (sip->si_code <= 0) { 488*7c478bd9Sstevel@tonic-gate /* 489*7c478bd9Sstevel@tonic-gate * If we are here then SIGSEGV must have been sent to 490*7c478bd9Sstevel@tonic-gate * us from a user process NOT as a result of an 491*7c478bd9Sstevel@tonic-gate * internal error within the shell eg 492*7c478bd9Sstevel@tonic-gate * kill -SEGV $$ 493*7c478bd9Sstevel@tonic-gate * will bring us here. So do the normal thing. 494*7c478bd9Sstevel@tonic-gate * 495*7c478bd9Sstevel@tonic-gate */ 496*7c478bd9Sstevel@tonic-gate fault(sig); 497*7c478bd9Sstevel@tonic-gate } else { 498*7c478bd9Sstevel@tonic-gate /* 499*7c478bd9Sstevel@tonic-gate * If we are here then there must have been an internal 500*7c478bd9Sstevel@tonic-gate * error within the shell to generate SIGSEGV eg 501*7c478bd9Sstevel@tonic-gate * the stack is full and we cannot call any more 502*7c478bd9Sstevel@tonic-gate * functions (Remeber this signal handler is running 503*7c478bd9Sstevel@tonic-gate * on an alternate stack). So we just exit cleanly 504*7c478bd9Sstevel@tonic-gate * with an error status (no core file). 505*7c478bd9Sstevel@tonic-gate */ 506*7c478bd9Sstevel@tonic-gate exit(ERROR); 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate } 509*7c478bd9Sstevel@tonic-gate } 510