hush: report [v]fork failures

hush: more correct handling of piping
config: add CONFIG_NOMMU
This commit is contained in:
Denis Vlasenko 2008-01-08 20:32:12 +00:00
parent 474d1c57c8
commit d2c450ce81
4 changed files with 53 additions and 37 deletions

View File

@ -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

View File

@ -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

View File

@ -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__

View File

@ -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;
} }