mirror of
https://github.com/sheumann/hush.git
synced 2024-12-26 10:32:02 +00:00
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
This commit is contained in:
parent
4ea187fd62
commit
270b1c3f68
97
shell/hush.c
97
shell/hush.c
@ -939,6 +939,52 @@ static void free_strings(char **strings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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
|
/* Basic theory of signal handling in shell
|
||||||
* ========================================
|
* ========================================
|
||||||
* This does not describe what hush does, rather, it is current understanding
|
* This does not describe what hush does, rather, it is current understanding
|
||||||
@ -2802,54 +2848,24 @@ static void exec_function(nommu_save_t *nommu_save,
|
|||||||
|
|
||||||
static int run_function(const struct function *funcp, char **argv)
|
static int run_function(const struct function *funcp, char **argv)
|
||||||
{
|
{
|
||||||
int n;
|
int rc;
|
||||||
char **pp;
|
save_arg_t sv;
|
||||||
char *sv_argv0;
|
|
||||||
smallint sv_g_malloced;
|
|
||||||
int sv_g_argc;
|
|
||||||
char **sv_g_argv;
|
|
||||||
|
|
||||||
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 */
|
/* On MMU, funcp->body is always non-NULL */
|
||||||
#if !BB_MMU
|
#if !BB_MMU
|
||||||
if (!funcp->body) {
|
if (!funcp->body) {
|
||||||
/* Function defined by -F */
|
/* Function defined by -F */
|
||||||
parse_and_run_string(funcp->body_as_string);
|
parse_and_run_string(funcp->body_as_string);
|
||||||
n = G.last_exitcode;
|
rc = G.last_exitcode;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
n = run_list(funcp->body);
|
rc = run_list(funcp->body);
|
||||||
}
|
}
|
||||||
|
restore_G_args(&sv, argv);
|
||||||
|
|
||||||
if (G.global_args_malloced) {
|
return rc;
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -6659,6 +6675,7 @@ static int builtin_shift(char **argv)
|
|||||||
static int builtin_source(char **argv)
|
static int builtin_source(char **argv)
|
||||||
{
|
{
|
||||||
FILE *input;
|
FILE *input;
|
||||||
|
save_arg_t sv;
|
||||||
|
|
||||||
if (*++argv == NULL)
|
if (*++argv == NULL)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -6672,11 +6689,11 @@ static int builtin_source(char **argv)
|
|||||||
close_on_exec_on(fileno(input));
|
close_on_exec_on(fileno(input));
|
||||||
|
|
||||||
/* Now run the file */
|
/* Now run the file */
|
||||||
/* TODO: argv and argc are broken; need to save old G.global_argv
|
save_and_replace_G_args(&sv, argv);
|
||||||
* (pointer only is OK!) on this stack frame,
|
|
||||||
* set G.global_argv=argv+1, recurse, and restore. */
|
|
||||||
parse_and_run_file(input);
|
parse_and_run_file(input);
|
||||||
|
restore_G_args(&sv, argv);
|
||||||
fclose(input);
|
fclose(input);
|
||||||
|
|
||||||
return G.last_exitcode;
|
return G.last_exitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user