diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-01-08 20:32:12 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-01-08 20:32:12 +0000 |
commit | d2c450ce811454fb77679d049538530d2cf54dd8 (patch) | |
tree | 319d23806c17472026e0a946d6ae320f513e34c0 | |
parent | 474d1c57c834ee3dee6de49f109c9b570236fa60 (diff) | |
download | busybox-w32-d2c450ce811454fb77679d049538530d2cf54dd8.tar.gz busybox-w32-d2c450ce811454fb77679d049538530d2cf54dd8.tar.bz2 busybox-w32-d2c450ce811454fb77679d049538530d2cf54dd8.zip |
hush: report [v]fork failures
hush: more correct handling of piping
config: add CONFIG_NOMMU
-rw-r--r-- | Config.in | 11 | ||||
-rw-r--r-- | TODO_config_nommu | 12 | ||||
-rw-r--r-- | include/platform.h | 5 | ||||
-rw-r--r-- | shell/hush.c | 62 |
4 files changed, 53 insertions, 37 deletions
@@ -280,6 +280,17 @@ config STATIC | |||
280 | 280 | ||
281 | Most people will leave this set to 'N'. | 281 | Most people will leave this set to 'N'. |
282 | 282 | ||
283 | config NOMMU | ||
284 | bool "Force NOMMU build" | ||
285 | default n | ||
286 | help | ||
287 | Busybox tries to detect whether architecture it is being | ||
288 | built against supports MMU or not. If this detection fails, | ||
289 | or if you want to build NOMMU version of busybox for testing, | ||
290 | you may force NOMMU build here. | ||
291 | |||
292 | Most people will leave this set to 'N'. | ||
293 | |||
283 | config BUILD_LIBBUSYBOX | 294 | config BUILD_LIBBUSYBOX |
284 | bool "Build shared libbusybox" | 295 | bool "Build shared libbusybox" |
285 | default n | 296 | default n |
diff --git a/TODO_config_nommu b/TODO_config_nommu index a4cc344ab..81db6db2f 100644 --- a/TODO_config_nommu +++ b/TODO_config_nommu | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Busybox version: 1.9.0.svn | 3 | # Busybox version: 1.10.0.svn |
4 | # Mon Dec 24 14:21:28 2007 | 4 | # Tue Jan 8 20:29:22 2008 |
5 | # | 5 | # |
6 | CONFIG_HAVE_DOT_CONFIG=y | 6 | CONFIG_HAVE_DOT_CONFIG=y |
7 | 7 | ||
@@ -39,6 +39,7 @@ CONFIG_FEATURE_HAVE_RPC=y | |||
39 | # Build Options | 39 | # Build Options |
40 | # | 40 | # |
41 | # CONFIG_STATIC is not set | 41 | # CONFIG_STATIC is not set |
42 | CONFIG_NOMMU=y | ||
42 | # CONFIG_BUILD_LIBBUSYBOX is not set | 43 | # CONFIG_BUILD_LIBBUSYBOX is not set |
43 | # CONFIG_FEATURE_INDIVIDUAL is not set | 44 | # CONFIG_FEATURE_INDIVIDUAL is not set |
44 | # CONFIG_FEATURE_SHARED_BUSYBOX is not set | 45 | # CONFIG_FEATURE_SHARED_BUSYBOX is not set |
@@ -222,6 +223,7 @@ CONFIG_FEATURE_STAT_FORMAT=y | |||
222 | CONFIG_STTY=y | 223 | CONFIG_STTY=y |
223 | CONFIG_SUM=y | 224 | CONFIG_SUM=y |
224 | CONFIG_SYNC=y | 225 | CONFIG_SYNC=y |
226 | CONFIG_TAC=y | ||
225 | CONFIG_TAIL=y | 227 | CONFIG_TAIL=y |
226 | CONFIG_FEATURE_FANCY_TAIL=y | 228 | CONFIG_FEATURE_FANCY_TAIL=y |
227 | CONFIG_TEE=y | 229 | CONFIG_TEE=y |
@@ -368,6 +370,8 @@ CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y | |||
368 | # CONFIG_INIT is not set | 370 | # CONFIG_INIT is not set |
369 | # CONFIG_DEBUG_INIT is not set | 371 | # CONFIG_DEBUG_INIT is not set |
370 | # CONFIG_FEATURE_USE_INITTAB is not set | 372 | # CONFIG_FEATURE_USE_INITTAB is not set |
373 | # CONFIG_FEATURE_KILL_REMOVED is not set | ||
374 | CONFIG_FEATURE_KILL_DELAY=0 | ||
371 | # CONFIG_FEATURE_INIT_SCTTY is not set | 375 | # CONFIG_FEATURE_INIT_SCTTY is not set |
372 | # CONFIG_FEATURE_INIT_SYSLOG is not set | 376 | # CONFIG_FEATURE_INIT_SYSLOG is not set |
373 | # CONFIG_FEATURE_EXTRA_QUIET is not set | 377 | # CONFIG_FEATURE_EXTRA_QUIET is not set |
@@ -679,6 +683,8 @@ CONFIG_FEATURE_PIDOF_OMIT=y | |||
679 | CONFIG_PKILL=y | 683 | CONFIG_PKILL=y |
680 | CONFIG_PS=y | 684 | CONFIG_PS=y |
681 | CONFIG_FEATURE_PS_WIDE=y | 685 | CONFIG_FEATURE_PS_WIDE=y |
686 | CONFIG_FEATURE_PS_TIME=y | ||
687 | # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set | ||
682 | CONFIG_RENICE=y | 688 | CONFIG_RENICE=y |
683 | CONFIG_BB_SYSCTL=y | 689 | CONFIG_BB_SYSCTL=y |
684 | CONFIG_TOP=y | 690 | CONFIG_TOP=y |
@@ -713,7 +719,7 @@ CONFIG_FEATURE_SH_IS_NONE=y | |||
713 | # CONFIG_ASH_EXPAND_PRMT is not set | 719 | # CONFIG_ASH_EXPAND_PRMT is not set |
714 | CONFIG_HUSH=y | 720 | CONFIG_HUSH=y |
715 | CONFIG_HUSH_HELP=y | 721 | CONFIG_HUSH_HELP=y |
716 | # CONFIG_HUSH_INTERACTIVE is not set | 722 | CONFIG_HUSH_INTERACTIVE=y |
717 | # CONFIG_HUSH_JOB is not set | 723 | # CONFIG_HUSH_JOB is not set |
718 | CONFIG_HUSH_TICK=y | 724 | CONFIG_HUSH_TICK=y |
719 | CONFIG_HUSH_IF=y | 725 | CONFIG_HUSH_IF=y |
diff --git a/include/platform.h b/include/platform.h index edb0f8ab0..4c38c6ae4 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -231,8 +231,9 @@ typedef unsigned smalluint; | |||
231 | * for a mmu-less system; the user should pass EXTRA_CFLAGS="-DBB_NOMMU" | 231 | * for a mmu-less system; the user should pass EXTRA_CFLAGS="-DBB_NOMMU" |
232 | * on his own. | 232 | * on his own. |
233 | */ | 233 | */ |
234 | #if defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \ | 234 | #if ENABLE_NOMMU || \ |
235 | __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__ | 235 | (defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \ |
236 | __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__) | ||
236 | #define BB_MMU 0 | 237 | #define BB_MMU 0 |
237 | #define BB_NOMMU 1 | 238 | #define BB_NOMMU 1 |
238 | #define USE_FOR_NOMMU(...) __VA_ARGS__ | 239 | #define USE_FOR_NOMMU(...) __VA_ARGS__ |
diff --git a/shell/hush.c b/shell/hush.c index b08fe10b6..9dc85d0ba 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1777,8 +1777,8 @@ static int checkjobs_and_fg_shell(struct pipe* fg_pipe) | |||
1777 | static int run_pipe_real(struct pipe *pi) | 1777 | static int run_pipe_real(struct pipe *pi) |
1778 | { | 1778 | { |
1779 | int i; | 1779 | int i; |
1780 | int nextin, nextout; | 1780 | int nextin; |
1781 | int pipefds[2]; /* pipefds[0] is for reading */ | 1781 | int pipefds[2]; /* pipefds[0] is for reading */ |
1782 | struct child_prog *child; | 1782 | struct child_prog *child; |
1783 | const struct built_in_command *x; | 1783 | const struct built_in_command *x; |
1784 | char *p; | 1784 | char *p; |
@@ -1789,7 +1789,6 @@ static int run_pipe_real(struct pipe *pi) | |||
1789 | 1789 | ||
1790 | debug_printf_exec("run_pipe_real start: single_fg=%d\n", single_fg); | 1790 | debug_printf_exec("run_pipe_real start: single_fg=%d\n", single_fg); |
1791 | 1791 | ||
1792 | nextin = 0; | ||
1793 | #if ENABLE_HUSH_JOB | 1792 | #if ENABLE_HUSH_JOB |
1794 | pi->pgrp = -1; | 1793 | pi->pgrp = -1; |
1795 | #endif | 1794 | #endif |
@@ -1874,13 +1873,14 @@ static int run_pipe_real(struct pipe *pi) | |||
1874 | #endif | 1873 | #endif |
1875 | } | 1874 | } |
1876 | 1875 | ||
1877 | /* Going to fork a child per each pipe member */ | ||
1878 | pi->running_progs = 0; | ||
1879 | |||
1880 | /* Disable job control signals for shell (parent) and | 1876 | /* Disable job control signals for shell (parent) and |
1881 | * for initial child code after fork */ | 1877 | * for initial child code after fork */ |
1882 | set_jobctrl_sighandler(SIG_IGN); | 1878 | set_jobctrl_sighandler(SIG_IGN); |
1883 | 1879 | ||
1880 | /* Going to fork a child per each pipe member */ | ||
1881 | pi->running_progs = 0; | ||
1882 | nextin = 0; | ||
1883 | |||
1884 | for (i = 0; i < pi->num_progs; i++) { | 1884 | for (i = 0; i < pi->num_progs; i++) { |
1885 | child = &(pi->progs[i]); | 1885 | child = &(pi->progs[i]); |
1886 | if (child->argv) | 1886 | if (child->argv) |
@@ -1889,24 +1889,20 @@ static int run_pipe_real(struct pipe *pi) | |||
1889 | debug_printf_exec(": pipe member with no argv\n"); | 1889 | debug_printf_exec(": pipe member with no argv\n"); |
1890 | 1890 | ||
1891 | /* pipes are inserted between pairs of commands */ | 1891 | /* pipes are inserted between pairs of commands */ |
1892 | if ((i + 1) < pi->num_progs) { | 1892 | pipefds[0] = 0; |
1893 | pipe(pipefds); | 1893 | pipefds[1] = 1; |
1894 | nextout = pipefds[1]; | 1894 | if ((i + 1) < pi->num_progs) |
1895 | } else { | 1895 | xpipe(pipefds); |
1896 | nextout = 1; | ||
1897 | pipefds[0] = -1; | ||
1898 | } | ||
1899 | 1896 | ||
1900 | /* XXX test for failed fork()? */ | ||
1901 | #if BB_MMU | 1897 | #if BB_MMU |
1902 | child->pid = fork(); | 1898 | child->pid = fork(); |
1903 | #else | 1899 | #else |
1904 | child->pid = vfork(); | 1900 | child->pid = vfork(); |
1905 | #endif | 1901 | #endif |
1906 | if (!child->pid) { /* child */ | 1902 | if (!child->pid) { /* child */ |
1903 | #if ENABLE_HUSH_JOB | ||
1907 | /* Every child adds itself to new process group | 1904 | /* Every child adds itself to new process group |
1908 | * with pgid == pid of first child in pipe */ | 1905 | * with pgid == pid of first child in pipe */ |
1909 | #if ENABLE_HUSH_JOB | ||
1910 | if (run_list_level == 1 && interactive_fd) { | 1906 | if (run_list_level == 1 && interactive_fd) { |
1911 | /* Don't do pgrp restore anymore on fatal signals */ | 1907 | /* Don't do pgrp restore anymore on fatal signals */ |
1912 | set_fatal_sighandler(SIG_DFL); | 1908 | set_fatal_sighandler(SIG_DFL); |
@@ -1919,12 +1915,10 @@ static int run_pipe_real(struct pipe *pi) | |||
1919 | } | 1915 | } |
1920 | } | 1916 | } |
1921 | #endif | 1917 | #endif |
1922 | /* in non-interactive case fatal sigs are already SIG_DFL */ | ||
1923 | xmove_fd(nextin, 0); | 1918 | xmove_fd(nextin, 0); |
1924 | xmove_fd(nextout, 1); | 1919 | xmove_fd(pipefds[1], 1); /* write end */ |
1925 | if (pipefds[0] != -1) { | 1920 | if (pipefds[0] > 1) |
1926 | close(pipefds[0]); /* opposite end of our output pipe */ | 1921 | close(pipefds[0]); /* read end */ |
1927 | } | ||
1928 | /* Like bash, explicit redirects override pipes, | 1922 | /* Like bash, explicit redirects override pipes, |
1929 | * and the pipe fd is available for dup'ing. */ | 1923 | * and the pipe fd is available for dup'ing. */ |
1930 | setup_redirects(child, NULL); | 1924 | setup_redirects(child, NULL); |
@@ -1933,25 +1927,29 @@ static int run_pipe_real(struct pipe *pi) | |||
1933 | set_jobctrl_sighandler(SIG_DFL); | 1927 | set_jobctrl_sighandler(SIG_DFL); |
1934 | set_misc_sighandler(SIG_DFL); | 1928 | set_misc_sighandler(SIG_DFL); |
1935 | signal(SIGCHLD, SIG_DFL); | 1929 | signal(SIGCHLD, SIG_DFL); |
1936 | pseudo_exec(child); | 1930 | pseudo_exec(child); /* does not return */ |
1937 | } | 1931 | } |
1938 | 1932 | ||
1939 | pi->running_progs++; | 1933 | if (child->pid < 0) { /* [v]fork failed */ |
1940 | 1934 | /* Clearly indicate, was it fork or vfork */ | |
1935 | bb_perror_msg(BB_MMU ? "cannot fork" : "cannot vfork"); | ||
1936 | } else { | ||
1937 | pi->running_progs++; | ||
1941 | #if ENABLE_HUSH_JOB | 1938 | #if ENABLE_HUSH_JOB |
1942 | /* Second and next children need to know pid of first one */ | 1939 | /* Second and next children need to know pid of first one */ |
1943 | if (pi->pgrp < 0) | 1940 | if (pi->pgrp < 0) |
1944 | pi->pgrp = child->pid; | 1941 | pi->pgrp = child->pid; |
1945 | #endif | 1942 | #endif |
1946 | if (nextin != 0) | 1943 | } |
1947 | close(nextin); | ||
1948 | if (nextout != 1) | ||
1949 | close(nextout); | ||
1950 | 1944 | ||
1951 | /* If there isn't another process, nextin is garbage | 1945 | if (i) |
1952 | but it doesn't matter */ | 1946 | close(nextin); |
1947 | if ((i + 1) < pi->num_progs) | ||
1948 | close(pipefds[1]); /* write end */ | ||
1949 | /* Pass read (output) pipe end to next iteration */ | ||
1953 | nextin = pipefds[0]; | 1950 | nextin = pipefds[0]; |
1954 | } | 1951 | } |
1952 | |||
1955 | debug_printf_exec("run_pipe_real return -1\n"); | 1953 | debug_printf_exec("run_pipe_real return -1\n"); |
1956 | return -1; | 1954 | return -1; |
1957 | } | 1955 | } |