summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-05-05 15:10:52 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-05-05 15:10:52 +0000
commita6c467f6d134f1fb906806f4cf3b6ca401b6a616 (patch)
treeda2697fd1fc7fc1f71b0f4dc83a6c8d7fd4532bf /shell/hush.c
parent734e5ebc93a4ed325173119211559f6942e651c4 (diff)
downloadbusybox-w32-a6c467f6d134f1fb906806f4cf3b6ca401b6a616.tar.gz
busybox-w32-a6c467f6d134f1fb906806f4cf3b6ca401b6a616.tar.bz2
busybox-w32-a6c467f6d134f1fb906806f4cf3b6ca401b6a616.zip
hush: preparatory patch for removing extra empty pipes generation
in parse stage. No real code change here.
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c170
1 files changed, 90 insertions, 80 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 78531e864..eb6f37f15 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -125,10 +125,10 @@ static const char *indenter(int i)
125#define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0 125#define ENABLE_FEATURE_EDITING_FANCY_PROMPT 0
126#endif 126#endif
127 127
128#define SPECIAL_VAR_SYMBOL 03 128#define SPECIAL_VAR_SYMBOL 3
129#define FLAG_EXIT_FROM_LOOP 1 129#define FLAG_EXIT_FROM_LOOP 1
130#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */ 130#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */
131#define FLAG_REPARSING (1 << 2) /* >=2nd pass */ 131#define FLAG_REPARSING (1 << 2) /* >= 2nd pass */
132 132
133typedef enum { 133typedef enum {
134 REDIRECT_INPUT = 1, 134 REDIRECT_INPUT = 1,
@@ -199,10 +199,10 @@ struct p_context {
199 struct pipe *list_head; 199 struct pipe *list_head;
200 struct pipe *pipe; 200 struct pipe *pipe;
201 struct redir_struct *pending_redirect; 201 struct redir_struct *pending_redirect;
202 reserved_style w; 202 reserved_style res_w;
203 int old_flag; /* for figuring out valid reserved words */ 203 int old_flag; /* for figuring out valid reserved words */
204 struct p_context *stack; 204 struct p_context *stack;
205 int type; /* define type of parser : ";$" common or special symbol */ 205 int parse_type; /* define type of parser : ";$" common or special symbol */
206 /* How about quoting status? */ 206 /* How about quoting status? */
207}; 207};
208 208
@@ -410,8 +410,8 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
410static int parse_string(o_string *dest, struct p_context *ctx, const char *src); 410static int parse_string(o_string *dest, struct p_context *ctx, const char *src);
411static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, const char *end_trigger); 411static int parse_stream(o_string *dest, struct p_context *ctx, struct in_str *input0, const char *end_trigger);
412/* setup: */ 412/* setup: */
413static int parse_stream_outer(struct in_str *inp, int flag); 413static int parse_stream_outer(struct in_str *inp, int parse_flag);
414static int parse_string_outer(const char *s, int flag); 414static int parse_string_outer(const char *s, int parse_flag);
415static int parse_file_outer(FILE *f); 415static int parse_file_outer(FILE *f);
416/* job management: */ 416/* job management: */
417static int checkjobs(struct pipe* fg_pipe); 417static int checkjobs(struct pipe* fg_pipe);
@@ -1854,23 +1854,24 @@ static void debug_print_tree(struct pipe *pi, int lvl)
1854 }; 1854 };
1855 1855
1856 int pin, prn; 1856 int pin, prn;
1857 char **argv;
1858 pin = 0; 1857 pin = 0;
1859 while (pi) { 1858 while (pi) {
1860 fprintf(stderr, "%*spipe %d r_mode=%s followup=%d %s\n", lvl*2, "", 1859 fprintf(stderr, "%*spipe %d r_mode=%s followup=%d %s\n", lvl*2, "",
1861 pin, RES[pi->r_mode], pi->followup, PIPE[pi->followup]); 1860 pin, RES[pi->r_mode], pi->followup, PIPE[pi->followup]);
1862 prn = 0; 1861 prn = 0;
1863 while (prn < pi->num_progs) { 1862 while (prn < pi->num_progs) {
1863 struct child_prog *child = &pi->progs[prn];
1864 char **argv = child->argv;
1865
1864 fprintf(stderr, "%*s prog %d", lvl*2, "", prn); 1866 fprintf(stderr, "%*s prog %d", lvl*2, "", prn);
1865 if (pi->progs[prn].group) { 1867 if (child->group) {
1866 fprintf(stderr, " group %s: (argv=%p)\n", 1868 fprintf(stderr, " group %s: (argv=%p)\n",
1867 (pi->subshell ? "()" : "{}"), 1869 (child->subshell ? "()" : "{}"),
1868 pi->progs[prn].argv); 1870 argv);
1869 debug_print_tree(pi->progs[prn].group, lvl+1); 1871 debug_print_tree(child->group, lvl+1);
1870 prn++; 1872 prn++;
1871 continue; 1873 continue;
1872 } 1874 }
1873 argv = pi->progs[prn].argv;
1874 if (argv) while (*argv) { 1875 if (argv) while (*argv) {
1875 fprintf(stderr, " '%s'", *argv); 1876 fprintf(stderr, " '%s'", *argv);
1876 argv++; 1877 argv++;
@@ -1901,7 +1902,7 @@ static int run_list_real(struct pipe *pi)
1901 int flag_rep = 0; 1902 int flag_rep = 0;
1902 int save_num_progs; 1903 int save_num_progs;
1903 int flag_skip = 1; 1904 int flag_skip = 1;
1904 int rcode = 0; /* probaly for gcc only */ 1905 int rcode = 0; /* probably for gcc only */
1905 int flag_restore = 0; 1906 int flag_restore = 0;
1906 int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */ 1907 int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */
1907 reserved_style rmode, skip_more_in_this_rmode = RES_XXXX; 1908 reserved_style rmode, skip_more_in_this_rmode = RES_XXXX;
@@ -1968,17 +1969,15 @@ static int run_list_real(struct pipe *pi)
1968 } 1969 }
1969#endif 1970#endif
1970 1971
1971 for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) { 1972 for (; pi; pi = flag_restore ? rpipe : pi->next) {
1972 if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL 1973 rmode = pi->r_mode;
1973 || pi->r_mode == RES_FOR 1974 if (rmode == RES_WHILE || rmode == RES_UNTIL || rmode == RES_FOR) {
1974 ) {
1975 flag_restore = 0; 1975 flag_restore = 0;
1976 if (!rpipe) { 1976 if (!rpipe) {
1977 flag_rep = 0; 1977 flag_rep = 0;
1978 rpipe = pi; 1978 rpipe = pi;
1979 } 1979 }
1980 } 1980 }
1981 rmode = pi->r_mode;
1982 debug_printf_exec(": rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", 1981 debug_printf_exec(": rmode=%d if_code=%d next_if_code=%d skip_more=%d\n",
1983 rmode, if_code, next_if_code, skip_more_in_this_rmode); 1982 rmode, if_code, next_if_code, skip_more_in_this_rmode);
1984 if (rmode == skip_more_in_this_rmode && flag_skip) { 1983 if (rmode == skip_more_in_this_rmode && flag_skip) {
@@ -2535,7 +2534,7 @@ static void initialize_context(struct p_context *ctx)
2535 ctx->child = NULL; 2534 ctx->child = NULL;
2536 ctx->list_head = new_pipe(); 2535 ctx->list_head = new_pipe();
2537 ctx->pipe = ctx->list_head; 2536 ctx->pipe = ctx->list_head;
2538 ctx->w = RES_NONE; 2537 ctx->res_w = RES_NONE;
2539 ctx->stack = NULL; 2538 ctx->stack = NULL;
2540 ctx->old_flag = 0; 2539 ctx->old_flag = 0;
2541 done_command(ctx); /* creates the memory for working child */ 2540 done_command(ctx); /* creates the memory for working child */
@@ -2574,29 +2573,29 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
2574 enum { NRES = sizeof(reserved_list)/sizeof(reserved_list[0]) }; 2573 enum { NRES = sizeof(reserved_list)/sizeof(reserved_list[0]) };
2575 const struct reserved_combo *r; 2574 const struct reserved_combo *r;
2576 2575
2577 for (r = reserved_list; r < reserved_list+NRES; r++) { 2576 for (r = reserved_list; r < reserved_list + NRES; r++) {
2578 if (strcmp(dest->data, r->literal) == 0) { 2577 if (strcmp(dest->data, r->literal) == 0) {
2579 debug_printf("found reserved word %s, code %d\n", r->literal, r->code); 2578 debug_printf("found reserved word %s, code %d\n", r->literal, r->code);
2580 if (r->flag & FLAG_START) { 2579 if (r->flag & FLAG_START) {
2581 struct p_context *new = xmalloc(sizeof(struct p_context)); 2580 struct p_context *new = xmalloc(sizeof(struct p_context));
2582 debug_printf("push stack\n"); 2581 debug_printf("push stack\n");
2583 if (ctx->w == RES_IN || ctx->w == RES_FOR) { 2582 if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) {
2584 syntax(); 2583 syntax();
2585 free(new); 2584 free(new);
2586 ctx->w = RES_SNTX; 2585 ctx->res_w = RES_SNTX;
2587 b_reset(dest); 2586 b_reset(dest);
2588 return 1; 2587 return 1;
2589 } 2588 }
2590 *new = *ctx; /* physical copy */ 2589 *new = *ctx; /* physical copy */
2591 initialize_context(ctx); 2590 initialize_context(ctx);
2592 ctx->stack = new; 2591 ctx->stack = new;
2593 } else if (ctx->w == RES_NONE || !(ctx->old_flag & (1 << r->code))) { 2592 } else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) {
2594 syntax(); 2593 syntax();
2595 ctx->w = RES_SNTX; 2594 ctx->res_w = RES_SNTX;
2596 b_reset(dest); 2595 b_reset(dest);
2597 return 1; 2596 return 1;
2598 } 2597 }
2599 ctx->w = r->code; 2598 ctx->res_w = r->code;
2600 ctx->old_flag = r->flag; 2599 ctx->old_flag = r->flag;
2601 if (ctx->old_flag & FLAG_END) { 2600 if (ctx->old_flag & FLAG_END) {
2602 struct p_context *old; 2601 struct p_context *old;
@@ -2623,7 +2622,7 @@ static int done_word(o_string *dest, struct p_context *ctx)
2623 glob_t *glob_target; 2622 glob_t *glob_target;
2624 int gr, flags = 0; 2623 int gr, flags = 0;
2625 2624
2626 debug_printf_parse("done_word: '%s' %p\n", dest->data, child); 2625 debug_printf_parse("done_word entered: '%s' %p\n", dest->data, child);
2627 if (dest->length == 0 && !dest->nonnull) { 2626 if (dest->length == 0 && !dest->nonnull) {
2628 debug_printf_parse("done_word return 0: true null, ignored\n"); 2627 debug_printf_parse("done_word return 0: true null, ignored\n");
2629 return 0; 2628 return 0;
@@ -2636,15 +2635,16 @@ static int done_word(o_string *dest, struct p_context *ctx)
2636 debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n"); 2635 debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n");
2637 return 1; 2636 return 1;
2638 } 2637 }
2639 if (!child->argv && (ctx->type & FLAG_PARSE_SEMICOLON)) { 2638 if (!child->argv && (ctx->parse_type & FLAG_PARSE_SEMICOLON)) {
2640 debug_printf_parse(": checking %s for reserved-ness\n", dest->data); 2639 debug_printf_parse(": checking '%s' for reserved-ness\n", dest->data);
2641 if (reserved_word(dest, ctx)) { 2640 if (reserved_word(dest, ctx)) {
2642 debug_printf_parse("done_word return %d\n", (ctx->w == RES_SNTX)); 2641 debug_printf_parse("done_word return %d\n", (ctx->res_w == RES_SNTX));
2643 return (ctx->w == RES_SNTX); 2642 return (ctx->res_w == RES_SNTX);
2644 } 2643 }
2645 } 2644 }
2646 glob_target = &child->glob_result; 2645 glob_target = &child->glob_result;
2647 if (child->argv) flags |= GLOB_APPEND; 2646 if (child->argv)
2647 flags |= GLOB_APPEND;
2648 } 2648 }
2649 gr = xglob(dest, flags, glob_target); 2649 gr = xglob(dest, flags, glob_target);
2650 if (gr != 0) { 2650 if (gr != 0) {
@@ -2663,7 +2663,7 @@ static int done_word(o_string *dest, struct p_context *ctx)
2663 } else { 2663 } else {
2664 child->argv = glob_target->gl_pathv; 2664 child->argv = glob_target->gl_pathv;
2665 } 2665 }
2666 if (ctx->w == RES_FOR) { 2666 if (ctx->res_w == RES_FOR) {
2667 done_word(dest, ctx); 2667 done_word(dest, ctx);
2668 done_pipe(ctx, PIPE_SEQ); 2668 done_pipe(ctx, PIPE_SEQ);
2669 } 2669 }
@@ -2676,56 +2676,63 @@ static int done_word(o_string *dest, struct p_context *ctx)
2676static int done_command(struct p_context *ctx) 2676static int done_command(struct p_context *ctx)
2677{ 2677{
2678 /* The child is really already in the pipe structure, so 2678 /* The child is really already in the pipe structure, so
2679 * advance the pipe counter and make a new, null child. 2679 * advance the pipe counter and make a new, null child. */
2680 * Only real trickiness here is that the uncommitted
2681 * child structure, to which ctx->child points, is not
2682 * counted in pi->num_progs. */
2683 struct pipe *pi = ctx->pipe; 2680 struct pipe *pi = ctx->pipe;
2684 struct child_prog *prog = ctx->child; 2681 struct child_prog *child = ctx->child;
2685 2682
2686 if (prog && prog->group == NULL 2683 if (child) {
2687 && prog->argv == NULL 2684 if (child->group == NULL
2688 && prog->redirects == NULL 2685 && child->argv == NULL
2689 ) { 2686 && child->redirects == NULL
2690 debug_printf("done_command: skipping null command\n"); 2687 ) {
2691 return 0; 2688 debug_printf_parse("done_command: skipping null command\n");
2692 } 2689 return 0;
2693 if (prog) { 2690 }
2694 pi->num_progs++; 2691 pi->num_progs++;
2695 debug_printf("done_command: num_progs incremented to %d\n", pi->num_progs); 2692 debug_printf_parse("done_command: ++num_progs=%d\n", pi->num_progs);
2696 } else { 2693 } else {
2697 debug_printf("done_command: initializing\n"); 2694 debug_printf_parse("done_command: initializing, num_progs=%d\n", pi->num_progs);
2698 } 2695 }
2699 pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1));
2700
2701 prog = pi->progs + pi->num_progs;
2702 memset(prog, 0, sizeof(*prog));
2703 /*prog->redirects = NULL;*/
2704 /*prog->argv = NULL; */
2705 /*prog->is_stopped = 0;*/
2706 /*prog->group = NULL;*/
2707 /*prog->glob_result.gl_pathv = NULL;*/
2708 prog->family = pi;
2709 /*prog->sp = 0;*/
2710 ctx->child = prog;
2711 prog->type = ctx->type;
2712 2696
2697 /* Only real trickiness here is that the uncommitted
2698 * child structure is not counted in pi->num_progs. */
2699 pi->progs = xrealloc(pi->progs, sizeof(*pi->progs) * (pi->num_progs+1));
2700 child = &pi->progs[pi->num_progs];
2701
2702 memset(child, 0, sizeof(*child));
2703 /*child->redirects = NULL;*/
2704 /*child->argv = NULL;*/
2705 /*child->is_stopped = 0;*/
2706 /*child->group = NULL;*/
2707 /*child->glob_result.gl_pathv = NULL;*/
2708 child->family = pi;
2709 /*child->sp = 0;*/
2710 child->type = ctx->parse_type;
2711
2712 ctx->child = child;
2713 /* but ctx->pipe and ctx->list_head remain unchanged */ 2713 /* but ctx->pipe and ctx->list_head remain unchanged */
2714
2714 return 0; 2715 return 0;
2715} 2716}
2716 2717
2717static int done_pipe(struct p_context *ctx, pipe_style type) 2718static int done_pipe(struct p_context *ctx, pipe_style type)
2718{ 2719{
2719 struct pipe *new_p; 2720 struct pipe *new_p;
2721
2722 debug_printf_parse("done_pipe entered, followup %d\n", type);
2720 done_command(ctx); /* implicit closure of previous command */ 2723 done_command(ctx); /* implicit closure of previous command */
2721 debug_printf_parse("done_pipe, type %d\n", type);
2722 ctx->pipe->followup = type; 2724 ctx->pipe->followup = type;
2723 ctx->pipe->r_mode = ctx->w; 2725 ctx->pipe->r_mode = ctx->res_w;
2724 new_p = new_pipe(); 2726 new_p = new_pipe();
2725 ctx->pipe->next = new_p; 2727 ctx->pipe->next = new_p;
2726 ctx->pipe = new_p; 2728 ctx->pipe = new_p;
2727 ctx->child = NULL; 2729 ctx->child = NULL;
2730// TODO: even just <enter> on command line basically generates
2731// tree of three NOPs (!).
2732// Can we detect that previous done_command have seen "skipping null command"
2733// condition and NOT create new pipe here?
2728 done_command(ctx); /* set up new pipe to accept commands */ 2734 done_command(ctx); /* set up new pipe to accept commands */
2735 debug_printf_parse("done_pipe return 0\n");
2729 return 0; 2736 return 0;
2730} 2737}
2731 2738
@@ -3055,7 +3062,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3055 } 3062 }
3056 if (m == MAP_IFS_IF_UNQUOTED) { 3063 if (m == MAP_IFS_IF_UNQUOTED) {
3057 if (done_word(dest, ctx)) { 3064 if (done_word(dest, ctx)) {
3058 debug_printf_parse("parse_stream return 1\n"); 3065 debug_printf_parse("parse_stream return 1: done_word!=0\n");
3059 return 1; 3066 return 1;
3060 } 3067 }
3061 /* If we aren't performing a substitution, treat 3068 /* If we aren't performing a substitution, treat
@@ -3066,9 +3073,9 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3066 } 3073 }
3067 } 3074 }
3068 if ((end_trigger && strchr(end_trigger, ch)) 3075 if ((end_trigger && strchr(end_trigger, ch))
3069 && !dest->quote && ctx->w == RES_NONE 3076 && !dest->quote && ctx->res_w == RES_NONE
3070 ) { 3077 ) {
3071 debug_printf_parse("parse_stream return 0\n"); 3078 debug_printf_parse("parse_stream return 0: end_trigger char found\n");
3072 return 0; 3079 return 0;
3073 } 3080 }
3074 if (m == MAP_IFS_IF_UNQUOTED) 3081 if (m == MAP_IFS_IF_UNQUOTED)
@@ -3089,7 +3096,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3089 case '\\': 3096 case '\\':
3090 if (next == EOF) { 3097 if (next == EOF) {
3091 syntax(); 3098 syntax();
3092 debug_printf_parse("parse_stream return 1\n"); 3099 debug_printf_parse("parse_stream return 1: \\<eof>\n");
3093 return 1; 3100 return 1;
3094 } 3101 }
3095 b_addqchr(dest, '\\', dest->quote); 3102 b_addqchr(dest, '\\', dest->quote);
@@ -3111,7 +3118,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3111 } 3118 }
3112 if (ch == EOF) { 3119 if (ch == EOF) {
3113 syntax(); 3120 syntax();
3114 debug_printf_parse("parse_stream return 1\n"); 3121 debug_printf_parse("parse_stream return 1: unterminated '\n");
3115 return 1; 3122 return 1;
3116 } 3123 }
3117 break; 3124 break;
@@ -3204,7 +3211,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3204 * that is, we were really supposed to get end_trigger, and never got 3211 * that is, we were really supposed to get end_trigger, and never got
3205 * one before the EOF. Can't use the standard "syntax error" return code, 3212 * one before the EOF. Can't use the standard "syntax error" return code,
3206 * so that parse_stream_outer can distinguish the EOF and exit smoothly. */ 3213 * so that parse_stream_outer can distinguish the EOF and exit smoothly. */
3207 debug_printf_parse("parse_stream return -%d\n", end_trigger != NULL); 3214 debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL));
3208 if (end_trigger) 3215 if (end_trigger)
3209 return -1; 3216 return -1;
3210 return 0; 3217 return 0;
@@ -3220,7 +3227,8 @@ static void update_ifs_map(void)
3220{ 3227{
3221 /* char *ifs and char map[256] are both globals. */ 3228 /* char *ifs and char map[256] are both globals. */
3222 ifs = getenv("IFS"); 3229 ifs = getenv("IFS");
3223 if (ifs == NULL) ifs = " \t\n"; 3230 if (ifs == NULL)
3231 ifs = " \t\n";
3224 /* Precompute a list of 'flow through' behavior so it can be treated 3232 /* Precompute a list of 'flow through' behavior so it can be treated
3225 * quickly up front. Computation is necessary because of IFS. 3233 * quickly up front. Computation is necessary because of IFS.
3226 * Special case handling of IFS == " \t\n" is not implemented. 3234 * Special case handling of IFS == " \t\n" is not implemented.
@@ -3235,24 +3243,26 @@ static void update_ifs_map(void)
3235 3243
3236/* most recursion does not come through here, the exception is 3244/* most recursion does not come through here, the exception is
3237 * from builtin_source() */ 3245 * from builtin_source() */
3238static int parse_stream_outer(struct in_str *inp, int flag) 3246static int parse_stream_outer(struct in_str *inp, int parse_flag)
3239{ 3247{
3240// FIXME: '{ true | exit 3; echo $? }' is parsed as a whole, 3248// FIXME: '{ true | exit 3; echo $? }' is parsed as a whole,
3241// as a result $? is replaced by 0, not 3! 3249// as a result $? is replaced by 0, not 3!
3242// Need to stop & execute stuff at ';', not parse till EOL!
3243 3250
3244 struct p_context ctx; 3251 struct p_context ctx;
3245 o_string temp = NULL_O_STRING; 3252 o_string temp = NULL_O_STRING;
3246 int rcode; 3253 int rcode;
3247 do { 3254 do {
3248 ctx.type = flag; 3255 ctx.parse_type = parse_flag;
3249 initialize_context(&ctx); 3256 initialize_context(&ctx);
3250 update_ifs_map(); 3257 update_ifs_map();
3251 if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) 3258 if (!(parse_flag & FLAG_PARSE_SEMICOLON) || (parse_flag & FLAG_REPARSING))
3252 mapset(";$&|", MAP_ORDINARY); 3259 mapset(";$&|", MAP_ORDINARY);
3253#if ENABLE_HUSH_INTERACTIVE 3260#if ENABLE_HUSH_INTERACTIVE
3254 inp->promptmode = 1; 3261 inp->promptmode = 1;
3255#endif 3262#endif
3263 /* We will stop & execute after each ';' or '\n'.
3264 * Example: "sleep 9999; echo TEST" + ctrl-C:
3265 * TEST should be printed */
3256 rcode = parse_stream(&temp, &ctx, inp, ";\n"); 3266 rcode = parse_stream(&temp, &ctx, inp, ";\n");
3257 if (rcode != 1 && ctx.old_flag != 0) { 3267 if (rcode != 1 && ctx.old_flag != 0) {
3258 syntax(); 3268 syntax();
@@ -3274,15 +3284,15 @@ static int parse_stream_outer(struct in_str *inp, int flag)
3274 free_pipe_list(ctx.list_head, 0); 3284 free_pipe_list(ctx.list_head, 0);
3275 } 3285 }
3276 b_free(&temp); 3286 b_free(&temp);
3277 } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */ 3287 } while (rcode != -1 && !(parse_flag & FLAG_EXIT_FROM_LOOP)); /* loop on syntax errors, return on EOF */
3278 return 0; 3288 return 0;
3279} 3289}
3280 3290
3281static int parse_string_outer(const char *s, int flag) 3291static int parse_string_outer(const char *s, int parse_flag)
3282{ 3292{
3283 struct in_str input; 3293 struct in_str input;
3284 setup_string_in_str(&input, s); 3294 setup_string_in_str(&input, s);
3285 return parse_stream_outer(&input, flag); 3295 return parse_stream_outer(&input, parse_flag);
3286} 3296}
3287 3297
3288static int parse_file_outer(FILE *f) 3298static int parse_file_outer(FILE *f)
@@ -3303,7 +3313,7 @@ static void setup_job_control(void)
3303 pid_t shell_pgrp; 3313 pid_t shell_pgrp;
3304 3314
3305 saved_task_pgrp = shell_pgrp = getpgrp(); 3315 saved_task_pgrp = shell_pgrp = getpgrp();
3306 debug_printf("saved_task_pgrp=%d\n", saved_task_pgrp); 3316 debug_printf_jobs("saved_task_pgrp=%d\n", saved_task_pgrp);
3307 fcntl(interactive_fd, F_SETFD, FD_CLOEXEC); 3317 fcntl(interactive_fd, F_SETFD, FD_CLOEXEC);
3308 3318
3309 /* If we were ran as 'hush &', 3319 /* If we were ran as 'hush &',
@@ -3319,7 +3329,7 @@ static void setup_job_control(void)
3319 set_misc_sighandler(SIG_IGN); 3329 set_misc_sighandler(SIG_IGN);
3320//huh? signal(SIGCHLD, SIG_IGN); 3330//huh? signal(SIGCHLD, SIG_IGN);
3321 3331
3322 /* We _must_ restore tty pgrp fatal signals */ 3332 /* We _must_ restore tty pgrp on fatal signals */
3323 set_fatal_sighandler(sigexit); 3333 set_fatal_sighandler(sigexit);
3324 3334
3325 /* Put ourselves in our own process group. */ 3335 /* Put ourselves in our own process group. */