diff options
author | Ron Yorston <rmy@pobox.com> | 2017-08-01 19:47:20 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2017-08-01 19:47:20 +0100 |
commit | f5051d07f196a8ff7aeaae762333d5aa2b824088 (patch) | |
tree | 3b61563a88c7fe57fddc4bc24a6a42b7ea755c21 | |
parent | 2a210715a9a85fb48cf8f636c74e63f54605eedc (diff) | |
download | busybox-w32-f5051d07f196a8ff7aeaae762333d5aa2b824088.tar.gz busybox-w32-f5051d07f196a8ff7aeaae762333d5aa2b824088.tar.bz2 busybox-w32-f5051d07f196a8ff7aeaae762333d5aa2b824088.zip |
ash: allow long-running nofork applets to be interrupted
Nofork applets can't be interrupted with ctrl-c. This isn't an
issue for most such applets because they do very little and won't
run for very long. However 'yes' and 'seq 10000000' can't be
interrupted in a interactive shell, which is awkward.
As a special case ignore the nofork-ness of these applets if they're
run from an interactive shell.
This isn't foolproof as there are still ways to run them such that
they can't be interrupted, but it helps.
-rw-r--r-- | include/libbb.h | 3 | ||||
-rw-r--r-- | libbb/appletlib.c | 16 | ||||
-rw-r--r-- | shell/ash.c | 10 |
3 files changed, 28 insertions, 1 deletions
diff --git a/include/libbb.h b/include/libbb.h index 105a0b988..a345a8f35 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1145,6 +1145,9 @@ int run_nofork_applet(int applet_no, char **argv) FAST_FUNC; | |||
1145 | extern int find_applet_by_name(const char *name) FAST_FUNC; | 1145 | extern int find_applet_by_name(const char *name) FAST_FUNC; |
1146 | extern void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; | 1146 | extern void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; |
1147 | #endif | 1147 | #endif |
1148 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_NOFORK | ||
1149 | extern int long_running_applet(int applet_no) FAST_FUNC; | ||
1150 | #endif | ||
1148 | 1151 | ||
1149 | /* Helpers for daemonization. | 1152 | /* Helpers for daemonization. |
1150 | * | 1153 | * |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 3cdf0c613..401475f18 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -310,6 +310,22 @@ int FAST_FUNC find_applet_by_name(const char *name) | |||
310 | #endif | 310 | #endif |
311 | } | 311 | } |
312 | 312 | ||
313 | # if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_NOFORK | ||
314 | int FAST_FUNC long_running_applet(int applet_no) | ||
315 | { | ||
316 | int ret = 0; | ||
317 | |||
318 | #if defined(APPLET_NO_seq) | ||
319 | ret |= (applet_no == APPLET_NO_seq); | ||
320 | #endif | ||
321 | #if defined(APPLET_NO_yes) | ||
322 | ret |= (applet_no == APPLET_NO_yes); | ||
323 | #endif | ||
324 | |||
325 | return ret; | ||
326 | } | ||
327 | #endif | ||
328 | |||
313 | 329 | ||
314 | void lbb_prepare(const char *applet | 330 | void lbb_prepare(const char *applet |
315 | IF_FEATURE_INDIVIDUAL(, char **argv)) | 331 | IF_FEATURE_INDIVIDUAL(, char **argv)) |
diff --git a/shell/ash.c b/shell/ash.c index 441da4d85..b06ed18f4 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -10268,7 +10268,15 @@ evalcommand(union node *cmd, int flags) | |||
10268 | */ | 10268 | */ |
10269 | /* find_command() encodes applet_no as (-2 - applet_no) */ | 10269 | /* find_command() encodes applet_no as (-2 - applet_no) */ |
10270 | int applet_no = (- cmdentry.u.index - 2); | 10270 | int applet_no = (- cmdentry.u.index - 2); |
10271 | if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) { | 10271 | if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no) |
10272 | #if ENABLE_PLATFORM_MINGW32 | ||
10273 | /* | ||
10274 | * Fork long-running nofork applets (e.g. yes) in interactive | ||
10275 | * sessions. Otherwise ctrl-c won't let the user kill them. | ||
10276 | */ | ||
10277 | && !(iflag && long_running_applet(applet_no)) | ||
10278 | #endif | ||
10279 | ) { | ||
10272 | listsetvar(varlist.list, VEXPORT|VSTACK); | 10280 | listsetvar(varlist.list, VEXPORT|VSTACK); |
10273 | /* run <applet>_main() */ | 10281 | /* run <applet>_main() */ |
10274 | status = run_nofork_applet(applet_no, argv); | 10282 | status = run_nofork_applet(applet_no, argv); |