svn commit: [26138] trunk/busybox/shell
vda at busybox.net
vda at busybox.net
Fri Apr 17 18:54:50 UTC 2009
Author: vda
Date: 2009-04-17 18:54:50 +0000 (Fri, 17 Apr 2009)
New Revision: 26138
Log:
hush: set $n properly for "source" builtin
function old new delta
restore_G_args - 78 +78
save_and_replace_G_args - 64 +64
builtin_source 72 107 +35
run_list 2549 2367 -182
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 1/1 up/down: 177/-182) Total: -5 bytes
Modified:
trunk/busybox/shell/hush.c
Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c 2009-04-17 18:17:33 UTC (rev 26137)
+++ trunk/busybox/shell/hush.c 2009-04-17 18:54:50 UTC (rev 26138)
@@ -939,6 +939,52 @@
}
+/* Helpers for setting new $n and restoring them back
+ */
+typedef struct save_arg_t {
+ char *sv_argv0;
+ char **sv_g_argv;
+ int sv_g_argc;
+ smallint sv_g_malloced;
+} save_arg_t;
+
+static void save_and_replace_G_args(save_arg_t *sv, char **argv)
+{
+ int n;
+
+ sv->sv_argv0 = argv[0];
+ sv->sv_g_argv = G.global_argv;
+ sv->sv_g_argc = G.global_argc;
+ sv->sv_g_malloced = G.global_args_malloced;
+
+ argv[0] = G.global_argv[0]; /* retain $0 */
+ G.global_argv = argv;
+ G.global_args_malloced = 0;
+
+ n = 1;
+ while (*++argv)
+ n++;
+ G.global_argc = n;
+}
+
+static void restore_G_args(save_arg_t *sv, char **argv)
+{
+ char **pp;
+
+ if (G.global_args_malloced) {
+ /* someone ran "set -- arg1 arg2 ...", undo */
+ pp = G.global_argv;
+ while (*++pp) /* note: does not free $0 */
+ free(*pp);
+ free(G.global_argv);
+ }
+ argv[0] = sv->sv_argv0;
+ G.global_argv = sv->sv_g_argv;
+ G.global_argc = sv->sv_g_argc;
+ G.global_args_malloced = sv->sv_g_malloced;
+}
+
+
/* Basic theory of signal handling in shell
* ========================================
* This does not describe what hush does, rather, it is current understanding
@@ -2802,54 +2848,24 @@
static int run_function(const struct function *funcp, char **argv)
{
- int n;
- char **pp;
- char *sv_argv0;
- smallint sv_g_malloced;
- int sv_g_argc;
- char **sv_g_argv;
+ int rc;
+ save_arg_t sv;
- sv_argv0 = argv[0];
- sv_g_malloced = G.global_args_malloced;
- sv_g_argc = G.global_argc;
- sv_g_argv = G.global_argv;
-
- pp = argv;
- n = 1;
- while (*++pp)
- n++;
-
- argv[0] = G.global_argv[0]; /* retain $0 */
- G.global_args_malloced = 0;
- G.global_argc = n;
- G.global_argv = argv;
-
+ save_and_replace_G_args(&sv, argv);
/* On MMU, funcp->body is always non-NULL */
#if !BB_MMU
if (!funcp->body) {
/* Function defined by -F */
parse_and_run_string(funcp->body_as_string);
- n = G.last_exitcode;
+ rc = G.last_exitcode;
} else
#endif
{
- n = run_list(funcp->body);
+ rc = run_list(funcp->body);
}
+ restore_G_args(&sv, argv);
- if (G.global_args_malloced) {
- /* function ran "set -- arg1 arg2 ..." */
- pp = G.global_argv;
- while (*++pp)
- free(*pp);
- free(G.global_argv);
- }
-
- argv[0] = sv_argv0;
- G.global_args_malloced = sv_g_malloced;
- G.global_argc = sv_g_argc;
- G.global_argv = sv_g_argv;
-
- return n;
+ return rc;
}
#endif
@@ -6659,6 +6675,7 @@
static int builtin_source(char **argv)
{
FILE *input;
+ save_arg_t sv;
if (*++argv == NULL)
return EXIT_FAILURE;
@@ -6672,11 +6689,11 @@
close_on_exec_on(fileno(input));
/* Now run the file */
- /* TODO: argv and argc are broken; need to save old G.global_argv
- * (pointer only is OK!) on this stack frame,
- * set G.global_argv=argv+1, recurse, and restore. */
+ save_and_replace_G_args(&sv, argv);
parse_and_run_file(input);
+ restore_G_args(&sv, argv);
fclose(input);
+
return G.last_exitcode;
}
More information about the busybox-cvs
mailing list