aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-01-08 20:32:12 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-01-08 20:32:12 +0000
commitd2c450ce811454fb77679d049538530d2cf54dd8 (patch)
tree319d23806c17472026e0a946d6ae320f513e34c0 /shell
parent474d1c57c834ee3dee6de49f109c9b570236fa60 (diff)
downloadbusybox-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
Diffstat (limited to 'shell')
-rw-r--r--shell/hush.c62
1 files changed, 30 insertions, 32 deletions
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)
1777static int run_pipe_real(struct pipe *pi) 1777static 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}