diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-15 23:29:44 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-15 23:29:44 +0000 |
commit | 74a931ac9ea807d14a44baf3fdb957bc58db14c6 (patch) | |
tree | 0d0f7ee4585a7e9bed445236f207a604818f1043 | |
parent | c4ada7934307c6ef0b5b207df13a54fecd4ad81d (diff) | |
download | busybox-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.c | 27 |
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 | ||
2277 | static void reset_traps_to_defaults(void) | 2277 | static 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 */ |