char **new_env;
char **old_env;
char **argv;
+ char **argv_from_re_execing;
} nommu_save_t;
#endif
char **global_argv;
#if !BB_MMU
char *argv0_for_re_execing;
- char **argv_from_re_execing;
#endif
#if ENABLE_HUSH_LOOPS
unsigned depth_break_continue;
#if BB_MMU
/* never called */
-void re_execute_shell(const char *s, char *argv0, char **argv);
-
-#define clean_up_after_re_execute() ((void)0)
+void re_execute_shell(char ***to_free, const char *s, char *argv0, char **argv);
static void reset_traps_to_defaults(void)
{
#else /* !BB_MMU */
-static void re_execute_shell(const char *s, char *g_argv0, char **g_argv) NORETURN;
-static void re_execute_shell(const char *s, char *g_argv0, char **g_argv)
+static void re_execute_shell(char ***to_free, const char *s, char *g_argv0, char **g_argv) NORETURN;
+static void re_execute_shell(char ***to_free, const char *s, char *g_argv0, char **g_argv)
{
char param_buf[sizeof("-$%x:%x:%x:%x") + sizeof(unsigned) * 4];
char *heredoc_argv[4];
pp = g_argv;
while (*pp++)
cnt++;
- G.argv_from_re_execing = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
+ *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt);
*pp++ = (char *) G.argv0_for_re_execing;
*pp++ = param_buf;
for (cur = G.top_var; cur; cur = cur->next) {
xfunc_error_retval = 127;
bb_error_msg_and_die("can't re-execute the shell");
}
-
-static void clean_up_after_re_execute(void)
-{
- char **pp = G.argv_from_re_execing;
- if (pp) {
- /* Must match re_execute_shell's allocations (if any) */
- free(pp);
- G.argv_from_re_execing = NULL;
- }
-}
#endif /* !BB_MMU */
/* the _body_ of heredoc (misleading field name) */
const char *heredoc = redir->rd_filename;
char *expanded;
+#if !BB_MMU
+ char **to_free;
+#endif
expanded = NULL;
if (!(redir->rd_dup & HEREDOC_QUOTED)) {
/* Delegate blocking writes to another process */
disable_restore_tty_pgrp_on_exit();
xmove_fd(pair.wr, STDOUT_FILENO);
- re_execute_shell(heredoc, NULL, NULL);
+ re_execute_shell(&to_free, heredoc, NULL, NULL);
#endif
}
/* parent */
enable_restore_tty_pgrp_on_exit();
- clean_up_after_re_execute();
+#if !BB_MMU
+ free(to_free);
+#endif
close(pair.wr);
free(expanded);
wait(NULL); /* wait till child has died */
return funcp;
}
-static void exec_function(const struct function *funcp, char **argv) NORETURN;
-static void exec_function(const struct function *funcp, char **argv)
+#if BB_MMU
+#define exec_function(nommu_save, funcp, argv) \
+ exec_function(funcp, argv)
+#endif
+static void exec_function(nommu_save_t *nommu_save,
+ const struct function *funcp,
+ char **argv) NORETURN;
+static void exec_function(nommu_save_t *nommu_save,
+ const struct function *funcp,
+ char **argv)
{
# if BB_MMU
int n = 1;
fflush(NULL);
_exit(n);
# else
- re_execute_shell(funcp->body_as_string, G.global_argv[0], argv + 1);
+ re_execute_shell(&nommu_save->argv_from_re_execing,
+ funcp->body_as_string,
+ G.global_argv[0],
+ argv + 1);
# endif
}
{
const struct function *funcp = find_function(argv[0]);
if (funcp) {
- exec_function(funcp, argv);
+ exec_function(nommu_save, funcp, argv);
}
}
#endif
* since this process is about to exit */
_exit(rcode);
#else
- re_execute_shell(command->group_as_string,
+ re_execute_shell(&nommu_save->argv_from_re_execing,
+ command->group_as_string,
G.global_argv[0],
G.global_argv + 1);
#endif
nommu_save.new_env = NULL;
nommu_save.old_env = NULL;
nommu_save.argv = NULL;
+ nommu_save.argv_from_re_execing = NULL;
#endif
command = &(pi->cmds[i]);
if (command->argv) {
enable_restore_tty_pgrp_on_exit();
#if !BB_MMU
/* Clean up after vforked child */
- clean_up_after_re_execute();
free(nommu_save.argv);
+ free(nommu_save.argv_from_re_execing);
free_strings_and_unsetenv(nommu_save.new_env, 1);
putenv_all(nommu_save.old_env);
/* Free the pointers, but the strings themselves
{
FILE *pf;
int pid, channel[2];
+#if !BB_MMU
+ char **to_free;
+#endif
xpipe(channel);
pid = BB_MMU ? fork() : vfork();
* huge=`cat BIG` # was blocking here forever
* echo OK
*/
- re_execute_shell(s,
+ re_execute_shell(&to_free,
+ s,
G.global_argv[0],
G.global_argv + 1);
#endif
/* parent */
enable_restore_tty_pgrp_on_exit();
- clean_up_after_re_execute();
+#if !BB_MMU
+ free(to_free);
+#endif
close(channel[1]);
pf = fdopen(channel[0], "r");
return pf;