ash: add FEATURE_SH_NOFORK support
authorDenis Vlasenko <vda.linux@googlemail.com>
Sat, 12 Apr 2008 20:07:53 +0000 (20:07 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Sat, 12 Apr 2008 20:07:53 +0000 (20:07 -0000)
shell/Config.in
shell/ash.c

index 40e0217f4c0a17376d5e5c062f543960c4d13ee7..94ffa09f870c384f9dc777437b0e1112bd6fd04e 100644 (file)
@@ -287,6 +287,23 @@ config FEATURE_SH_STANDALONE
 #        that exact location with that exact name, this option will not work at
 #        all.
 
+config FEATURE_SH_NOFORK
+       bool "Run 'nofork' applets directly"
+       default n
+       depends on (MSH || LASH || HUSH || ASH) && FEATURE_PREFER_APPLETS
+       help
+         This option causes busybox shells [currently only ash]
+         to not execute typical fork/exec/wait sequence, but call <applet>_main
+         directly, if possible. (Sometimes it is not possible: for example,
+         this is not possible in pipes).
+
+         This will be done only for some applets (those which are marked
+         NOFORK in include/applets.h).
+
+         This may significantly speed up some shell scripts.
+
+         This feature is relatively new. Use with care.
+
 config CTTYHACK
        bool "cttyhack"
        default n
index 0872e681a2e7ea08acd000923b1f60381bc96256..cc61401d10ef0edfdca11d6f60f74b1ff4783a1c 100644 (file)
@@ -8747,6 +8747,24 @@ evalcommand(union node *cmd, int flags)
        /* Execute the command. */
        switch (cmdentry.cmdtype) {
        default:
+
+#if ENABLE_FEATURE_SH_NOFORK
+               {
+               /* TODO: don't rerun find_applet_by_name, find_command
+                * already did it. Make it save applet_no somewhere */
+               int applet_no = find_applet_by_name(argv[0]);
+               if (applet_no >= 0 && APPLET_IS_NOFORK(applet_no)) {
+                       struct nofork_save_area nofork_save;
+
+                       listsetvar(varlist.list, VEXPORT|VSTACK);
+                       save_nofork_data(&nofork_save);
+                       /* run <applet>_main(), then restore nofork_save_area */
+                       exitstatus = run_nofork_applet_prime(&nofork_save, applet_no, argv) & 0xff;
+                       break;
+               }
+               }
+#endif
+
                /* Fork off a child process if necessary. */
                if (!(flags & EV_EXIT) || trap[0]) {
                        INT_OFF;