aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-15 23:29:44 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-15 23:29:44 +0000
commit74a931ac9ea807d14a44baf3fdb957bc58db14c6 (patch)
tree0d0f7ee4585a7e9bed445236f207a604818f1043
parentc4ada7934307c6ef0b5b207df13a54fecd4ad81d (diff)
downloadbusybox-w32-74a931ac9ea807d14a44baf3fdb957bc58db14c6.tar.gz
busybox-w32-74a931ac9ea807d14a44baf3fdb957bc58db14c6.tar.bz2
busybox-w32-74a931ac9ea807d14a44baf3fdb957bc58db14c6.zip
hush: stop ignoring ^Z in child shells
-rw-r--r--shell/hush.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 16f304d81..a5d5741da 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2276,15 +2276,28 @@ void re_execute_shell(char ***to_free, const char *s, char *argv0, char **argv);
2276 2276
2277static void reset_traps_to_defaults(void) 2277static void reset_traps_to_defaults(void)
2278{ 2278{
2279 enum {
2280 JOBSIGS = (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP)
2281 };
2279 unsigned sig; 2282 unsigned sig;
2280 int dirty;
2281 2283
2282 if (!G.traps) 2284 if (!G.traps && !(G.non_DFL_mask & JOBSIGS))
2283 return; 2285 return;
2284 dirty = 0; 2286
2285 for (sig = 0; sig < NSIG; sig++) { 2287 /* This function is always called in a child shell.
2286 if (!G.traps[sig]) 2288 * Child shells are not interactive.
2289 * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling.
2290 * Testcase: (while :; do :; done) + ^Z should background.
2291 */
2292 G.non_DFL_mask &= ~JOBSIGS;
2293 sigdelset(&G.blocked_set, SIGTTIN);
2294 sigdelset(&G.blocked_set, SIGTTOU);
2295 sigdelset(&G.blocked_set, SIGTSTP);
2296
2297 if (G.traps) for (sig = 0; sig < NSIG; sig++) {
2298 if (!G.traps[sig]) {
2287 continue; 2299 continue;
2300 }
2288 free(G.traps[sig]); 2301 free(G.traps[sig]);
2289 G.traps[sig] = NULL; 2302 G.traps[sig] = NULL;
2290 /* There is no signal for 0 (EXIT) */ 2303 /* There is no signal for 0 (EXIT) */
@@ -2296,10 +2309,8 @@ static void reset_traps_to_defaults(void)
2296 if (sig < 32 && (G.non_DFL_mask & (1 << sig))) 2309 if (sig < 32 && (G.non_DFL_mask & (1 << sig)))
2297 continue; 2310 continue;
2298 sigdelset(&G.blocked_set, sig); 2311 sigdelset(&G.blocked_set, sig);
2299 dirty = 1;
2300 } 2312 }
2301 if (dirty) 2313 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
2302 sigprocmask(SIG_SETMASK, &G.blocked_set, NULL);
2303} 2314}
2304 2315
2305#else /* !BB_MMU */ 2316#else /* !BB_MMU */