summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2008-01-08 20:32:12 +0000
committerDenis Vlasenko2008-01-08 20:32:12 +0000
commitd2c450ce811454fb77679d049538530d2cf54dd8 (patch)
tree319d23806c17472026e0a946d6ae320f513e34c0
parent474d1c57c834ee3dee6de49f109c9b570236fa60 (diff)
downloadbusybox-d2c450ce811454fb77679d049538530d2cf54dd8.zip
busybox-d2c450ce811454fb77679d049538530d2cf54dd8.tar.gz
hush: report [v]fork failures
hush: more correct handling of piping config: add CONFIG_NOMMU
-rw-r--r--Config.in11
-rw-r--r--TODO_config_nommu12
-rw-r--r--include/platform.h5
-rw-r--r--shell/hush.c62
4 files changed, 53 insertions, 37 deletions
diff --git a/Config.in b/Config.in
index fa48ddd..d2bb632 100644
--- a/Config.in
+++ b/Config.in
@@ -280,6 +280,17 @@ config STATIC
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
bool "Build shared libbusybox"
default n
diff --git a/TODO_config_nommu b/TODO_config_nommu
index a4cc344..81db6db 100644
--- a/TODO_config_nommu
+++ b/TODO_config_nommu
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Busybox version: 1.9.0.svn
-# Mon Dec 24 14:21:28 2007
+# Busybox version: 1.10.0.svn
+# Tue Jan 8 20:29:22 2008
#
CONFIG_HAVE_DOT_CONFIG=y
@@ -39,6 +39,7 @@ CONFIG_FEATURE_HAVE_RPC=y
# Build Options
#
# CONFIG_STATIC is not set
+CONFIG_NOMMU=y
# CONFIG_BUILD_LIBBUSYBOX is not set
# CONFIG_FEATURE_INDIVIDUAL is not set
# CONFIG_FEATURE_SHARED_BUSYBOX is not set
@@ -222,6 +223,7 @@ CONFIG_FEATURE_STAT_FORMAT=y
CONFIG_STTY=y
CONFIG_SUM=y
CONFIG_SYNC=y
+CONFIG_TAC=y
CONFIG_TAIL=y
CONFIG_FEATURE_FANCY_TAIL=y
CONFIG_TEE=y
@@ -368,6 +370,8 @@ CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
# CONFIG_INIT is not set
# CONFIG_DEBUG_INIT 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_SYSLOG is not set
# CONFIG_FEATURE_EXTRA_QUIET is not set
@@ -679,6 +683,8 @@ CONFIG_FEATURE_PIDOF_OMIT=y
CONFIG_PKILL=y
CONFIG_PS=y
CONFIG_FEATURE_PS_WIDE=y
+CONFIG_FEATURE_PS_TIME=y
+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
CONFIG_RENICE=y
CONFIG_BB_SYSCTL=y
CONFIG_TOP=y
@@ -713,7 +719,7 @@ CONFIG_FEATURE_SH_IS_NONE=y
# CONFIG_ASH_EXPAND_PRMT is not set
CONFIG_HUSH=y
CONFIG_HUSH_HELP=y
-# CONFIG_HUSH_INTERACTIVE is not set
+CONFIG_HUSH_INTERACTIVE=y
# CONFIG_HUSH_JOB is not set
CONFIG_HUSH_TICK=y
CONFIG_HUSH_IF=y
diff --git a/include/platform.h b/include/platform.h
index edb0f8a..4c38c6a 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -231,8 +231,9 @@ typedef unsigned smalluint;
* for a mmu-less system; the user should pass EXTRA_CFLAGS="-DBB_NOMMU"
* on his own.
*/
-#if defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \
- __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__
+#if ENABLE_NOMMU || \
+ (defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \
+ __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__)
#define BB_MMU 0
#define BB_NOMMU 1
#define USE_FOR_NOMMU(...) __VA_ARGS__
diff --git a/shell/hush.c b/shell/hush.c
index b08fe10..9dc85d0 100644
--- a/shell/hush.c
+++ b/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)
{
int i;
- int nextin, nextout;
- int pipefds[2]; /* pipefds[0] is for reading */
+ int nextin;
+ int pipefds[2]; /* pipefds[0] is for reading */
struct child_prog *child;
const struct built_in_command *x;
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);
- nextin = 0;
#if ENABLE_HUSH_JOB
pi->pgrp = -1;
#endif
@@ -1874,13 +1873,14 @@ static int run_pipe_real(struct pipe *pi)
#endif
}
- /* Going to fork a child per each pipe member */
- pi->running_progs = 0;
-
/* Disable job control signals for shell (parent) and
* for initial child code after fork */
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++) {
child = &(pi->progs[i]);
if (child->argv)
@@ -1889,24 +1889,20 @@ static int run_pipe_real(struct pipe *pi)
debug_printf_exec(": pipe member with no argv\n");
/* pipes are inserted between pairs of commands */
- if ((i + 1) < pi->num_progs) {
- pipe(pipefds);
- nextout = pipefds[1];
- } else {
- nextout = 1;
- pipefds[0] = -1;
- }
+ pipefds[0] = 0;
+ pipefds[1] = 1;
+ if ((i + 1) < pi->num_progs)
+ xpipe(pipefds);
- /* XXX test for failed fork()? */
#if BB_MMU
child->pid = fork();
#else
child->pid = vfork();
#endif
if (!child->pid) { /* child */
+#if ENABLE_HUSH_JOB
/* Every child adds itself to new process group
* with pgid == pid of first child in pipe */
-#if ENABLE_HUSH_JOB
if (run_list_level == 1 && interactive_fd) {
/* Don't do pgrp restore anymore on fatal signals */
set_fatal_sighandler(SIG_DFL);
@@ -1919,12 +1915,10 @@ static int run_pipe_real(struct pipe *pi)
}
}
#endif
- /* in non-interactive case fatal sigs are already SIG_DFL */
xmove_fd(nextin, 0);
- xmove_fd(nextout, 1);
- if (pipefds[0] != -1) {
- close(pipefds[0]); /* opposite end of our output pipe */
- }
+ xmove_fd(pipefds[1], 1); /* write end */
+ if (pipefds[0] > 1)
+ close(pipefds[0]); /* read end */
/* Like bash, explicit redirects override pipes,
* and the pipe fd is available for dup'ing. */
setup_redirects(child, NULL);
@@ -1933,25 +1927,29 @@ static int run_pipe_real(struct pipe *pi)
set_jobctrl_sighandler(SIG_DFL);
set_misc_sighandler(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
- /* Second and next children need to know pid of first one */
- if (pi->pgrp < 0)
- pi->pgrp = child->pid;
+ /* Second and next children need to know pid of first one */
+ if (pi->pgrp < 0)
+ pi->pgrp = child->pid;
#endif
- if (nextin != 0)
- close(nextin);
- if (nextout != 1)
- close(nextout);
+ }
- /* If there isn't another process, nextin is garbage
- but it doesn't matter */
+ if (i)
+ close(nextin);
+ if ((i + 1) < pi->num_progs)
+ close(pipefds[1]); /* write end */
+ /* Pass read (output) pipe end to next iteration */
nextin = pipefds[0];
}
+
debug_printf_exec("run_pipe_real return -1\n");
return -1;
}