aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-03-21 20:17:27 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-03-21 20:17:27 +0000
commit7c139b477882a06a86c31928d997d43c696dbc62 (patch)
treeca1e64745da7ff43f154ad6ea66c37f9e97840fb
parentb8e72fdde1186f41963697d57383c08402513ca8 (diff)
downloadbusybox-w32-7c139b477882a06a86c31928d997d43c696dbc62.tar.gz
busybox-w32-7c139b477882a06a86c31928d997d43c696dbc62.tar.bz2
busybox-w32-7c139b477882a06a86c31928d997d43c696dbc62.zip
ash: fix signal handling
-rw-r--r--shell/ash.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 29156c199..a5ffaaf8e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -183,7 +183,7 @@ static volatile sig_atomic_t intpending;
183/* do we generate EXSIG events */ 183/* do we generate EXSIG events */
184static int exsig; 184static int exsig;
185/* last pending signal */ 185/* last pending signal */
186static volatile sig_atomic_t pendingsigs; 186static volatile sig_atomic_t pendingsig;
187 187
188/* 188/*
189 * Sigmode records the current value of the signal handlers for the various 189 * Sigmode records the current value of the signal handlers for the various
@@ -239,8 +239,15 @@ static void
239raise_interrupt(void) 239raise_interrupt(void)
240{ 240{
241 int i; 241 int i;
242 sigset_t mask;
242 243
243 intpending = 0; 244 intpending = 0;
245 /* Signal is not automatically re-enabled after it is raised,
246 * do it ourself */
247 sigemptyset(&mask);
248 sigprocmask(SIG_SETMASK, &mask, 0);
249 /* pendingsig = 0; - now done in onsig() */
250
244 i = EXSIG; 251 i = EXSIG;
245 if (gotsig[SIGINT - 1] && !trap[SIGINT]) { 252 if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
246 if (!(rootshell && iflag)) { 253 if (!(rootshell && iflag)) {
@@ -300,7 +307,7 @@ force_int_on(void)
300 do { \ 307 do { \
301 exsig++; \ 308 exsig++; \
302 xbarrier(); \ 309 xbarrier(); \
303 if (pendingsigs) \ 310 if (pendingsig) \
304 raise_exception(EXSIG); \ 311 raise_exception(EXSIG); \
305 } while (0) 312 } while (0)
306/* EXSIG is turned off by evalbltin(). */ 313/* EXSIG is turned off by evalbltin(). */
@@ -324,11 +331,13 @@ static void
324onsig(int signo) 331onsig(int signo)
325{ 332{
326 gotsig[signo - 1] = 1; 333 gotsig[signo - 1] = 1;
327 pendingsigs = signo; 334 pendingsig = signo;
328 335
329 if (exsig || (signo == SIGINT && !trap[SIGINT])) { 336 if (exsig || (signo == SIGINT && !trap[SIGINT])) {
330 if (!suppressint) 337 if (!suppressint) {
338 pendingsig = 0;
331 raise_interrupt(); 339 raise_interrupt();
340 }
332 intpending = 1; 341 intpending = 1;
333 } 342 }
334} 343}
@@ -7441,7 +7450,7 @@ dotrap(void)
7441 int skip = 0; 7450 int skip = 0;
7442 7451
7443 savestatus = exitstatus; 7452 savestatus = exitstatus;
7444 pendingsigs = 0; 7453 pendingsig = 0;
7445 xbarrier(); 7454 xbarrier();
7446 7455
7447 for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) { 7456 for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
@@ -7580,7 +7589,7 @@ evaltree(union node *n, int flags)
7580 out: 7589 out:
7581 if ((checkexit & exitstatus)) 7590 if ((checkexit & exitstatus))
7582 evalskip |= SKIPEVAL; 7591 evalskip |= SKIPEVAL;
7583 else if (pendingsigs && dotrap()) 7592 else if (pendingsig && dotrap())
7584 goto exexit; 7593 goto exexit;
7585 7594
7586 if (flags & EV_EXIT) { 7595 if (flags & EV_EXIT) {
@@ -8447,7 +8456,7 @@ evalcommand(union node *cmd, int flags)
8447 if (i == EXINT) 8456 if (i == EXINT)
8448 j = SIGINT; 8457 j = SIGINT;
8449 if (i == EXSIG) 8458 if (i == EXSIG)
8450 j = pendingsigs; 8459 j = pendingsig;
8451 if (j) 8460 if (j)
8452 exit_status = j + 128; 8461 exit_status = j + 128;
8453 exitstatus = exit_status; 8462 exitstatus = exit_status;