hush: report [v]fork failures
authorDenis Vlasenko <vda.linux@googlemail.com>
Tue, 8 Jan 2008 20:32:12 +0000 (20:32 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Tue, 8 Jan 2008 20:32:12 +0000 (20:32 -0000)
hush: more correct handling of piping
config: add CONFIG_NOMMU

Config.in
TODO_config_nommu
include/platform.h
shell/hush.c

index fa48ddd63346cb257b6675755c5de96689094db2..d2bb63200a856353a0fb048e1b9be42201e23c32 100644 (file)
--- 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
index a4cc344abb2f21dd90ccbe820899432745b73dd7..81db6db2f3cb545e90c5e32b6a9c3d1695015d2b 100644 (file)
@@ -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
index edb0f8ab0f94ad540bc0780ff29d42e7a445a22b..4c38c6ae4675ef96fe817b32ef12e04578401d3b 100644 (file)
@@ -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__
index b08fe10b6ec733f819f46a680e9aafa19a4b3acd..9dc85d0bad1debb17b4b9c8a04abea36e4e24c2d 100644 (file)
@@ -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;
 }