summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-05-02 15:35:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-05-02 15:35:45 +0000
commit4ac530c0ef4f2c4c15a177456b01e240bfb9f1aa (patch)
tree3485963e2615b501d56aa03ff8f399abbce7c53c /shell/hush.c
parentef36ead37061690f9a20b5f03164e99ab1b9bdd4 (diff)
downloadbusybox-w32-4ac530c0ef4f2c4c15a177456b01e240bfb9f1aa.tar.gz
busybox-w32-4ac530c0ef4f2c4c15a177456b01e240bfb9f1aa.tar.bz2
busybox-w32-4ac530c0ef4f2c4c15a177456b01e240bfb9f1aa.zip
hush: add debugging for tracing execution,
add FIXME for 'true | exit 3; echo $?' case
Diffstat (limited to '')
-rw-r--r--shell/hush.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 8dfe2be93..f931a06e1 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -85,6 +85,7 @@
85//#define DEBUG_SHELL 85//#define DEBUG_SHELL
86/* Finer-grained debug switch */ 86/* Finer-grained debug switch */
87//#define DEBUG_SHELL_JOBS 87//#define DEBUG_SHELL_JOBS
88//#define DEBUG_SHELL_EXECUTION
88 89
89#if !ENABLE_HUSH_INTERACTIVE 90#if !ENABLE_HUSH_INTERACTIVE
90#undef ENABLE_FEATURE_EDITING 91#undef ENABLE_FEATURE_EDITING
@@ -315,6 +316,12 @@ static char *indenter(int i)
315#define debug_jobs_printf(...) do {} while (0) 316#define debug_jobs_printf(...) do {} while (0)
316#endif 317#endif
317 318
319#ifdef DEBUG_SHELL_EXECUTION
320#define debug_exec_printf(...) fprintf(stderr, __VA_ARGS__)
321#else
322#define debug_exec_printf(...) do {} while (0)
323#endif
324
318#define final_printf debug_printf 325#define final_printf debug_printf
319 326
320static void __syntax(int line) 327static void __syntax(int line)
@@ -1322,11 +1329,11 @@ static void pseudo_exec(struct child_prog *child)
1322 } 1329 }
1323 1330
1324 if (child->group) { 1331 if (child->group) {
1325 debug_printf("runtime nesting to group\n");
1326 // FIXME: do not modify globals! Think vfork! 1332 // FIXME: do not modify globals! Think vfork!
1327#if ENABLE_HUSH_INTERACTIVE 1333#if ENABLE_HUSH_INTERACTIVE
1328 interactive_fd = 0; /* crucial!!!! */ 1334 interactive_fd = 0; /* crucial!!!! */
1329#endif 1335#endif
1336 debug_exec_printf("pseudo_exec: run_list_real\n");
1330 rcode = run_list_real(child->group); 1337 rcode = run_list_real(child->group);
1331 /* OK to leak memory by not calling free_pipe_list, 1338 /* OK to leak memory by not calling free_pipe_list,
1332 * since this process is about to exit */ 1339 * since this process is about to exit */
@@ -1641,6 +1648,8 @@ static int run_pipe_real(struct pipe *pi)
1641 int rcode; 1648 int rcode;
1642 const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG); 1649 const int single_fg = (pi->num_progs == 1 && pi->followup != PIPE_BG);
1643 1650
1651 debug_exec_printf("run_pipe_real start:\n");
1652
1644 nextin = 0; 1653 nextin = 0;
1645#if ENABLE_HUSH_JOB 1654#if ENABLE_HUSH_JOB
1646 pi->pgrp = -1; 1655 pi->pgrp = -1;
@@ -1658,8 +1667,10 @@ static int run_pipe_real(struct pipe *pi)
1658 setup_redirects(child, squirrel); 1667 setup_redirects(child, squirrel);
1659 /* XXX could we merge code with following builtin case, 1668 /* XXX could we merge code with following builtin case,
1660 * by creating a pseudo builtin that calls run_list_real? */ 1669 * by creating a pseudo builtin that calls run_list_real? */
1670 debug_exec_printf(": run_list_real\n");
1661 rcode = run_list_real(child->group); 1671 rcode = run_list_real(child->group);
1662 restore_redirects(squirrel); 1672 restore_redirects(squirrel);
1673 debug_exec_printf("run_pipe_real return %d\n", rcode);
1663 return rcode; 1674 return rcode;
1664 } 1675 }
1665 1676
@@ -1707,8 +1718,10 @@ static int run_pipe_real(struct pipe *pi)
1707 char *str; 1718 char *str;
1708 1719
1709 str = make_string(argv + i); 1720 str = make_string(argv + i);
1721 debug_exec_printf(": parse_string_outer '%s'\n", str);
1710 parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); 1722 parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
1711 free(str); 1723 free(str);
1724 debug_exec_printf("run_pipe_real return %d\n", last_return_code);
1712 return last_return_code; 1725 return last_return_code;
1713 } 1726 }
1714 for (x = bltins; x->cmd; x++) { 1727 for (x = bltins; x->cmd; x++) {
@@ -1725,8 +1738,10 @@ static int run_pipe_real(struct pipe *pi)
1725 * things seem to work with glibc. */ 1738 * things seem to work with glibc. */
1726// TODO: fflush(NULL)? 1739// TODO: fflush(NULL)?
1727 setup_redirects(child, squirrel); 1740 setup_redirects(child, squirrel);
1741 debug_exec_printf(": builtin '%s' '%s'...\n", x->cmd, argv[i+1]);
1728 rcode = x->function(argv + i); 1742 rcode = x->function(argv + i);
1729 restore_redirects(squirrel); 1743 restore_redirects(squirrel);
1744 debug_exec_printf("run_pipe_real return %d\n", rcode);
1730 return rcode; 1745 return rcode;
1731 } 1746 }
1732 } 1747 }
@@ -1735,8 +1750,10 @@ static int run_pipe_real(struct pipe *pi)
1735 const struct bb_applet *a = find_applet_by_name(argv[i]); 1750 const struct bb_applet *a = find_applet_by_name(argv[i]);
1736 if (a && a->nofork) { 1751 if (a && a->nofork) {
1737 setup_redirects(child, squirrel); 1752 setup_redirects(child, squirrel);
1753 debug_exec_printf(": run_single_fg_nofork '%s' '%s'...\n", argv[i], argv[i+1]);
1738 rcode = run_single_fg_nofork(pi, a, argv + i); 1754 rcode = run_single_fg_nofork(pi, a, argv + i);
1739 restore_redirects(squirrel); 1755 restore_redirects(squirrel);
1756 debug_exec_printf("run_pipe_real return %d\n", rcode);
1740 return rcode; 1757 return rcode;
1741 } 1758 }
1742 } 1759 }
@@ -1751,6 +1768,7 @@ static int run_pipe_real(struct pipe *pi)
1751 1768
1752 for (i = 0; i < pi->num_progs; i++) { 1769 for (i = 0; i < pi->num_progs; i++) {
1753 child = &(pi->progs[i]); 1770 child = &(pi->progs[i]);
1771 debug_exec_printf(": pipe member '%s' '%s'...\n", child->argv[0], child->argv[1]);
1754 1772
1755 /* pipes are inserted between pairs of commands */ 1773 /* pipes are inserted between pairs of commands */
1756 if ((i + 1) < pi->num_progs) { 1774 if ((i + 1) < pi->num_progs) {
@@ -1831,6 +1849,7 @@ static int run_pipe_real(struct pipe *pi)
1831 but it doesn't matter */ 1849 but it doesn't matter */
1832 nextin = pipefds[0]; 1850 nextin = pipefds[0];
1833 } 1851 }
1852 debug_exec_printf("run_pipe_real return -1\n");
1834 return -1; 1853 return -1;
1835} 1854}
1836 1855
@@ -1846,18 +1865,23 @@ static int run_list_real(struct pipe *pi)
1846 int flag_restore = 0; 1865 int flag_restore = 0;
1847 int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */ 1866 int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */
1848 reserved_style rmode, skip_more_in_this_rmode = RES_XXXX; 1867 reserved_style rmode, skip_more_in_this_rmode = RES_XXXX;
1868
1869 debug_exec_printf("run_list_real start:\n");
1870
1849 /* check syntax for "for" */ 1871 /* check syntax for "for" */
1850 for (rpipe = pi; rpipe; rpipe = rpipe->next) { 1872 for (rpipe = pi; rpipe; rpipe = rpipe->next) {
1851 if ((rpipe->r_mode == RES_IN || rpipe->r_mode == RES_FOR) 1873 if ((rpipe->r_mode == RES_IN || rpipe->r_mode == RES_FOR)
1852 && (rpipe->next == NULL) 1874 && (rpipe->next == NULL)
1853 ) { 1875 ) {
1854 syntax(); 1876 syntax();
1877 debug_exec_printf("run_list_real return 1\n");
1855 return 1; 1878 return 1;
1856 } 1879 }
1857 if ((rpipe->r_mode == RES_IN && rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL) 1880 if ((rpipe->r_mode == RES_IN && rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL)
1858 || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN) 1881 || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN)
1859 ) { 1882 ) {
1860 syntax(); 1883 syntax();
1884 debug_exec_printf("run_list_real return 1\n");
1861 return 1; 1885 return 1;
1862 } 1886 }
1863 } 1887 }
@@ -1933,8 +1957,8 @@ static int run_list_real(struct pipe *pi)
1933 if (pi->num_progs == 0) 1957 if (pi->num_progs == 0)
1934 continue; 1958 continue;
1935 save_num_progs = pi->num_progs; /* save number of programs */ 1959 save_num_progs = pi->num_progs; /* save number of programs */
1960 debug_exec_printf(": run_pipe_real with %d members\n", pi->num_progs);
1936 rcode = run_pipe_real(pi); 1961 rcode = run_pipe_real(pi);
1937 debug_printf("run_pipe_real returned %d\n", rcode);
1938 if (rcode != -1) { 1962 if (rcode != -1) {
1939 /* We only ran a builtin: rcode was set by the return value 1963 /* We only ran a builtin: rcode was set by the return value
1940 * of run_pipe_real(), and we don't need to wait for anything. */ 1964 * of run_pipe_real(), and we don't need to wait for anything. */
@@ -1972,6 +1996,7 @@ static int run_list_real(struct pipe *pi)
1972 } 1996 }
1973 checkjobs(NULL); 1997 checkjobs(NULL);
1974 } 1998 }
1999 debug_exec_printf("run_list_real return %d\n", rcode);
1975 return rcode; 2000 return rcode;
1976} 2001}
1977 2002
@@ -2047,6 +2072,7 @@ static int run_list(struct pipe *pi)
2047{ 2072{
2048 int rcode = 0; 2073 int rcode = 0;
2049 if (fake_mode == 0) { 2074 if (fake_mode == 0) {
2075 debug_exec_printf("run_list: run_list_real with %d members\n", pi->num_progs);
2050 rcode = run_list_real(pi); 2076 rcode = run_list_real(pi);
2051 } 2077 }
2052 /* free_pipe_list has the side effect of clearing memory 2078 /* free_pipe_list has the side effect of clearing memory
@@ -3083,6 +3109,10 @@ static void update_ifs_map(void)
3083 * from builtin_source() */ 3109 * from builtin_source() */
3084static int parse_stream_outer(struct in_str *inp, int flag) 3110static int parse_stream_outer(struct in_str *inp, int flag)
3085{ 3111{
3112// FIXME: 'true | exit 3; echo $?' is parsed as a whole,
3113// as a result $? is replaced by 0, not 3!
3114// Need to stop & execute stuff at ';', not parse till EOL!
3115
3086 struct p_context ctx; 3116 struct p_context ctx;
3087 o_string temp = NULL_O_STRING; 3117 o_string temp = NULL_O_STRING;
3088 int rcode; 3118 int rcode;
@@ -3102,6 +3132,7 @@ static int parse_stream_outer(struct in_str *inp, int flag)
3102 if (rcode != 1 && ctx.old_flag == 0) { 3132 if (rcode != 1 && ctx.old_flag == 0) {
3103 done_word(&temp, &ctx); 3133 done_word(&temp, &ctx);
3104 done_pipe(&ctx, PIPE_SEQ); 3134 done_pipe(&ctx, PIPE_SEQ);
3135 debug_exec_printf("parse_stream_outer: run_list\n");
3105 run_list(ctx.list_head); 3136 run_list(ctx.list_head);
3106 } else { 3137 } else {
3107 if (ctx.old_flag != 0) { 3138 if (ctx.old_flag != 0) {