hush: report [v]fork failures
hush: more correct handling of piping config: add CONFIG_NOMMU
This commit is contained in:
parent
474d1c57c8
commit
d2c450ce81
11
Config.in
11
Config.in
@ -280,6 +280,17 @@ config STATIC
|
|||||||
|
|
||||||
Most people will leave this set to 'N'.
|
Most people will leave this set to 'N'.
|
||||||
|
|
||||||
|
config NOMMU
|
||||||
|
bool "Force NOMMU build"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Busybox tries to detect whether architecture it is being
|
||||||
|
built against supports MMU or not. If this detection fails,
|
||||||
|
or if you want to build NOMMU version of busybox for testing,
|
||||||
|
you may force NOMMU build here.
|
||||||
|
|
||||||
|
Most people will leave this set to 'N'.
|
||||||
|
|
||||||
config BUILD_LIBBUSYBOX
|
config BUILD_LIBBUSYBOX
|
||||||
bool "Build shared libbusybox"
|
bool "Build shared libbusybox"
|
||||||
default n
|
default n
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Busybox version: 1.9.0.svn
|
# Busybox version: 1.10.0.svn
|
||||||
# Mon Dec 24 14:21:28 2007
|
# Tue Jan 8 20:29:22 2008
|
||||||
#
|
#
|
||||||
CONFIG_HAVE_DOT_CONFIG=y
|
CONFIG_HAVE_DOT_CONFIG=y
|
||||||
|
|
||||||
@ -39,6 +39,7 @@ CONFIG_FEATURE_HAVE_RPC=y
|
|||||||
# Build Options
|
# Build Options
|
||||||
#
|
#
|
||||||
# CONFIG_STATIC is not set
|
# CONFIG_STATIC is not set
|
||||||
|
CONFIG_NOMMU=y
|
||||||
# CONFIG_BUILD_LIBBUSYBOX is not set
|
# CONFIG_BUILD_LIBBUSYBOX is not set
|
||||||
# CONFIG_FEATURE_INDIVIDUAL is not set
|
# CONFIG_FEATURE_INDIVIDUAL is not set
|
||||||
# CONFIG_FEATURE_SHARED_BUSYBOX is not set
|
# CONFIG_FEATURE_SHARED_BUSYBOX is not set
|
||||||
@ -222,6 +223,7 @@ CONFIG_FEATURE_STAT_FORMAT=y
|
|||||||
CONFIG_STTY=y
|
CONFIG_STTY=y
|
||||||
CONFIG_SUM=y
|
CONFIG_SUM=y
|
||||||
CONFIG_SYNC=y
|
CONFIG_SYNC=y
|
||||||
|
CONFIG_TAC=y
|
||||||
CONFIG_TAIL=y
|
CONFIG_TAIL=y
|
||||||
CONFIG_FEATURE_FANCY_TAIL=y
|
CONFIG_FEATURE_FANCY_TAIL=y
|
||||||
CONFIG_TEE=y
|
CONFIG_TEE=y
|
||||||
@ -368,6 +370,8 @@ CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
|
|||||||
# CONFIG_INIT is not set
|
# CONFIG_INIT is not set
|
||||||
# CONFIG_DEBUG_INIT is not set
|
# CONFIG_DEBUG_INIT is not set
|
||||||
# CONFIG_FEATURE_USE_INITTAB is not set
|
# CONFIG_FEATURE_USE_INITTAB is not set
|
||||||
|
# CONFIG_FEATURE_KILL_REMOVED is not set
|
||||||
|
CONFIG_FEATURE_KILL_DELAY=0
|
||||||
# CONFIG_FEATURE_INIT_SCTTY is not set
|
# CONFIG_FEATURE_INIT_SCTTY is not set
|
||||||
# CONFIG_FEATURE_INIT_SYSLOG is not set
|
# CONFIG_FEATURE_INIT_SYSLOG is not set
|
||||||
# CONFIG_FEATURE_EXTRA_QUIET is not set
|
# CONFIG_FEATURE_EXTRA_QUIET is not set
|
||||||
@ -679,6 +683,8 @@ CONFIG_FEATURE_PIDOF_OMIT=y
|
|||||||
CONFIG_PKILL=y
|
CONFIG_PKILL=y
|
||||||
CONFIG_PS=y
|
CONFIG_PS=y
|
||||||
CONFIG_FEATURE_PS_WIDE=y
|
CONFIG_FEATURE_PS_WIDE=y
|
||||||
|
CONFIG_FEATURE_PS_TIME=y
|
||||||
|
# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
|
||||||
CONFIG_RENICE=y
|
CONFIG_RENICE=y
|
||||||
CONFIG_BB_SYSCTL=y
|
CONFIG_BB_SYSCTL=y
|
||||||
CONFIG_TOP=y
|
CONFIG_TOP=y
|
||||||
@ -713,7 +719,7 @@ CONFIG_FEATURE_SH_IS_NONE=y
|
|||||||
# CONFIG_ASH_EXPAND_PRMT is not set
|
# CONFIG_ASH_EXPAND_PRMT is not set
|
||||||
CONFIG_HUSH=y
|
CONFIG_HUSH=y
|
||||||
CONFIG_HUSH_HELP=y
|
CONFIG_HUSH_HELP=y
|
||||||
# CONFIG_HUSH_INTERACTIVE is not set
|
CONFIG_HUSH_INTERACTIVE=y
|
||||||
# CONFIG_HUSH_JOB is not set
|
# CONFIG_HUSH_JOB is not set
|
||||||
CONFIG_HUSH_TICK=y
|
CONFIG_HUSH_TICK=y
|
||||||
CONFIG_HUSH_IF=y
|
CONFIG_HUSH_IF=y
|
||||||
|
@ -231,8 +231,9 @@ typedef unsigned smalluint;
|
|||||||
* for a mmu-less system; the user should pass EXTRA_CFLAGS="-DBB_NOMMU"
|
* for a mmu-less system; the user should pass EXTRA_CFLAGS="-DBB_NOMMU"
|
||||||
* on his own.
|
* on his own.
|
||||||
*/
|
*/
|
||||||
#if defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \
|
#if ENABLE_NOMMU || \
|
||||||
__UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__
|
(defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \
|
||||||
|
__UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__)
|
||||||
#define BB_MMU 0
|
#define BB_MMU 0
|
||||||
#define BB_NOMMU 1
|
#define BB_NOMMU 1
|
||||||
#define USE_FOR_NOMMU(...) __VA_ARGS__
|
#define USE_FOR_NOMMU(...) __VA_ARGS__
|
||||||
|
62
shell/hush.c
62
shell/hush.c
@ -1777,8 +1777,8 @@ static int checkjobs_and_fg_shell(struct pipe* fg_pipe)
|
|||||||
static int run_pipe_real(struct pipe *pi)
|
static int run_pipe_real(struct pipe *pi)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int nextin, nextout;
|
int nextin;
|
||||||
int pipefds[2]; /* pipefds[0] is for reading */
|
int pipefds[2]; /* pipefds[0] is for reading */
|
||||||
struct child_prog *child;
|
struct child_prog *child;
|
||||||
const struct built_in_command *x;
|
const struct built_in_command *x;
|
||||||
char *p;
|
char *p;
|
||||||
@ -1789,7 +1789,6 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
|
|
||||||
debug_printf_exec("run_pipe_real start: single_fg=%d\n", single_fg);
|
debug_printf_exec("run_pipe_real start: single_fg=%d\n", single_fg);
|
||||||
|
|
||||||
nextin = 0;
|
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
pi->pgrp = -1;
|
pi->pgrp = -1;
|
||||||
#endif
|
#endif
|
||||||
@ -1874,13 +1873,14 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Going to fork a child per each pipe member */
|
|
||||||
pi->running_progs = 0;
|
|
||||||
|
|
||||||
/* Disable job control signals for shell (parent) and
|
/* Disable job control signals for shell (parent) and
|
||||||
* for initial child code after fork */
|
* for initial child code after fork */
|
||||||
set_jobctrl_sighandler(SIG_IGN);
|
set_jobctrl_sighandler(SIG_IGN);
|
||||||
|
|
||||||
|
/* Going to fork a child per each pipe member */
|
||||||
|
pi->running_progs = 0;
|
||||||
|
nextin = 0;
|
||||||
|
|
||||||
for (i = 0; i < pi->num_progs; i++) {
|
for (i = 0; i < pi->num_progs; i++) {
|
||||||
child = &(pi->progs[i]);
|
child = &(pi->progs[i]);
|
||||||
if (child->argv)
|
if (child->argv)
|
||||||
@ -1889,24 +1889,20 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
debug_printf_exec(": pipe member with no argv\n");
|
debug_printf_exec(": pipe member with no argv\n");
|
||||||
|
|
||||||
/* pipes are inserted between pairs of commands */
|
/* pipes are inserted between pairs of commands */
|
||||||
if ((i + 1) < pi->num_progs) {
|
pipefds[0] = 0;
|
||||||
pipe(pipefds);
|
pipefds[1] = 1;
|
||||||
nextout = pipefds[1];
|
if ((i + 1) < pi->num_progs)
|
||||||
} else {
|
xpipe(pipefds);
|
||||||
nextout = 1;
|
|
||||||
pipefds[0] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX test for failed fork()? */
|
|
||||||
#if BB_MMU
|
#if BB_MMU
|
||||||
child->pid = fork();
|
child->pid = fork();
|
||||||
#else
|
#else
|
||||||
child->pid = vfork();
|
child->pid = vfork();
|
||||||
#endif
|
#endif
|
||||||
if (!child->pid) { /* child */
|
if (!child->pid) { /* child */
|
||||||
|
#if ENABLE_HUSH_JOB
|
||||||
/* Every child adds itself to new process group
|
/* Every child adds itself to new process group
|
||||||
* with pgid == pid of first child in pipe */
|
* with pgid == pid of first child in pipe */
|
||||||
#if ENABLE_HUSH_JOB
|
|
||||||
if (run_list_level == 1 && interactive_fd) {
|
if (run_list_level == 1 && interactive_fd) {
|
||||||
/* Don't do pgrp restore anymore on fatal signals */
|
/* Don't do pgrp restore anymore on fatal signals */
|
||||||
set_fatal_sighandler(SIG_DFL);
|
set_fatal_sighandler(SIG_DFL);
|
||||||
@ -1919,12 +1915,10 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* in non-interactive case fatal sigs are already SIG_DFL */
|
|
||||||
xmove_fd(nextin, 0);
|
xmove_fd(nextin, 0);
|
||||||
xmove_fd(nextout, 1);
|
xmove_fd(pipefds[1], 1); /* write end */
|
||||||
if (pipefds[0] != -1) {
|
if (pipefds[0] > 1)
|
||||||
close(pipefds[0]); /* opposite end of our output pipe */
|
close(pipefds[0]); /* read end */
|
||||||
}
|
|
||||||
/* Like bash, explicit redirects override pipes,
|
/* Like bash, explicit redirects override pipes,
|
||||||
* and the pipe fd is available for dup'ing. */
|
* and the pipe fd is available for dup'ing. */
|
||||||
setup_redirects(child, NULL);
|
setup_redirects(child, NULL);
|
||||||
@ -1933,25 +1927,29 @@ static int run_pipe_real(struct pipe *pi)
|
|||||||
set_jobctrl_sighandler(SIG_DFL);
|
set_jobctrl_sighandler(SIG_DFL);
|
||||||
set_misc_sighandler(SIG_DFL);
|
set_misc_sighandler(SIG_DFL);
|
||||||
signal(SIGCHLD, SIG_DFL);
|
signal(SIGCHLD, SIG_DFL);
|
||||||
pseudo_exec(child);
|
pseudo_exec(child); /* does not return */
|
||||||
}
|
}
|
||||||
|
|
||||||
pi->running_progs++;
|
if (child->pid < 0) { /* [v]fork failed */
|
||||||
|
/* Clearly indicate, was it fork or vfork */
|
||||||
|
bb_perror_msg(BB_MMU ? "cannot fork" : "cannot vfork");
|
||||||
|
} else {
|
||||||
|
pi->running_progs++;
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
/* Second and next children need to know pid of first one */
|
/* Second and next children need to know pid of first one */
|
||||||
if (pi->pgrp < 0)
|
if (pi->pgrp < 0)
|
||||||
pi->pgrp = child->pid;
|
pi->pgrp = child->pid;
|
||||||
#endif
|
#endif
|
||||||
if (nextin != 0)
|
}
|
||||||
close(nextin);
|
|
||||||
if (nextout != 1)
|
|
||||||
close(nextout);
|
|
||||||
|
|
||||||
/* If there isn't another process, nextin is garbage
|
if (i)
|
||||||
but it doesn't matter */
|
close(nextin);
|
||||||
|
if ((i + 1) < pi->num_progs)
|
||||||
|
close(pipefds[1]); /* write end */
|
||||||
|
/* Pass read (output) pipe end to next iteration */
|
||||||
nextin = pipefds[0];
|
nextin = pipefds[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_printf_exec("run_pipe_real return -1\n");
|
debug_printf_exec("run_pipe_real return -1\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user