svn commit: trunk/busybox: libbb shell

vda at busybox.net vda at busybox.net
Sun Apr 13 02:25:54 UTC 2008


Author: vda
Date: 2008-04-12 19:25:53 -0700 (Sat, 12 Apr 2008)
New Revision: 21724

Log:
ash: speed up NOFORK code in ash by eliminating second find_applet().
some code reduction along the way.

function                                             old     new   delta
run_list                                            1971    1981     +10
run_nofork_applet_prime                              181     182      +1
unsetcmd                                              97      96      -1
delete_cmd_entry                                      54      53      -1
describe_command                                     399     397      -2
cmdlookup                                            152     150      -2
evaltreenr                                           602     599      -3
evaltree                                             602     599      -3
clearcmdentry                                        101      98      -3
cdcmd                                                675     672      -3
hashcmd                                              305     301      -4
find_command                                         933     910     -23
evalcommand                                         1371    1229    -142
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/11 up/down: 11/-187)         Total: -176 bytes



Modified:
   trunk/busybox/libbb/vfork_daemon_rexec.c
   trunk/busybox/shell/ash.c
   trunk/busybox/shell/hush.c


Changeset:
Modified: trunk/busybox/libbb/vfork_daemon_rexec.c
===================================================================
--- trunk/busybox/libbb/vfork_daemon_rexec.c	2008-04-12 23:02:43 UTC (rev 21723)
+++ trunk/busybox/libbb/vfork_daemon_rexec.c	2008-04-13 02:25:53 UTC (rev 21724)
@@ -146,6 +146,15 @@
 		memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
 		/* Finally we can call NOFORK applet's main() */
 		rc = applet_main[applet_no](argc, tmp_argv);
+
+	/* The whole reason behind nofork_save_area is that <applet>_main
+	 * may exit non-locally! For example, in hush Ctrl-Z tries to
+	 * (modulo bugs) to dynamically create child (backgrounded task)
+	 * if it detects that Ctrl-Z was pressed when a NOFORK was running!
+	 * Testcase: interactive "rm -i".
+	 * Don't fool yourself into thinking "and <applet>_main() returns
+	 * quickly here" and removing "useless" nofork_save_area code. */
+
 	} else { /* xfunc died in NOFORK applet */
 		/* in case they meant to return 0... */
 		if (rc == -2222)
@@ -154,7 +163,7 @@
 
 	/* Restoring globals */
 	restore_nofork_data(old);
-	return rc;
+	return rc & 0xff; /* don't confuse people with "exitcodes" >255 */
 }
 
 int run_nofork_applet(int applet_no, char **argv)

Modified: trunk/busybox/shell/ash.c
===================================================================
--- trunk/busybox/shell/ash.c	2008-04-12 23:02:43 UTC (rev 21723)
+++ trunk/busybox/shell/ash.c	2008-04-13 02:25:53 UTC (rev 21724)
@@ -6828,9 +6828,13 @@
 #define IS_BUILTIN_ASSIGN(b)  ((b)->name[0] & 4)
 
 struct cmdentry {
-	int cmdtype;
+	smallint cmdtype;       /* CMDxxx */
 	union param {
 		int index;
+		/* index >= 0 for commands without path (slashes) */
+		/* (TODO: what exactly does the value mean? PATH position?) */
+		/* index == -1 for commands with slashes */
+		/* index == (-2 - applet_no) for NOFORK applets */
 		const struct builtincmd *cmd;
 		struct funcnode *func;
 	} u;
@@ -6867,7 +6871,7 @@
 struct tblentry {
 	struct tblentry *next;  /* next entry in hash chain */
 	union param param;      /* definition of builtin function */
-	short cmdtype;          /* index identifying command */
+	smallint cmdtype;       /* CMDxxx */
 	char rehash;            /* if set, cd done since entry created */
 	char cmdname[ARB];      /* name of command */
 };
@@ -7355,7 +7359,7 @@
 	case CMDNORMAL: {
 		int j = entry.u.index;
 		char *p;
-		if (j == -1) {
+		if (j < 0) {
 			p = command;
 		} else {
 			do {
@@ -8747,22 +8751,17 @@
 	/* 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]);
+	{
+		/* find_command() encodes applet_no as (-2 - applet_no) */
+		int applet_no = (- cmdentry.u.index - 2);
 		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;
+			/* run <applet>_main() */
+			exitstatus = run_nofork_applet(applet_no, argv);
 			break;
 		}
-		}
+	}
 #endif
 
 		/* Fork off a child process if necessary. */
@@ -11618,10 +11617,13 @@
 	}
 
 #if ENABLE_FEATURE_SH_STANDALONE
-	if (find_applet_by_name(name) >= 0) {
-		entry->cmdtype = CMDNORMAL;
-		entry->u.index = -1;
-		return;
+	{
+		int applet_no = find_applet_by_name(name);
+		if (applet_no >= 0) {
+			entry->cmdtype = CMDNORMAL;
+			entry->u.index = -2 - applet_no;
+			return;
+		}
 	}
 #endif
 
@@ -12691,7 +12693,7 @@
 	        || prec == PREC(TOK_CONDITIONAL));
 }
 
-typedef struct ARITCH_VAR_NUM {
+typedef struct {
 	arith_t val;
 	arith_t contidional_second_val;
 	char contidional_second_val_initialized;
@@ -12699,9 +12701,9 @@
 			   else is variable name */
 } v_n_t;
 
-typedef struct CHK_VAR_RECURSIVE_LOOPED {
+typedef struct chk_var_recursive_looped_t {
 	const char *var;
-	struct CHK_VAR_RECURSIVE_LOOPED *next;
+	struct chk_var_recursive_looped_t *next;
 } chk_var_recursive_looped_t;
 
 static chk_var_recursive_looped_t *prev_chk_var_recursive;

Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2008-04-12 23:02:43 UTC (rev 21723)
+++ trunk/busybox/shell/hush.c	2008-04-13 02:25:53 UTC (rev 21724)
@@ -1861,7 +1861,7 @@
 				//sp: if (child->sp)
 				argv_expanded = expand_strvec_to_strvec(argv + i);
 				debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]);
-				rcode = run_nofork_applet_prime(&nofork_save, a, argv_expanded) & 0xff;
+				rcode = run_nofork_applet_prime(&nofork_save, a, argv_expanded);
 				free(argv_expanded);
 				restore_redirects(squirrel);
 				debug_printf_exec("run_pipe return %d\n", rcode);




More information about the busybox-cvs mailing list