pass a copy of argv[i] to NOFORK applets (they may permute it etc).
set/save/restore more shared global variables whan call one applet from another
This commit is contained in:
parent
c98c31783c
commit
831a20f512
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE
|
#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE
|
||||||
/* Define usage_messages[] */
|
/* Define usage_messages[] */
|
||||||
static const char usage_messages[] =
|
static const char usage_messages[] = ""
|
||||||
#define MAKE_USAGE
|
#define MAKE_USAGE
|
||||||
#include "usage.h"
|
#include "usage.h"
|
||||||
#include "applets.h"
|
#include "applets.h"
|
||||||
@ -590,6 +590,10 @@ static int busybox_main(int argc, char **argv)
|
|||||||
|
|
||||||
void run_current_applet_and_exit(int argc, char **argv)
|
void run_current_applet_and_exit(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
/* Reinit some shared global data */
|
||||||
|
optind = 1;
|
||||||
|
xfunc_error_retval = EXIT_FAILURE;
|
||||||
|
|
||||||
applet_name = current_applet->name;
|
applet_name = current_applet->name;
|
||||||
if (argc == 2 && !strcmp(argv[1], "--help"))
|
if (argc == 2 && !strcmp(argv[1], "--help"))
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
|
@ -119,11 +119,16 @@ int spawn_and_wait(char **argv)
|
|||||||
if (a->nofork)
|
if (a->nofork)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int old_sleep = die_sleep;
|
/* Save some shared globals */
|
||||||
|
const struct bb_applet *old_a = current_applet;
|
||||||
int old_x = xfunc_error_retval;
|
int old_x = xfunc_error_retval;
|
||||||
uint32_t old_m = option_mask32;
|
uint32_t old_m = option_mask32;
|
||||||
|
int old_sleep = die_sleep;
|
||||||
|
|
||||||
|
current_applet = a;
|
||||||
|
applet_name = a->name;
|
||||||
xfunc_error_retval = EXIT_FAILURE;
|
xfunc_error_retval = EXIT_FAILURE;
|
||||||
|
/*option_mask32 = 0; - not needed */
|
||||||
/* special flag for xfunc_die(). If xfunc will "die"
|
/* special flag for xfunc_die(). If xfunc will "die"
|
||||||
* in NOFORK applet, xfunc_die() sees negative
|
* in NOFORK applet, xfunc_die() sees negative
|
||||||
* die_sleep and longjmp here instead. */
|
* die_sleep and longjmp here instead. */
|
||||||
@ -131,25 +136,24 @@ int spawn_and_wait(char **argv)
|
|||||||
|
|
||||||
rc = setjmp(die_jmp);
|
rc = setjmp(die_jmp);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
const struct bb_applet *old_a = current_applet;
|
/* Some callers (xargs)
|
||||||
current_applet = a;
|
* need argv untouched because they free argv[i]! */
|
||||||
applet_name = a->name;
|
char *tmp_argv[argc+1];
|
||||||
// what else should we save/restore?
|
memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
|
||||||
// TODO: what if applet will mangle argv vector?
|
/* Finally we can call NOFORK applet's main() */
|
||||||
// xargs needs argv untouched because it frees argv[i]!
|
rc = a->main(argc, tmp_argv);
|
||||||
// shouldn't we pass a copy?
|
} else { /* xfunc died in NOFORK applet */
|
||||||
rc = a->main(argc, argv);
|
/* in case they meant to return 0... */
|
||||||
current_applet = old_a;
|
|
||||||
applet_name = old_a->name;
|
|
||||||
} else {
|
|
||||||
/* xfunc died in NOFORK applet */
|
|
||||||
if (rc == -111)
|
if (rc == -111)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
die_sleep = old_sleep;
|
/* Restoring globals */
|
||||||
|
current_applet = old_a;
|
||||||
|
applet_name = old_a->name;
|
||||||
xfunc_error_retval = old_x;
|
xfunc_error_retval = old_x;
|
||||||
option_mask32 = old_m;
|
option_mask32 = old_m;
|
||||||
|
die_sleep = old_sleep;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#if BB_MMU
|
#if BB_MMU
|
||||||
|
@ -1119,8 +1119,7 @@ static void pseudo_exec(struct child_prog *child)
|
|||||||
|
|
||||||
/* Count argc for use in a second... */
|
/* Count argc for use in a second... */
|
||||||
for (argc_l = 0; *argv_l; argv_l++, argc_l++)
|
for (argc_l = 0; *argv_l; argv_l++, argc_l++)
|
||||||
/**/;
|
continue;
|
||||||
optind = 1;
|
|
||||||
debug_printf("running applet %s\n", name);
|
debug_printf("running applet %s\n", name);
|
||||||
run_applet_and_exit(name, argc_l, child->argv);
|
run_applet_and_exit(name, argc_l, child->argv);
|
||||||
}
|
}
|
||||||
|
20
shell/lash.c
20
shell/lash.c
@ -32,6 +32,7 @@
|
|||||||
#define ENABLE_LASH_PIPE_N_REDIRECTS 1
|
#define ENABLE_LASH_PIPE_N_REDIRECTS 1
|
||||||
#define ENABLE_LASH_JOB_CONTROL 1
|
#define ENABLE_LASH_JOB_CONTROL 1
|
||||||
|
|
||||||
|
|
||||||
enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
|
enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
|
||||||
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
|
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
|
||||||
|
|
||||||
@ -408,12 +409,12 @@ static int builtin_read(struct child_prog *child)
|
|||||||
** the string resides in a static buffer!)
|
** the string resides in a static buffer!)
|
||||||
*/
|
*/
|
||||||
res = -1;
|
res = -1;
|
||||||
if ((s = strdup(string)))
|
s = strdup(string);
|
||||||
|
if (s)
|
||||||
res = putenv(s);
|
res = putenv(s);
|
||||||
if (res)
|
if (res)
|
||||||
bb_perror_msg("read");
|
bb_perror_msg("read");
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
fgets(string, sizeof(string), stdin);
|
fgets(string, sizeof(string), stdin);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -1167,8 +1168,8 @@ static int pseudo_exec(struct child_prog *child)
|
|||||||
char **argv_l = child->argv;
|
char **argv_l = child->argv;
|
||||||
int argc_l;
|
int argc_l;
|
||||||
|
|
||||||
for (argc_l = 0; *argv_l; argv_l++, argc_l++);
|
for (argc_l = 0; *argv_l; argv_l++, argc_l++)
|
||||||
optind = 1;
|
continue;
|
||||||
run_applet_and_exit(child->argv[0], argc_l, child->argv);
|
run_applet_and_exit(child->argv[0], argc_l, child->argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,11 +1276,11 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
|
#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
|
||||||
if (!(child->pid = fork()))
|
child->pid = fork();
|
||||||
#else
|
#else
|
||||||
if (!(child->pid = vfork()))
|
child->pid = vfork();
|
||||||
#endif
|
#endif
|
||||||
{
|
if (!child->pid) {
|
||||||
/* Set the handling for job control signals back to the default. */
|
/* Set the handling for job control signals back to the default. */
|
||||||
signal(SIGINT, SIG_DFL);
|
signal(SIGINT, SIG_DFL);
|
||||||
signal(SIGQUIT, SIG_DFL);
|
signal(SIGQUIT, SIG_DFL);
|
||||||
@ -1474,7 +1475,8 @@ static void setup_job_control(void)
|
|||||||
|
|
||||||
/* Loop until we are in the foreground. */
|
/* Loop until we are in the foreground. */
|
||||||
while ((status = tcgetpgrp(shell_terminal)) >= 0) {
|
while ((status = tcgetpgrp(shell_terminal)) >= 0) {
|
||||||
if (status == (shell_pgrp = getpgrp ())) {
|
shell_pgrp = getpgrp();
|
||||||
|
if (status == shell_pgrp) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
kill(- shell_pgrp, SIGTTIN);
|
kill(- shell_pgrp, SIGTTIN);
|
||||||
|
@ -3065,7 +3065,6 @@ static const char *rexecve(char *c, char **v, char **envp)
|
|||||||
char *name = c;
|
char *name = c;
|
||||||
|
|
||||||
if (ENABLE_FEATURE_SH_STANDALONE) {
|
if (ENABLE_FEATURE_SH_STANDALONE) {
|
||||||
optind = 1;
|
|
||||||
if (find_applet_by_name(name)) {
|
if (find_applet_by_name(name)) {
|
||||||
/* We have to exec here since we vforked. Running
|
/* We have to exec here since we vforked. Running
|
||||||
* run_applet_and_exit() won't work and bad things
|
* run_applet_and_exit() won't work and bad things
|
||||||
|
Loading…
Reference in New Issue
Block a user