aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2017-08-01 19:47:20 +0100
committerRon Yorston <rmy@pobox.com>2017-08-01 19:47:20 +0100
commitf5051d07f196a8ff7aeaae762333d5aa2b824088 (patch)
tree3b61563a88c7fe57fddc4bc24a6a42b7ea755c21
parent2a210715a9a85fb48cf8f636c74e63f54605eedc (diff)
downloadbusybox-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.h3
-rw-r--r--libbb/appletlib.c16
-rw-r--r--shell/ash.c10
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;
1145extern int find_applet_by_name(const char *name) FAST_FUNC; 1145extern int find_applet_by_name(const char *name) FAST_FUNC;
1146extern void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; 1146extern 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
1149extern 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
314int 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
314void lbb_prepare(const char *applet 330void 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);