4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
36 #include <sys/procset.h>
42 extern void hupforegnd(void);
44 /* previous signal handler for signal 0 */
45 static void (*psig0_func
)() = SIG_ERR
;
46 static char sigsegv_stack
[SIGSTKSZ
];
48 static void sigsegv(int sig
, siginfo_t
*sip
, ucontext_t
*uap
);
50 static BOOL sleeping
= 0;
51 static unsigned char *trapcom
[MAXTRAP
]; /* array of actions, one per signal */
52 static BOOL trapflg
[MAXTRAP
] =
58 0, /* illegal instr */
62 0, /* float pt. exp */
65 0, /* memory faults */
67 0, /* bad pipe call */
69 0, /* software termination */
72 0, /* death of child */
74 0, /* window size change */
75 0, /* urgent IO condition */
76 0, /* pollable event occured */
77 0, /* stopped by signal */
78 0, /* stopped by user */
80 0, /* stopped by tty input */
81 0, /* stopped by tty output */
82 0, /* virtual timer expired */
83 0, /* profiling timer expired */
84 0, /* exceeded cpu limit */
85 0, /* exceeded file size limit */
86 0, /* process's lwps are blocked */
87 0, /* special signal used by thread library */
88 0, /* check point freeze */
89 0, /* check point thaw */
97 fault
, /* interrupt */
99 done
, /* illegal instr */
100 done
, /* trace trap */
103 done
, /* floating pt. exp */
105 done
, /* bus error */
106 sigsegv
, /* memory faults */
107 done
, /* bad sys call */
108 done
, /* bad pipe call */
110 fault
, /* software termination */
111 done
, /* unassigned */
112 done
, /* unassigned */
113 0, /* death of child */
114 done
, /* power fail */
115 0, /* window size change */
116 done
, /* urgent IO condition */
117 done
, /* pollable event occured */
118 0, /* uncatchable stop */
119 0, /* foreground stop */
120 0, /* stopped process continued */
121 0, /* background tty read */
122 0, /* background tty write */
123 done
, /* virtual timer expired */
124 done
, /* profiling timer expired */
125 done
, /* exceeded cpu limit */
126 done
, /* exceeded file size limit */
127 0, /* process's lwps are blocked */
128 0, /* special signal used by thread library */
129 0, /* check point freeze */
130 0, /* check point thaw */
136 struct sigaction act
;
137 if (trapflg
[i
] & SIGIGN
)
139 sigaction(i
, 0, &act
);
140 if (act
.sa_handler
== SIG_IGN
) {
141 trapflg
[i
] |= SIGIGN
;
151 if (trapcom
[i
] != 0) {
157 if (trapflg
[i
] & SIGMOD
) {
159 * If the signal has been set to SIGIGN and we are now
160 * clearing the disposition of the signal (restoring it
161 * back to its default value) then we need to clear this
165 if (trapflg
[i
] & SIGIGN
)
166 trapflg
[i
] &= ~SIGIGN
;
168 trapflg
[i
] &= ~SIGMOD
;
169 handle(i
, sigval
[i
]);
179 if (t
= trapcom
[0]) {
181 /* Save exit value so trap handler will not change its val */
184 exitval
= savxit
; /* Restore exit value */
197 /* in a subshell, need to wait on foreground job */
206 * If the signal is SIGHUP, then it should be delivered
207 * to the process group leader of the foreground job.
213 sigaddset(&set
, sig
);
214 sigprocmask(SIG_UNBLOCK
, &set
, 0);
215 handle(sig
, SIG_DFL
);
235 else if (flags
& subsh
)
241 trapflg
[sig
] |= flag
;
250 struct sigaction act
, oact
;
252 if (func
== SIG_IGN
&& (trapflg
[sig
] & SIGIGN
))
256 * Ensure that sigaction is only called with valid signal numbers,
257 * we can get random values back for oact.sa_handler if the signal
261 if (sig
> MINTRAP
&& sig
< MAXTRAP
) {
262 sigemptyset(&act
.sa_mask
);
263 act
.sa_flags
= (sig
== SIGSEGV
) ? (SA_ONSTACK
| SA_SIGINFO
) : 0;
264 act
.sa_handler
= func
;
265 sigaction(sig
, &act
, &oact
);
269 trapflg
[sig
] |= SIGIGN
;
272 * Special case for signal zero, we can not obtain the previos
273 * action by calling sigaction, instead we save it in the variable
274 * psig0_func, so we can test it next time through this code
278 ret
= (psig0_func
!= func
);
281 ret
= (func
!= oact
.sa_handler
);
292 int rtmin
= (int)SIGRTMIN
;
293 int rtmax
= (int)SIGRTMAX
;
295 ss
.ss_size
= SIGSTKSZ
;
296 ss
.ss_sp
= sigsegv_stack
;
298 if (sigaltstack(&ss
, NULL
) == -1) {
299 error("sigaltstack(2) failed");
302 for (i
= 1; i
< MAXTRAP
; i
++) {
309 if (i
!= SIGSEGV
&& ignoring(i
))
311 handle(i
, sigval
[i
]);
315 * handle all the realtime signals
318 for (i
= rtmin
; i
<= rtmax
; i
++) {
349 trapnote
&= ~TRAPSET
;
351 if (trapflg
[i
] & TRAPSET
) {
352 trapflg
[i
] &= ~TRAPSET
;
353 if (t
= trapcom
[i
]) {
354 int savxit
= exitval
;
365 systrap(int argc
, char **argv
)
371 * print out the current action associated with each signal
372 * handled by the shell
375 for (sig
= 0; sig
< MAXTRAP
; sig
++) {
379 prs_buff(trapcom
[sig
]);
385 * set the action for the list of signals
388 char *cmd
= *argv
, *a1
= *(argv
+1);
390 noa1
= (str2sig(a1
, &sig
) == 0);
394 if (str2sig(*argv
, &sig
) < 0 ||
395 sig
>= MAXTRAP
|| sig
< MINTRAP
||
397 failure(cmd
, badtrap
);
400 * no action specifed so reset the siganl
401 * to its default disposition
407 * set the action associated with the signal
411 if (trapflg
[sig
] & SIGMOD
|| sig
== 0 ||
414 trapflg
[sig
] |= SIGMOD
;
415 replace(&trapcom
[sig
], a1
);
417 } else if (handle(sig
, SIG_IGN
)) {
419 * set the action associated with the signal
423 trapflg
[sig
] |= SIGMOD
;
424 replace(&trapcom
[sig
], a1
);
431 sh_sleep(unsigned int ticks
)
434 struct sigaction act
, oact
;
438 * add SIGALRM to mask
442 sigaddset(&set
, SIGALRM
);
443 sigprocmask(SIG_BLOCK
, &set
, &oset
);
449 sigemptyset(&act
.sa_mask
);
451 act
.sa_handler
= fault
;
452 sigaction(SIGALRM
, &act
, &oact
);
455 * start alarm and wait for signal
464 * reset alarm, catcher and mask
468 sigaction(SIGALRM
, &oact
, NULL
);
469 sigprocmask(SIG_SETMASK
, &oset
, 0);
474 sigsegv(int sig
, siginfo_t
*sip
, ucontext_t
*uap
)
476 if (sip
== (siginfo_t
*)NULL
) {
478 * This should never happen, but if it does this is all we
479 * can do. It can only happen if sigaction(2) for SIGSEGV
480 * has been called without SA_SIGINFO being set.
486 if (sip
->si_code
<= 0) {
488 * If we are here then SIGSEGV must have been sent to
489 * us from a user process NOT as a result of an
490 * internal error within the shell eg
492 * will bring us here. So do the normal thing.
498 * If we are here then there must have been an internal
499 * error within the shell to generate SIGSEGV eg
500 * the stack is full and we cannot call any more
501 * functions (Remeber this signal handler is running
502 * on an alternate stack). So we just exit cleanly
503 * with an error status (no core file).