hush: report [v]fork failures
hush: more correct handling of piping config: add CONFIG_NOMMU
This commit is contained in:
		
							
								
								
									
										11
									
								
								Config.in
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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__
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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)
 | 
			
		||||
{
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user