17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
539e7390aSna195498 * Common Development and Distribution License (the "License").
639e7390aSna195498 * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
21965005c8Schin
22965005c8Schin /*
23*05845d98SArindam Sarkar * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24965005c8Schin * Use is subject to license terms.
25965005c8Schin */
26965005c8Schin
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate * UNIX shell
337c478bd9Sstevel@tonic-gate */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate #include "defs.h"
367c478bd9Sstevel@tonic-gate #include <sys/procset.h>
377c478bd9Sstevel@tonic-gate #include <siginfo.h>
387c478bd9Sstevel@tonic-gate #include <ucontext.h>
397c478bd9Sstevel@tonic-gate #include <errno.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate
42*05845d98SArindam Sarkar extern void hupforegnd(void);
43*05845d98SArindam Sarkar
44*05845d98SArindam Sarkar /* previous signal handler for signal 0 */
45*05845d98SArindam Sarkar static void (*psig0_func)() = SIG_ERR;
467c478bd9Sstevel@tonic-gate static char sigsegv_stack[SIGSTKSZ];
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate static void sigsegv(int sig, siginfo_t *sip, ucontext_t *uap);
497c478bd9Sstevel@tonic-gate static void fault();
507c478bd9Sstevel@tonic-gate static BOOL sleeping = 0;
517c478bd9Sstevel@tonic-gate static unsigned char *trapcom[MAXTRAP]; /* array of actions, one per signal */
527c478bd9Sstevel@tonic-gate static BOOL trapflg[MAXTRAP] =
537c478bd9Sstevel@tonic-gate {
547c478bd9Sstevel@tonic-gate 0,
557c478bd9Sstevel@tonic-gate 0, /* hangup */
567c478bd9Sstevel@tonic-gate 0, /* interrupt */
577c478bd9Sstevel@tonic-gate 0, /* quit */
587c478bd9Sstevel@tonic-gate 0, /* illegal instr */
597c478bd9Sstevel@tonic-gate 0, /* trace trap */
607c478bd9Sstevel@tonic-gate 0, /* IOT */
617c478bd9Sstevel@tonic-gate 0, /* EMT */
627c478bd9Sstevel@tonic-gate 0, /* float pt. exp */
637c478bd9Sstevel@tonic-gate 0, /* kill */
647c478bd9Sstevel@tonic-gate 0, /* bus error */
657c478bd9Sstevel@tonic-gate 0, /* memory faults */
667c478bd9Sstevel@tonic-gate 0, /* bad sys call */
677c478bd9Sstevel@tonic-gate 0, /* bad pipe call */
687c478bd9Sstevel@tonic-gate 0, /* alarm */
697c478bd9Sstevel@tonic-gate 0, /* software termination */
707c478bd9Sstevel@tonic-gate 0, /* unassigned */
717c478bd9Sstevel@tonic-gate 0, /* unassigned */
727c478bd9Sstevel@tonic-gate 0, /* death of child */
737c478bd9Sstevel@tonic-gate 0, /* power fail */
747c478bd9Sstevel@tonic-gate 0, /* window size change */
757c478bd9Sstevel@tonic-gate 0, /* urgent IO condition */
767c478bd9Sstevel@tonic-gate 0, /* pollable event occured */
777c478bd9Sstevel@tonic-gate 0, /* stopped by signal */
787c478bd9Sstevel@tonic-gate 0, /* stopped by user */
797c478bd9Sstevel@tonic-gate 0, /* continued */
807c478bd9Sstevel@tonic-gate 0, /* stopped by tty input */
817c478bd9Sstevel@tonic-gate 0, /* stopped by tty output */
827c478bd9Sstevel@tonic-gate 0, /* virtual timer expired */
837c478bd9Sstevel@tonic-gate 0, /* profiling timer expired */
847c478bd9Sstevel@tonic-gate 0, /* exceeded cpu limit */
857c478bd9Sstevel@tonic-gate 0, /* exceeded file size limit */
867c478bd9Sstevel@tonic-gate 0, /* process's lwps are blocked */
877c478bd9Sstevel@tonic-gate 0, /* special signal used by thread library */
887c478bd9Sstevel@tonic-gate 0, /* check point freeze */
897c478bd9Sstevel@tonic-gate 0, /* check point thaw */
907c478bd9Sstevel@tonic-gate };
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate static void (*(
937c478bd9Sstevel@tonic-gate sigval[MAXTRAP]))() =
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate 0,
967c478bd9Sstevel@tonic-gate done, /* hangup */
977c478bd9Sstevel@tonic-gate fault, /* interrupt */
987c478bd9Sstevel@tonic-gate fault, /* quit */
997c478bd9Sstevel@tonic-gate done, /* illegal instr */
1007c478bd9Sstevel@tonic-gate done, /* trace trap */
1017c478bd9Sstevel@tonic-gate done, /* IOT */
1027c478bd9Sstevel@tonic-gate done, /* EMT */
1037c478bd9Sstevel@tonic-gate done, /* floating pt. exp */
1047c478bd9Sstevel@tonic-gate 0, /* kill */
1057c478bd9Sstevel@tonic-gate done, /* bus error */
1067c478bd9Sstevel@tonic-gate sigsegv, /* memory faults */
1077c478bd9Sstevel@tonic-gate done, /* bad sys call */
1087c478bd9Sstevel@tonic-gate done, /* bad pipe call */
1097c478bd9Sstevel@tonic-gate done, /* alarm */
1107c478bd9Sstevel@tonic-gate fault, /* software termination */
1117c478bd9Sstevel@tonic-gate done, /* unassigned */
1127c478bd9Sstevel@tonic-gate done, /* unassigned */
1137c478bd9Sstevel@tonic-gate 0, /* death of child */
1147c478bd9Sstevel@tonic-gate done, /* power fail */
1157c478bd9Sstevel@tonic-gate 0, /* window size change */
1167c478bd9Sstevel@tonic-gate done, /* urgent IO condition */
1177c478bd9Sstevel@tonic-gate done, /* pollable event occured */
1187c478bd9Sstevel@tonic-gate 0, /* uncatchable stop */
1197c478bd9Sstevel@tonic-gate 0, /* foreground stop */
1207c478bd9Sstevel@tonic-gate 0, /* stopped process continued */
1217c478bd9Sstevel@tonic-gate 0, /* background tty read */
1227c478bd9Sstevel@tonic-gate 0, /* background tty write */
1237c478bd9Sstevel@tonic-gate done, /* virtual timer expired */
1247c478bd9Sstevel@tonic-gate done, /* profiling timer expired */
1257c478bd9Sstevel@tonic-gate done, /* exceeded cpu limit */
1267c478bd9Sstevel@tonic-gate done, /* exceeded file size limit */
1277c478bd9Sstevel@tonic-gate 0, /* process's lwps are blocked */
1287c478bd9Sstevel@tonic-gate 0, /* special signal used by thread library */
1297c478bd9Sstevel@tonic-gate 0, /* check point freeze */
1307c478bd9Sstevel@tonic-gate 0, /* check point thaw */
1317c478bd9Sstevel@tonic-gate };
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate static int
ignoring(int i)134965005c8Schin ignoring(int i)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate struct sigaction act;
1377c478bd9Sstevel@tonic-gate if (trapflg[i] & SIGIGN)
1387c478bd9Sstevel@tonic-gate return (1);
1397c478bd9Sstevel@tonic-gate sigaction(i, 0, &act);
1407c478bd9Sstevel@tonic-gate if (act.sa_handler == SIG_IGN) {
1417c478bd9Sstevel@tonic-gate trapflg[i] |= SIGIGN;
1427c478bd9Sstevel@tonic-gate return (1);
1437c478bd9Sstevel@tonic-gate }
1447c478bd9Sstevel@tonic-gate return (0);
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate static void
clrsig(i)1487c478bd9Sstevel@tonic-gate clrsig(i)
1497c478bd9Sstevel@tonic-gate int i;
1507c478bd9Sstevel@tonic-gate {
1517c478bd9Sstevel@tonic-gate if (trapcom[i] != 0) {
1527c478bd9Sstevel@tonic-gate free(trapcom[i]);
1537c478bd9Sstevel@tonic-gate trapcom[i] = 0;
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate if (trapflg[i] & SIGMOD) {
1587c478bd9Sstevel@tonic-gate /*
1597c478bd9Sstevel@tonic-gate * If the signal has been set to SIGIGN and we are now
1607c478bd9Sstevel@tonic-gate * clearing the disposition of the signal (restoring it
1617c478bd9Sstevel@tonic-gate * back to its default value) then we need to clear this
1627c478bd9Sstevel@tonic-gate * bit as well
1637c478bd9Sstevel@tonic-gate *
1647c478bd9Sstevel@tonic-gate */
1657c478bd9Sstevel@tonic-gate if (trapflg[i] & SIGIGN)
1667c478bd9Sstevel@tonic-gate trapflg[i] &= ~SIGIGN;
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate trapflg[i] &= ~SIGMOD;
1697c478bd9Sstevel@tonic-gate handle(i, sigval[i]);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate
1737c478bd9Sstevel@tonic-gate void
done(sig)1747c478bd9Sstevel@tonic-gate done(sig)
1757c478bd9Sstevel@tonic-gate {
176965005c8Schin unsigned char *t;
1777c478bd9Sstevel@tonic-gate int savxit;
1787c478bd9Sstevel@tonic-gate
179*05845d98SArindam Sarkar if (t = trapcom[0]) {
1807c478bd9Sstevel@tonic-gate trapcom[0] = 0;
1817c478bd9Sstevel@tonic-gate /* Save exit value so trap handler will not change its val */
1827c478bd9Sstevel@tonic-gate savxit = exitval;
1837c478bd9Sstevel@tonic-gate execexp(t, 0);
1847c478bd9Sstevel@tonic-gate exitval = savxit; /* Restore exit value */
1857c478bd9Sstevel@tonic-gate free(t);
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate else
1887c478bd9Sstevel@tonic-gate chktrap();
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate rmtemp(0);
1917c478bd9Sstevel@tonic-gate rmfunctmp();
1927c478bd9Sstevel@tonic-gate
1937c478bd9Sstevel@tonic-gate #ifdef ACCT
1947c478bd9Sstevel@tonic-gate doacct();
1957c478bd9Sstevel@tonic-gate #endif
1967c478bd9Sstevel@tonic-gate if (flags & subsh) {
1977c478bd9Sstevel@tonic-gate /* in a subshell, need to wait on foreground job */
1987c478bd9Sstevel@tonic-gate collect_fg_job();
1997c478bd9Sstevel@tonic-gate }
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate (void) endjobs(0);
2027c478bd9Sstevel@tonic-gate if (sig) {
2037c478bd9Sstevel@tonic-gate sigset_t set;
204*05845d98SArindam Sarkar
205*05845d98SArindam Sarkar /*
206*05845d98SArindam Sarkar * If the signal is SIGHUP, then it should be delivered
207*05845d98SArindam Sarkar * to the process group leader of the foreground job.
208*05845d98SArindam Sarkar */
209*05845d98SArindam Sarkar if (sig == SIGHUP)
210*05845d98SArindam Sarkar hupforegnd();
211*05845d98SArindam Sarkar
2127c478bd9Sstevel@tonic-gate sigemptyset(&set);
2137c478bd9Sstevel@tonic-gate sigaddset(&set, sig);
2147c478bd9Sstevel@tonic-gate sigprocmask(SIG_UNBLOCK, &set, 0);
2157c478bd9Sstevel@tonic-gate handle(sig, SIG_DFL);
2167c478bd9Sstevel@tonic-gate kill(mypid, sig);
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate exit(exitval);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate static void
fault(int sig)222965005c8Schin fault(int sig)
2237c478bd9Sstevel@tonic-gate {
224965005c8Schin int flag;
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate switch (sig) {
2277c478bd9Sstevel@tonic-gate case SIGALRM:
2287c478bd9Sstevel@tonic-gate if (sleeping)
2297c478bd9Sstevel@tonic-gate return;
2307c478bd9Sstevel@tonic-gate break;
2317c478bd9Sstevel@tonic-gate }
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate if (trapcom[sig])
2347c478bd9Sstevel@tonic-gate flag = TRAPSET;
2357c478bd9Sstevel@tonic-gate else if (flags & subsh)
2367c478bd9Sstevel@tonic-gate done(sig);
2377c478bd9Sstevel@tonic-gate else
2387c478bd9Sstevel@tonic-gate flag = SIGSET;
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate trapnote |= flag;
2417c478bd9Sstevel@tonic-gate trapflg[sig] |= flag;
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate int
handle(sig,func)2457c478bd9Sstevel@tonic-gate handle(sig, func)
2467c478bd9Sstevel@tonic-gate int sig;
2477c478bd9Sstevel@tonic-gate void (*func)();
2487c478bd9Sstevel@tonic-gate {
2497c478bd9Sstevel@tonic-gate int ret;
2507c478bd9Sstevel@tonic-gate struct sigaction act, oact;
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate if (func == SIG_IGN && (trapflg[sig] & SIGIGN))
2537c478bd9Sstevel@tonic-gate return (0);
2547c478bd9Sstevel@tonic-gate
2557c478bd9Sstevel@tonic-gate /*
2567c478bd9Sstevel@tonic-gate * Ensure that sigaction is only called with valid signal numbers,
2577c478bd9Sstevel@tonic-gate * we can get random values back for oact.sa_handler if the signal
2587c478bd9Sstevel@tonic-gate * number is invalid
2597c478bd9Sstevel@tonic-gate *
2607c478bd9Sstevel@tonic-gate */
2617c478bd9Sstevel@tonic-gate if (sig > MINTRAP && sig < MAXTRAP) {
2627c478bd9Sstevel@tonic-gate sigemptyset(&act.sa_mask);
2637c478bd9Sstevel@tonic-gate act.sa_flags = (sig == SIGSEGV) ? (SA_ONSTACK | SA_SIGINFO) : 0;
2647c478bd9Sstevel@tonic-gate act.sa_handler = func;
2657c478bd9Sstevel@tonic-gate sigaction(sig, &act, &oact);
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate if (func == SIG_IGN)
2697c478bd9Sstevel@tonic-gate trapflg[sig] |= SIGIGN;
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate /*
2727c478bd9Sstevel@tonic-gate * Special case for signal zero, we can not obtain the previos
2737c478bd9Sstevel@tonic-gate * action by calling sigaction, instead we save it in the variable
2747c478bd9Sstevel@tonic-gate * psig0_func, so we can test it next time through this code
2757c478bd9Sstevel@tonic-gate *
2767c478bd9Sstevel@tonic-gate */
2777c478bd9Sstevel@tonic-gate if (sig == 0) {
2787c478bd9Sstevel@tonic-gate ret = (psig0_func != func);
2797c478bd9Sstevel@tonic-gate psig0_func = func;
2807c478bd9Sstevel@tonic-gate } else {
2817c478bd9Sstevel@tonic-gate ret = (func != oact.sa_handler);
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate return (ret);
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate void
stdsigs()2887c478bd9Sstevel@tonic-gate stdsigs()
2897c478bd9Sstevel@tonic-gate {
290965005c8Schin int i;
2917c478bd9Sstevel@tonic-gate stack_t ss;
2927c478bd9Sstevel@tonic-gate int rtmin = (int)SIGRTMIN;
2937c478bd9Sstevel@tonic-gate int rtmax = (int)SIGRTMAX;
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate ss.ss_size = SIGSTKSZ;
2967c478bd9Sstevel@tonic-gate ss.ss_sp = sigsegv_stack;
2977c478bd9Sstevel@tonic-gate ss.ss_flags = 0;
29839e7390aSna195498 if (sigaltstack(&ss, NULL) == -1) {
29939e7390aSna195498 error("sigaltstack(2) failed");
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate for (i = 1; i < MAXTRAP; i++) {
3037c478bd9Sstevel@tonic-gate if (i == rtmin) {
3047c478bd9Sstevel@tonic-gate i = rtmax;
3057c478bd9Sstevel@tonic-gate continue;
3067c478bd9Sstevel@tonic-gate }
3077c478bd9Sstevel@tonic-gate if (sigval[i] == 0)
3087c478bd9Sstevel@tonic-gate continue;
3097c478bd9Sstevel@tonic-gate if (i != SIGSEGV && ignoring(i))
3107c478bd9Sstevel@tonic-gate continue;
3117c478bd9Sstevel@tonic-gate handle(i, sigval[i]);
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate /*
3157c478bd9Sstevel@tonic-gate * handle all the realtime signals
3167c478bd9Sstevel@tonic-gate *
3177c478bd9Sstevel@tonic-gate */
3187c478bd9Sstevel@tonic-gate for (i = rtmin; i <= rtmax; i++) {
3197c478bd9Sstevel@tonic-gate handle(i, done);
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate void
oldsigs()3247c478bd9Sstevel@tonic-gate oldsigs()
3257c478bd9Sstevel@tonic-gate {
326965005c8Schin int i;
327965005c8Schin unsigned char *t;
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate i = MAXTRAP;
330*05845d98SArindam Sarkar while (i--) {
3317c478bd9Sstevel@tonic-gate t = trapcom[i];
3327c478bd9Sstevel@tonic-gate if (t == 0 || *t)
3337c478bd9Sstevel@tonic-gate clrsig(i);
3347c478bd9Sstevel@tonic-gate trapflg[i] = 0;
3357c478bd9Sstevel@tonic-gate }
3367c478bd9Sstevel@tonic-gate trapnote = 0;
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate /*
3407c478bd9Sstevel@tonic-gate * check for traps
3417c478bd9Sstevel@tonic-gate */
3427c478bd9Sstevel@tonic-gate
3437c478bd9Sstevel@tonic-gate void
chktrap()3447c478bd9Sstevel@tonic-gate chktrap()
3457c478bd9Sstevel@tonic-gate {
346965005c8Schin int i = MAXTRAP;
347965005c8Schin unsigned char *t;
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate trapnote &= ~TRAPSET;
350*05845d98SArindam Sarkar while (--i) {
351*05845d98SArindam Sarkar if (trapflg[i] & TRAPSET) {
3527c478bd9Sstevel@tonic-gate trapflg[i] &= ~TRAPSET;
353*05845d98SArindam Sarkar if (t = trapcom[i]) {
3547c478bd9Sstevel@tonic-gate int savxit = exitval;
355*05845d98SArindam Sarkar
3567c478bd9Sstevel@tonic-gate execexp(t, 0);
3577c478bd9Sstevel@tonic-gate exitval = savxit;
3587c478bd9Sstevel@tonic-gate exitset();
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate }
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate
364965005c8Schin void
systrap(int argc,char ** argv)365965005c8Schin systrap(int argc, char **argv)
3667c478bd9Sstevel@tonic-gate {
3677c478bd9Sstevel@tonic-gate int sig;
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate if (argc == 1) {
3707c478bd9Sstevel@tonic-gate /*
3717c478bd9Sstevel@tonic-gate * print out the current action associated with each signal
3727c478bd9Sstevel@tonic-gate * handled by the shell
3737c478bd9Sstevel@tonic-gate *
3747c478bd9Sstevel@tonic-gate */
3757c478bd9Sstevel@tonic-gate for (sig = 0; sig < MAXTRAP; sig++) {
3767c478bd9Sstevel@tonic-gate if (trapcom[sig]) {
3777c478bd9Sstevel@tonic-gate prn_buff(sig);
3787c478bd9Sstevel@tonic-gate prs_buff(colon);
3797c478bd9Sstevel@tonic-gate prs_buff(trapcom[sig]);
3807c478bd9Sstevel@tonic-gate prc_buff(NL);
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate } else {
3847c478bd9Sstevel@tonic-gate /*
3857c478bd9Sstevel@tonic-gate * set the action for the list of signals
3867c478bd9Sstevel@tonic-gate *
3877c478bd9Sstevel@tonic-gate */
3887c478bd9Sstevel@tonic-gate char *cmd = *argv, *a1 = *(argv+1);
3897c478bd9Sstevel@tonic-gate BOOL noa1;
3907c478bd9Sstevel@tonic-gate noa1 = (str2sig(a1, &sig) == 0);
3917c478bd9Sstevel@tonic-gate if (noa1 == 0)
3927c478bd9Sstevel@tonic-gate ++argv;
3937c478bd9Sstevel@tonic-gate while (*++argv) {
3947c478bd9Sstevel@tonic-gate if (str2sig(*argv, &sig) < 0 ||
3957c478bd9Sstevel@tonic-gate sig >= MAXTRAP || sig < MINTRAP ||
3967c478bd9Sstevel@tonic-gate sig == SIGSEGV) {
3977c478bd9Sstevel@tonic-gate failure(cmd, badtrap);
3987c478bd9Sstevel@tonic-gate } else if (noa1) {
3997c478bd9Sstevel@tonic-gate /*
4007c478bd9Sstevel@tonic-gate * no action specifed so reset the siganl
4017c478bd9Sstevel@tonic-gate * to its default disposition
4027c478bd9Sstevel@tonic-gate *
4037c478bd9Sstevel@tonic-gate */
4047c478bd9Sstevel@tonic-gate clrsig(sig);
4057c478bd9Sstevel@tonic-gate } else if (*a1) {
4067c478bd9Sstevel@tonic-gate /*
4077c478bd9Sstevel@tonic-gate * set the action associated with the signal
4087c478bd9Sstevel@tonic-gate * to a1
4097c478bd9Sstevel@tonic-gate *
4107c478bd9Sstevel@tonic-gate */
4117c478bd9Sstevel@tonic-gate if (trapflg[sig] & SIGMOD || sig == 0 ||
4127c478bd9Sstevel@tonic-gate !ignoring(sig)) {
4137c478bd9Sstevel@tonic-gate handle(sig, fault);
4147c478bd9Sstevel@tonic-gate trapflg[sig] |= SIGMOD;
4157c478bd9Sstevel@tonic-gate replace(&trapcom[sig], a1);
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate } else if (handle(sig, SIG_IGN)) {
4187c478bd9Sstevel@tonic-gate /*
4197c478bd9Sstevel@tonic-gate * set the action associated with the signal
4207c478bd9Sstevel@tonic-gate * to SIG_IGN
4217c478bd9Sstevel@tonic-gate *
4227c478bd9Sstevel@tonic-gate */
4237c478bd9Sstevel@tonic-gate trapflg[sig] |= SIGMOD;
4247c478bd9Sstevel@tonic-gate replace(&trapcom[sig], a1);
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate }
4277c478bd9Sstevel@tonic-gate }
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate
430965005c8Schin void
sh_sleep(unsigned int ticks)431965005c8Schin sh_sleep(unsigned int ticks)
4327c478bd9Sstevel@tonic-gate {
4337c478bd9Sstevel@tonic-gate sigset_t set, oset;
4347c478bd9Sstevel@tonic-gate struct sigaction act, oact;
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate * add SIGALRM to mask
4397c478bd9Sstevel@tonic-gate */
4407c478bd9Sstevel@tonic-gate
4417c478bd9Sstevel@tonic-gate sigemptyset(&set);
4427c478bd9Sstevel@tonic-gate sigaddset(&set, SIGALRM);
4437c478bd9Sstevel@tonic-gate sigprocmask(SIG_BLOCK, &set, &oset);
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate /*
4467c478bd9Sstevel@tonic-gate * catch SIGALRM
4477c478bd9Sstevel@tonic-gate */
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate sigemptyset(&act.sa_mask);
4507c478bd9Sstevel@tonic-gate act.sa_flags = 0;
4517c478bd9Sstevel@tonic-gate act.sa_handler = fault;
4527c478bd9Sstevel@tonic-gate sigaction(SIGALRM, &act, &oact);
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate /*
4557c478bd9Sstevel@tonic-gate * start alarm and wait for signal
4567c478bd9Sstevel@tonic-gate */
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate alarm(ticks);
4597c478bd9Sstevel@tonic-gate sleeping = 1;
4607c478bd9Sstevel@tonic-gate sigsuspend(&oset);
4617c478bd9Sstevel@tonic-gate sleeping = 0;
4627c478bd9Sstevel@tonic-gate
4637c478bd9Sstevel@tonic-gate /*
4647c478bd9Sstevel@tonic-gate * reset alarm, catcher and mask
4657c478bd9Sstevel@tonic-gate */
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate alarm(0);
4687c478bd9Sstevel@tonic-gate sigaction(SIGALRM, &oact, NULL);
4697c478bd9Sstevel@tonic-gate sigprocmask(SIG_SETMASK, &oset, 0);
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate void
sigsegv(int sig,siginfo_t * sip,ucontext_t * uap)4747c478bd9Sstevel@tonic-gate sigsegv(int sig, siginfo_t *sip, ucontext_t *uap)
4757c478bd9Sstevel@tonic-gate {
4767c478bd9Sstevel@tonic-gate if (sip == (siginfo_t *)NULL) {
4777c478bd9Sstevel@tonic-gate /*
4787c478bd9Sstevel@tonic-gate * This should never happen, but if it does this is all we
4797c478bd9Sstevel@tonic-gate * can do. It can only happen if sigaction(2) for SIGSEGV
4807c478bd9Sstevel@tonic-gate * has been called without SA_SIGINFO being set.
4817c478bd9Sstevel@tonic-gate *
4827c478bd9Sstevel@tonic-gate */
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate exit(ERROR);
4857c478bd9Sstevel@tonic-gate } else {
4867c478bd9Sstevel@tonic-gate if (sip->si_code <= 0) {
4877c478bd9Sstevel@tonic-gate /*
4887c478bd9Sstevel@tonic-gate * If we are here then SIGSEGV must have been sent to
4897c478bd9Sstevel@tonic-gate * us from a user process NOT as a result of an
4907c478bd9Sstevel@tonic-gate * internal error within the shell eg
4917c478bd9Sstevel@tonic-gate * kill -SEGV $$
4927c478bd9Sstevel@tonic-gate * will bring us here. So do the normal thing.
4937c478bd9Sstevel@tonic-gate *
4947c478bd9Sstevel@tonic-gate */
4957c478bd9Sstevel@tonic-gate fault(sig);
4967c478bd9Sstevel@tonic-gate } else {
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * If we are here then there must have been an internal
4997c478bd9Sstevel@tonic-gate * error within the shell to generate SIGSEGV eg
5007c478bd9Sstevel@tonic-gate * the stack is full and we cannot call any more
5017c478bd9Sstevel@tonic-gate * functions (Remeber this signal handler is running
5027c478bd9Sstevel@tonic-gate * on an alternate stack). So we just exit cleanly
5037c478bd9Sstevel@tonic-gate * with an error status (no core file).
5047c478bd9Sstevel@tonic-gate */
5057c478bd9Sstevel@tonic-gate exit(ERROR);
5067c478bd9Sstevel@tonic-gate }
5077c478bd9Sstevel@tonic-gate }
5087c478bd9Sstevel@tonic-gate }
509