summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-20 08:35:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-20 08:35:45 +0000
commit5f786c24e4a80d5341f7a7449df5b32ec2dd440a (patch)
tree4a942939638c66fcca5f3526a597005faadf94be /shell/hush.c
parentf6250a3bee833db83e8a9ade62dce4e85830b6f7 (diff)
downloadbusybox-w32-5f786c24e4a80d5341f7a7449df5b32ec2dd440a.tar.gz
busybox-w32-5f786c24e4a80d5341f7a7449df5b32ec2dd440a.tar.bz2
busybox-w32-5f786c24e4a80d5341f7a7449df5b32ec2dd440a.zip
hush: small code shrink; style fixes
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c108
1 files changed, 57 insertions, 51 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 56f2728f5..e2ff012d7 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -140,19 +140,21 @@ typedef enum {
140 RES_IN = 12, 140 RES_IN = 12,
141 RES_SNTX = 13 141 RES_SNTX = 13
142} reserved_style; 142} reserved_style;
143#define FLAG_END (1<<RES_NONE) 143enum {
144#define FLAG_IF (1<<RES_IF) 144 FLAG_END = (1 << RES_NONE ),
145#define FLAG_THEN (1<<RES_THEN) 145 FLAG_IF = (1 << RES_IF ),
146#define FLAG_ELIF (1<<RES_ELIF) 146 FLAG_THEN = (1 << RES_THEN ),
147#define FLAG_ELSE (1<<RES_ELSE) 147 FLAG_ELIF = (1 << RES_ELIF ),
148#define FLAG_FI (1<<RES_FI) 148 FLAG_ELSE = (1 << RES_ELSE ),
149#define FLAG_FOR (1<<RES_FOR) 149 FLAG_FI = (1 << RES_FI ),
150#define FLAG_WHILE (1<<RES_WHILE) 150 FLAG_FOR = (1 << RES_FOR ),
151#define FLAG_UNTIL (1<<RES_UNTIL) 151 FLAG_WHILE = (1 << RES_WHILE),
152#define FLAG_DO (1<<RES_DO) 152 FLAG_UNTIL = (1 << RES_UNTIL),
153#define FLAG_DONE (1<<RES_DONE) 153 FLAG_DO = (1 << RES_DO ),
154#define FLAG_IN (1<<RES_IN) 154 FLAG_DONE = (1 << RES_DONE ),
155#define FLAG_START (1<<RES_XXXX) 155 FLAG_IN = (1 << RES_IN ),
156 FLAG_START = (1 << RES_XXXX ),
157};
156 158
157/* This holds pointers to the various results of parsing */ 159/* This holds pointers to the various results of parsing */
158struct p_context { 160struct p_context {
@@ -468,6 +470,7 @@ static int builtin_cd(struct child_prog *child)
468/* built-in 'env' handler */ 470/* built-in 'env' handler */
469static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED) 471static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED)
470{ 472{
473/* TODO: call env applet's code instead */
471 char **e = environ; 474 char **e = environ;
472 if (e == NULL) 475 if (e == NULL)
473 return EXIT_FAILURE; 476 return EXIT_FAILURE;
@@ -490,9 +493,13 @@ static int builtin_exec(struct child_prog *child)
490/* built-in 'exit' handler */ 493/* built-in 'exit' handler */
491static int builtin_exit(struct child_prog *child) 494static int builtin_exit(struct child_prog *child)
492{ 495{
496 /* bash prints "exit\n" here, then: */
493 if (child->argv[1] == NULL) 497 if (child->argv[1] == NULL)
494 exit(last_return_code); 498 exit(last_return_code);
495 exit(atoi(child->argv[1])); 499 /* mimic bash: exit 123abc == exit 255 + error msg */
500 xfunc_error_retval = 255;
501 /* bash: exit -2 == exit 254, no error msg */
502 exit(xatoi(child->argv[1]));
496} 503}
497 504
498/* built-in 'export VAR=value' handler */ 505/* built-in 'export VAR=value' handler */
@@ -1217,19 +1224,18 @@ static int checkjobs(struct pipe* fg_pipe)
1217 1224
1218 for (pi = job_list; pi; pi = pi->next) { 1225 for (pi = job_list; pi; pi = pi->next) {
1219 prognum = 0; 1226 prognum = 0;
1220 while (prognum < pi->num_progs && pi->progs[prognum].pid != childpid) { 1227 while (prognum < pi->num_progs) {
1228 if (pi->progs[prognum].pid == childpid)
1229 goto found_pi_and_prognum;
1221 prognum++; 1230 prognum++;
1222 } 1231 }
1223 if (prognum < pi->num_progs)
1224 break;
1225 } 1232 }
1226 1233
1227 if (pi == NULL) { 1234 /* Happens when shell is used as init process (init=/bin/sh) */
1228 debug_printf("checkjobs: pid %d was not in our list!\n", 1235 debug_printf("checkjobs: pid %d was not in our list!\n", childpid);
1229 childpid); 1236 continue;
1230 continue;
1231 }
1232 1237
1238 found_pi_and_prognum:
1233 if (WIFEXITED(status) || WIFSIGNALED(status)) { 1239 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1234 /* child exited */ 1240 /* child exited */
1235 pi->running_progs--; 1241 pi->running_progs--;
@@ -1539,13 +1545,12 @@ static int run_list_real(struct pipe *pi)
1539 pi->progs->argv[0] = save_name; 1545 pi->progs->argv[0] = save_name;
1540 pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0]; 1546 pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
1541 continue; 1547 continue;
1542 } else {
1543 /* insert new value from list for variable */
1544 if (pi->progs->argv[0])
1545 free(pi->progs->argv[0]);
1546 pi->progs->argv[0] = *list++;
1547 pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
1548 } 1548 }
1549 /* insert new value from list for variable */
1550 if (pi->progs->argv[0])
1551 free(pi->progs->argv[0]);
1552 pi->progs->argv[0] = *list++;
1553 pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
1549 } 1554 }
1550 if (rmode == RES_IN) 1555 if (rmode == RES_IN)
1551 continue; 1556 continue;
@@ -1553,7 +1558,7 @@ static int run_list_real(struct pipe *pi)
1553 if (!flag_rep) 1558 if (!flag_rep)
1554 continue; 1559 continue;
1555 } 1560 }
1556 if ((rmode == RES_DONE)) { 1561 if (rmode == RES_DONE) {
1557 if (flag_rep) { 1562 if (flag_rep) {
1558 flag_restore = 1; 1563 flag_restore = 1;
1559 } else { 1564 } else {
@@ -1590,7 +1595,7 @@ static int run_list_real(struct pipe *pi)
1590 } 1595 }
1591 last_return_code = rcode; 1596 last_return_code = rcode;
1592 pi->num_progs = save_num_progs; /* restore number of programs */ 1597 pi->num_progs = save_num_progs; /* restore number of programs */
1593 if ( rmode == RES_IF || rmode == RES_ELIF ) 1598 if (rmode == RES_IF || rmode == RES_ELIF)
1594 next_if_code = rcode; /* can be overwritten a number of times */ 1599 next_if_code = rcode; /* can be overwritten a number of times */
1595 if (rmode == RES_WHILE) 1600 if (rmode == RES_WHILE)
1596 flag_rep = !last_return_code; 1601 flag_rep = !last_return_code;
@@ -1663,7 +1668,7 @@ static int free_pipe_list(struct pipe *head, int indent)
1663 rcode = free_pipe(pi, indent); 1668 rcode = free_pipe(pi, indent);
1664 final_printf("%s pipe followup code %d\n", indenter(indent), pi->followup); 1669 final_printf("%s pipe followup code %d\n", indenter(indent), pi->followup);
1665 next = pi->next; 1670 next = pi->next;
1666 pi->next = NULL; 1671 /*pi->next = NULL;*/
1667 free(pi); 1672 free(pi);
1668 } 1673 }
1669 return rcode; 1674 return rcode;
@@ -1700,7 +1705,8 @@ static int globhack(const char *src, int flags, glob_t *pglob)
1700 cnt++; 1705 cnt++;
1701 } 1706 }
1702 dest = malloc(cnt); 1707 dest = malloc(cnt);
1703 if (!dest) return GLOB_NOSPACE; 1708 if (!dest)
1709 return GLOB_NOSPACE;
1704 if (!(flags & GLOB_APPEND)) { 1710 if (!(flags & GLOB_APPEND)) {
1705 pglob->gl_pathv = NULL; 1711 pglob->gl_pathv = NULL;
1706 pglob->gl_pathc = 0; 1712 pglob->gl_pathc = 0;
@@ -1709,7 +1715,8 @@ static int globhack(const char *src, int flags, glob_t *pglob)
1709 } 1715 }
1710 pathc = ++pglob->gl_pathc; 1716 pathc = ++pglob->gl_pathc;
1711 pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv)); 1717 pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv));
1712 if (pglob->gl_pathv == NULL) return GLOB_NOSPACE; 1718 if (pglob->gl_pathv == NULL)
1719 return GLOB_NOSPACE;
1713 pglob->gl_pathv[pathc-1] = dest; 1720 pglob->gl_pathv[pathc-1] = dest;
1714 pglob->gl_pathv[pathc] = NULL; 1721 pglob->gl_pathv[pathc] = NULL;
1715 for (s = src; s && *s; s++, dest++) { 1722 for (s = src; s && *s; s++, dest++) {
@@ -1857,15 +1864,12 @@ static int set_local_var(const char *s, int flg_export)
1857 1864
1858static void unset_local_var(const char *name) 1865static void unset_local_var(const char *name)
1859{ 1866{
1860 struct variables *cur; 1867 struct variables *cur, *next;
1861 1868
1862 if (name) { 1869 if (!name)
1863 for (cur = top_vars; cur; cur = cur->next) { 1870 return;
1864 if (strcmp(cur->name, name) == 0) 1871 for (cur = top_vars; cur; cur = cur->next) {
1865 break; 1872 if (strcmp(cur->name, name) == 0) {
1866 }
1867 if (cur != 0) {
1868 struct variables *next = top_vars;
1869 if (cur->flg_read_only) { 1873 if (cur->flg_read_only) {
1870 bb_error_msg("%s: readonly variable", name); 1874 bb_error_msg("%s: readonly variable", name);
1871 return; 1875 return;
@@ -1874,10 +1878,12 @@ static void unset_local_var(const char *name)
1874 unsetenv(cur->name); 1878 unsetenv(cur->name);
1875 free((char*)cur->name); 1879 free((char*)cur->name);
1876 free((char*)cur->value); 1880 free((char*)cur->value);
1881 next = top_vars;
1877 while (next->next != cur) 1882 while (next->next != cur)
1878 next = next->next; 1883 next = next->next;
1879 next->next = cur->next; 1884 next->next = cur->next;
1880 free(cur); 1885 free(cur);
1886 return;
1881 } 1887 }
1882 } 1888 }
1883} 1889}
@@ -1974,9 +1980,9 @@ static void initialize_context(struct p_context *ctx)
1974static int reserved_word(o_string *dest, struct p_context *ctx) 1980static int reserved_word(o_string *dest, struct p_context *ctx)
1975{ 1981{
1976 struct reserved_combo { 1982 struct reserved_combo {
1977 const char *literal; 1983 char literal[7];
1978 int code; 1984 unsigned char code;
1979 long flag; 1985 int flag;
1980 }; 1986 };
1981 /* Mostly a list of accepted follow-up reserved words. 1987 /* Mostly a list of accepted follow-up reserved words.
1982 * FLAG_END means we are done with the sequence, and are ready 1988 * FLAG_END means we are done with the sequence, and are ready
@@ -2223,7 +2229,7 @@ static FILE *generate_stream_from_list(struct pipe *head)
2223 } 2229 }
2224 debug_printf("forked child %d\n", pid); 2230 debug_printf("forked child %d\n", pid);
2225 close(channel[1]); 2231 close(channel[1]);
2226 pf = fdopen(channel[0],"r"); 2232 pf = fdopen(channel[0], "r");
2227 debug_printf("pipe on FILE *%p\n", pf); 2233 debug_printf("pipe on FILE *%p\n", pf);
2228 return pf; 2234 return pf;
2229} 2235}
@@ -2333,7 +2339,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
2333 } 2339 }
2334 b_addchr(dest, SPECIAL_VAR_SYMBOL); 2340 b_addchr(dest, SPECIAL_VAR_SYMBOL);
2335 } else if (isdigit(ch)) { 2341 } else if (isdigit(ch)) {
2336 i = ch-'0'; /* XXX is $0 special? */ 2342 i = ch - '0'; /* XXX is $0 special? */
2337 if (i < global_argc) { 2343 if (i < global_argc) {
2338 parse_string(dest, ctx, global_argv[i]); /* recursion */ 2344 parse_string(dest, ctx, global_argv[i]); /* recursion */
2339 } 2345 }
@@ -2403,7 +2409,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
2403 return 0; 2409 return 0;
2404} 2410}
2405 2411
2406int parse_string(o_string *dest, struct p_context *ctx, const char *src) 2412static int parse_string(o_string *dest, struct p_context *ctx, const char *src)
2407{ 2413{
2408 struct in_str foo; 2414 struct in_str foo;
2409 setup_string_in_str(&foo, src); 2415 setup_string_in_str(&foo, src);
@@ -2411,7 +2417,7 @@ int parse_string(o_string *dest, struct p_context *ctx, const char *src)
2411} 2417}
2412 2418
2413/* return code is 0 for normal exit, 1 for syntax error */ 2419/* return code is 0 for normal exit, 1 for syntax error */
2414int parse_stream(o_string *dest, struct p_context *ctx, 2420static int parse_stream(o_string *dest, struct p_context *ctx,
2415 struct in_str *input, int end_trigger) 2421 struct in_str *input, int end_trigger)
2416{ 2422{
2417 int ch, m; 2423 int ch, m;
@@ -2599,7 +2605,7 @@ static void update_ifs_map(void)
2599 2605
2600/* most recursion does not come through here, the exception is 2606/* most recursion does not come through here, the exception is
2601 * from builtin_source() */ 2607 * from builtin_source() */
2602int parse_stream_outer(struct in_str *inp, int flag) 2608static int parse_stream_outer(struct in_str *inp, int flag)
2603{ 2609{
2604 struct p_context ctx; 2610 struct p_context ctx;
2605 o_string temp = NULL_O_STRING; 2611 o_string temp = NULL_O_STRING;
@@ -2736,8 +2742,8 @@ int hush_main(int argc, char **argv)
2736 while ((opt = getopt(argc, argv, "c:xif")) > 0) { 2742 while ((opt = getopt(argc, argv, "c:xif")) > 0) {
2737 switch (opt) { 2743 switch (opt) {
2738 case 'c': 2744 case 'c':
2739 global_argv = argv+optind; 2745 global_argv = argv + optind;
2740 global_argc = argc-optind; 2746 global_argc = argc - optind;
2741 opt = parse_string_outer(optarg, FLAG_PARSE_SEMICOLON); 2747 opt = parse_string_outer(optarg, FLAG_PARSE_SEMICOLON);
2742 goto final_return; 2748 goto final_return;
2743 case 'i': 2749 case 'i':