aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-30 22:30:09 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-30 22:30:09 +0000
commit0c886c65de93f860a54508be0df40d1a9c52ab6d (patch)
treeb7938a51b43b76bbbd26bc8fbc1c98869519bcf8
parent15d78fb7241e324a823d00654206695a4f250648 (diff)
downloadbusybox-w32-0c886c65de93f860a54508be0df40d1a9c52ab6d.tar.gz
busybox-w32-0c886c65de93f860a54508be0df40d1a9c52ab6d.tar.bz2
busybox-w32-0c886c65de93f860a54508be0df40d1a9c52ab6d.zip
hush: style fixes
-rw-r--r--shell/hush.c646
1 files changed, 332 insertions, 314 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 1540327f1..1ff9b7fd5 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -79,21 +79,11 @@
79 */ 79 */
80 80
81#include "busybox.h" 81#include "busybox.h"
82#include <ctype.h> /* isalpha, isdigit */
83#include <unistd.h> /* getpid */
84#include <stdlib.h> /* getenv, atoi */
85#include <string.h> /* strchr */
86#include <stdio.h> /* popen etc. */
87#include <glob.h> /* glob, of course */ 82#include <glob.h> /* glob, of course */
88#include <stdarg.h> /* va_list */
89#include <errno.h>
90#include <fcntl.h>
91#include <getopt.h> /* should be pretty obvious */ 83#include <getopt.h> /* should be pretty obvious */
92 84
93#include <sys/stat.h> /* ulimit */ 85//#include <sys/wait.h>
94#include <sys/types.h> 86//#include <signal.h>
95#include <sys/wait.h>
96#include <signal.h>
97 87
98/* #include <dmalloc.h> */ 88/* #include <dmalloc.h> */
99/* #define DEBUG_SHELL */ 89/* #define DEBUG_SHELL */
@@ -168,46 +158,46 @@ struct p_context {
168 struct pipe *pipe; 158 struct pipe *pipe;
169 struct redir_struct *pending_redirect; 159 struct redir_struct *pending_redirect;
170 reserved_style w; 160 reserved_style w;
171 int old_flag; /* for figuring out valid reserved words */ 161 int old_flag; /* for figuring out valid reserved words */
172 struct p_context *stack; 162 struct p_context *stack;
173 int type; /* define type of parser : ";$" common or special symbol */ 163 int type; /* define type of parser : ";$" common or special symbol */
174 /* How about quoting status? */ 164 /* How about quoting status? */
175}; 165};
176 166
177struct redir_struct { 167struct redir_struct {
178 redir_type type; /* type of redirection */ 168 redir_type type; /* type of redirection */
179 int fd; /* file descriptor being redirected */ 169 int fd; /* file descriptor being redirected */
180 int dup; /* -1, or file descriptor being duplicated */ 170 int dup; /* -1, or file descriptor being duplicated */
181 struct redir_struct *next; /* pointer to the next redirect in the list */ 171 struct redir_struct *next; /* pointer to the next redirect in the list */
182 glob_t word; /* *word.gl_pathv is the filename */ 172 glob_t word; /* *word.gl_pathv is the filename */
183}; 173};
184 174
185struct child_prog { 175struct child_prog {
186 pid_t pid; /* 0 if exited */ 176 pid_t pid; /* 0 if exited */
187 char **argv; /* program name and arguments */ 177 char **argv; /* program name and arguments */
188 struct pipe *group; /* if non-NULL, first in group or subshell */ 178 struct pipe *group; /* if non-NULL, first in group or subshell */
189 int subshell; /* flag, non-zero if group must be forked */ 179 int subshell; /* flag, non-zero if group must be forked */
190 struct redir_struct *redirects; /* I/O redirections */ 180 struct redir_struct *redirects; /* I/O redirections */
191 glob_t glob_result; /* result of parameter globbing */ 181 glob_t glob_result; /* result of parameter globbing */
192 int is_stopped; /* is the program currently running? */ 182 int is_stopped; /* is the program currently running? */
193 struct pipe *family; /* pointer back to the child's parent pipe */ 183 struct pipe *family; /* pointer back to the child's parent pipe */
194 int sp; /* number of SPECIAL_VAR_SYMBOL */ 184 int sp; /* number of SPECIAL_VAR_SYMBOL */
195 int type; 185 int type;
196}; 186};
197 187
198struct pipe { 188struct pipe {
199 int jobid; /* job number */ 189 int jobid; /* job number */
200 int num_progs; /* total number of programs in job */ 190 int num_progs; /* total number of programs in job */
201 int running_progs; /* number of programs running */ 191 int running_progs; /* number of programs running */
202 char *text; /* name of job */ 192 char *text; /* name of job */
203 char *cmdbuf; /* buffer various argv's point into */ 193 char *cmdbuf; /* buffer various argv's point into */
204 pid_t pgrp; /* process group ID for the job */ 194 pid_t pgrp; /* process group ID for the job */
205 struct child_prog *progs; /* array of commands in pipe */ 195 struct child_prog *progs; /* array of commands in pipe */
206 struct pipe *next; /* to track background commands */ 196 struct pipe *next; /* to track background commands */
207 int stopped_progs; /* number of programs alive, but stopped */ 197 int stopped_progs; /* number of programs alive, but stopped */
208 int job_context; /* bitmask defining current context */ 198 int job_context; /* bitmask defining current context */
209 pipe_style followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */ 199 pipe_style followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
210 reserved_style r_mode; /* supports if, for, while, until */ 200 reserved_style r_mode; /* supports if, for, while, until */
211}; 201};
212 202
213struct close_me { 203struct close_me {
@@ -238,9 +228,9 @@ static int interactive;
238static struct close_me *close_me_head; 228static struct close_me *close_me_head;
239static const char *cwd; 229static const char *cwd;
240static struct pipe *job_list; 230static struct pipe *job_list;
241static unsigned int last_bg_pid; 231static unsigned last_bg_pid;
242static int last_jobid; 232static int last_jobid;
243static unsigned int shell_terminal; 233static unsigned shell_terminal;
244static char *PS1; 234static char *PS1;
245static char *PS2; 235static char *PS2;
246static struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 }; 236static struct variables shell_ver = { "HUSH_VERSION", "0.01", 1, 1, 0 };
@@ -301,11 +291,11 @@ static void debug_printf(const char *format, ...)
301/* broken, of course, but OK for testing */ 291/* broken, of course, but OK for testing */
302static char *indenter(int i) 292static char *indenter(int i)
303{ 293{
304 static char blanks[]=" "; 294 static char blanks[] = " ";
305 return &blanks[sizeof(blanks)-i-1]; 295 return &blanks[sizeof(blanks)-i-1];
306} 296}
307#else 297#else
308#define debug_printf(...) do {;} while(0); 298#define debug_printf(...) do {;} while (0);
309#endif 299#endif
310#define final_printf debug_printf 300#define final_printf debug_printf
311 301
@@ -340,7 +330,7 @@ static int b_check_space(o_string *o, int len);
340static int b_addchr(o_string *o, int ch); 330static int b_addchr(o_string *o, int ch);
341static void b_reset(o_string *o); 331static void b_reset(o_string *o);
342static int b_addqchr(o_string *o, int ch, int quote); 332static int b_addqchr(o_string *o, int ch, int quote);
343static int b_adduint(o_string *o, unsigned int i); 333static int b_adduint(o_string *o, unsigned i);
344/* in_str manipulations: */ 334/* in_str manipulations: */
345static int static_get(struct in_str *i); 335static int static_get(struct in_str *i);
346static int static_peek(struct in_str *i); 336static int static_peek(struct in_str *i);
@@ -404,35 +394,35 @@ static int set_local_var(const char *s, int flg_export);
404 * For example, 'unset foo | whatever' will parse and run, but foo will 394 * For example, 'unset foo | whatever' will parse and run, but foo will
405 * still be set at the end. */ 395 * still be set at the end. */
406static const struct built_in_command bltins[] = { 396static const struct built_in_command bltins[] = {
407 {"bg", "Resume a job in the background", builtin_fg_bg}, 397 { "bg", "Resume a job in the background", builtin_fg_bg },
408 {"break", "Exit for, while or until loop", builtin_not_written}, 398 { "break", "Exit for, while or until loop", builtin_not_written },
409 {"cd", "Change working directory", builtin_cd}, 399 { "cd", "Change working directory", builtin_cd },
410 {"continue", "Continue for, while or until loop", builtin_not_written}, 400 { "continue", "Continue for, while or until loop", builtin_not_written },
411 {"env", "Print all environment variables", builtin_env}, 401 { "env", "Print all environment variables", builtin_env },
412 {"eval", "Construct and run shell command", builtin_eval}, 402 { "eval", "Construct and run shell command", builtin_eval },
413 {"exec", "Exec command, replacing this shell with the exec'd process", 403 { "exec", "Exec command, replacing this shell with the exec'd process",
414 builtin_exec}, 404 builtin_exec },
415 {"exit", "Exit from shell()", builtin_exit}, 405 { "exit", "Exit from shell()", builtin_exit },
416 {"export", "Set environment variable", builtin_export}, 406 { "export", "Set environment variable", builtin_export },
417 {"fg", "Bring job into the foreground", builtin_fg_bg}, 407 { "fg", "Bring job into the foreground", builtin_fg_bg },
418 {"jobs", "Lists the active jobs", builtin_jobs}, 408 { "jobs", "Lists the active jobs", builtin_jobs },
419 {"pwd", "Print current directory", builtin_pwd}, 409 { "pwd", "Print current directory", builtin_pwd },
420 {"read", "Input environment variable", builtin_read}, 410 { "read", "Input environment variable", builtin_read },
421 {"return", "Return from a function", builtin_not_written}, 411 { "return", "Return from a function", builtin_not_written },
422 {"set", "Set/unset shell local variables", builtin_set}, 412 { "set", "Set/unset shell local variables", builtin_set },
423 {"shift", "Shift positional parameters", builtin_shift}, 413 { "shift", "Shift positional parameters", builtin_shift },
424 {"trap", "Trap signals", builtin_not_written}, 414 { "trap", "Trap signals", builtin_not_written },
425 {"ulimit","Controls resource limits", builtin_not_written}, 415 { "ulimit","Controls resource limits", builtin_not_written },
426 {"umask","Sets file creation mask", builtin_umask}, 416 { "umask","Sets file creation mask", builtin_umask },
427 {"unset", "Unset environment variable", builtin_unset}, 417 { "unset", "Unset environment variable", builtin_unset },
428 {".", "Source-in and run commands in a file", builtin_source}, 418 { ".", "Source-in and run commands in a file", builtin_source },
429 {"help", "List shell built-in commands", builtin_help}, 419 { "help", "List shell built-in commands", builtin_help },
430 {NULL, NULL, NULL} 420 { NULL, NULL, NULL }
431}; 421};
432 422
433static const char *set_cwd(void) 423static const char *set_cwd(void)
434{ 424{
435 if(cwd==bb_msg_unknown) 425 if (cwd == bb_msg_unknown)
436 cwd = NULL; /* xgetcwd(arg) called free(arg) */ 426 cwd = NULL; /* xgetcwd(arg) called free(arg) */
437 cwd = xgetcwd((char *)cwd); 427 cwd = xgetcwd((char *)cwd);
438 if (!cwd) 428 if (!cwd)
@@ -477,8 +467,8 @@ static int builtin_env(struct child_prog *dummy ATTRIBUTE_UNUSED)
477{ 467{
478 char **e = environ; 468 char **e = environ;
479 if (e == NULL) return EXIT_FAILURE; 469 if (e == NULL) return EXIT_FAILURE;
480 for (; *e; e++) { 470 for (*e) {
481 puts(*e); 471 puts(*e++);
482 } 472 }
483 return EXIT_SUCCESS; 473 return EXIT_SUCCESS;
484} 474}
@@ -513,7 +503,7 @@ static int builtin_export(struct child_prog *child)
513 503
514 name = strdup(name); 504 name = strdup(name);
515 505
516 if(name) { 506 if (name) {
517 const char *value = strchr(name, '='); 507 const char *value = strchr(name, '=');
518 508
519 if (!value) { 509 if (!value) {
@@ -525,7 +515,7 @@ static int builtin_export(struct child_prog *child)
525 size_t ln = strlen(name); 515 size_t ln = strlen(name);
526 516
527 tmp = realloc(name, ln+strlen(value)+2); 517 tmp = realloc(name, ln+strlen(value)+2);
528 if(tmp==NULL) 518 if (tmp == NULL)
529 res = -1; 519 res = -1;
530 else { 520 else {
531 sprintf(tmp+ln, "=%s", value); 521 sprintf(tmp+ln, "=%s", value);
@@ -538,9 +528,9 @@ static int builtin_export(struct child_prog *child)
538 } 528 }
539 } 529 }
540 } 530 }
541 if (res<0) 531 if (res < 0)
542 bb_perror_msg("export"); 532 bb_perror_msg("export");
543 else if(res==0) 533 else if (res == 0)
544 res = set_local_var(name, 1); 534 res = set_local_var(name, 1);
545 else 535 else
546 res = 0; 536 res = 0;
@@ -552,7 +542,7 @@ static int builtin_export(struct child_prog *child)
552static int builtin_fg_bg(struct child_prog *child) 542static int builtin_fg_bg(struct child_prog *child)
553{ 543{
554 int i, jobnum; 544 int i, jobnum;
555 struct pipe *pi=NULL; 545 struct pipe *pi = NULL;
556 546
557 if (!interactive) 547 if (!interactive)
558 return EXIT_FAILURE; 548 return EXIT_FAILURE;
@@ -612,7 +602,7 @@ static int builtin_help(struct child_prog *dummy ATTRIBUTE_UNUSED)
612 printf("\nBuilt-in commands:\n"); 602 printf("\nBuilt-in commands:\n");
613 printf("-------------------\n"); 603 printf("-------------------\n");
614 for (x = bltins; x->cmd; x++) { 604 for (x = bltins; x->cmd; x++) {
615 if (x->descr==NULL) 605 if (x->descr == NULL)
616 continue; 606 continue;
617 printf("%s\t%s\n", x->cmd, x->descr); 607 printf("%s\t%s\n", x->cmd, x->descr);
618 } 608 }
@@ -624,7 +614,7 @@ static int builtin_help(struct child_prog *dummy ATTRIBUTE_UNUSED)
624static int builtin_jobs(struct child_prog *child ATTRIBUTE_UNUSED) 614static int builtin_jobs(struct child_prog *child ATTRIBUTE_UNUSED)
625{ 615{
626 struct pipe *job; 616 struct pipe *job;
627 char *status_string; 617 const char *status_string;
628 618
629 for (job = job_list; job; job = job->next) { 619 for (job = job_list; job; job = job->next) {
630 if (job->running_progs == job->stopped_progs) 620 if (job->running_progs == job->stopped_progs)
@@ -652,14 +642,14 @@ static int builtin_read(struct child_prog *child)
652 642
653 if (child->argv[1]) { 643 if (child->argv[1]) {
654 char string[BUFSIZ]; 644 char string[BUFSIZ];
655 char *var = 0; 645 char *var = NULL;
656 646
657 string[0] = 0; /* In case stdin has only EOF */ 647 string[0] = '\0'; /* In case stdin has only EOF */
658 /* read string */ 648 /* read string */
659 fgets(string, sizeof(string), stdin); 649 fgets(string, sizeof(string), stdin);
660 chomp(string); 650 chomp(string);
661 var = malloc(strlen(child->argv[1])+strlen(string)+2); 651 var = malloc(strlen(child->argv[1]) + strlen(string) + 2);
662 if(var) { 652 if (var) {
663 sprintf(var, "%s=%s", child->argv[1], string); 653 sprintf(var, "%s=%s", child->argv[1], string);
664 res = set_local_var(var, 0); 654 res = set_local_var(var, 0);
665 } else 655 } else
@@ -668,10 +658,9 @@ static int builtin_read(struct child_prog *child)
668 bb_perror_msg("read"); 658 bb_perror_msg("read");
669 free(var); /* So not move up to avoid breaking errno */ 659 free(var); /* So not move up to avoid breaking errno */
670 return res; 660 return res;
671 } else {
672 do res=getchar(); while(res!='\n' && res!=EOF);
673 return 0;
674 } 661 }
662 do res = getchar(); while (res != '\n' && res != EOF);
663 return 0;
675} 664}
676 665
677/* built-in 'set VAR=value' handler */ 666/* built-in 'set VAR=value' handler */
@@ -681,23 +670,23 @@ static int builtin_set(struct child_prog *child)
681 struct variables *e; 670 struct variables *e;
682 671
683 if (temp == NULL) 672 if (temp == NULL)
684 for(e = top_vars; e; e=e->next) 673 for (e = top_vars; e; e = e->next)
685 printf("%s=%s\n", e->name, e->value); 674 printf("%s=%s\n", e->name, e->value);
686 else 675 else
687 set_local_var(temp, 0); 676 set_local_var(temp, 0);
688 677
689 return EXIT_SUCCESS; 678 return EXIT_SUCCESS;
690} 679}
691 680
692 681
693/* Built-in 'shift' handler */ 682/* Built-in 'shift' handler */
694static int builtin_shift(struct child_prog *child) 683static int builtin_shift(struct child_prog *child)
695{ 684{
696 int n=1; 685 int n = 1;
697 if (child->argv[1]) { 686 if (child->argv[1]) {
698 n=atoi(child->argv[1]); 687 n = atoi(child->argv[1]);
699 } 688 }
700 if (n>=0 && n<global_argc) { 689 if (n >= 0 && n < global_argc) {
701 /* XXX This probably breaks $0 */ 690 /* XXX This probably breaks $0 */
702 global_argc -= n; 691 global_argc -= n;
703 global_argv += n; 692 global_argv += n;
@@ -740,12 +729,13 @@ static int builtin_umask(struct child_prog *child)
740 const char *arg = child->argv[1]; 729 const char *arg = child->argv[1];
741 char *end; 730 char *end;
742 if (arg) { 731 if (arg) {
743 new_umask=strtoul(arg, &end, 8); 732 new_umask = strtoul(arg, &end, 8);
744 if (*end!='\0' || end == arg) { 733 if (*end != '\0' || end == arg) {
745 return EXIT_FAILURE; 734 return EXIT_FAILURE;
746 } 735 }
747 } else { 736 } else {
748 printf("%.3o\n", (unsigned int) (new_umask=umask(0))); 737 new_umask = umask(0);
738 printf("%.3o\n", (unsigned) new_umask);
749 } 739 }
750 umask(new_umask); 740 umask(new_umask);
751 return EXIT_SUCCESS; 741 return EXIT_SUCCESS;
@@ -761,7 +751,7 @@ static int builtin_unset(struct child_prog *child)
761 751
762static int builtin_not_written(struct child_prog *child) 752static int builtin_not_written(struct child_prog *child)
763{ 753{
764 printf("builtin_%s not written\n",child->argv[0]); 754 printf("builtin_%s not written\n", child->argv[0]);
765 return EXIT_FAILURE; 755 return EXIT_FAILURE;
766} 756}
767 757
@@ -784,7 +774,8 @@ static int b_check_space(o_string *o, int len)
784static int b_addchr(o_string *o, int ch) 774static int b_addchr(o_string *o, int ch)
785{ 775{
786 debug_printf("b_addchr: %c %d %p\n", ch, o->length, o); 776 debug_printf("b_addchr: %c %d %p\n", ch, o->length, o);
787 if (b_check_space(o, 1)) return B_NOSPAC; 777 if (b_check_space(o, 1))
778 return B_NOSPAC;
788 o->data[o->length] = ch; 779 o->data[o->length] = ch;
789 o->length++; 780 o->length++;
790 o->data[o->length] = '\0'; 781 o->data[o->length] = '\0';
@@ -795,7 +786,8 @@ static void b_reset(o_string *o)
795{ 786{
796 o->length = 0; 787 o->length = 0;
797 o->nonnull = 0; 788 o->nonnull = 0;
798 if (o->data != NULL) *o->data = '\0'; 789 if (o->data != NULL)
790 *o->data = '\0';
799} 791}
800 792
801static void b_free(o_string *o) 793static void b_free(o_string *o)
@@ -814,17 +806,17 @@ static int b_addqchr(o_string *o, int ch, int quote)
814 if (quote && strchr("*?[\\",ch)) { 806 if (quote && strchr("*?[\\",ch)) {
815 int rc; 807 int rc;
816 rc = b_addchr(o, '\\'); 808 rc = b_addchr(o, '\\');
817 if (rc) return rc; 809 if (rc)
810 return rc;
818 } 811 }
819 return b_addchr(o, ch); 812 return b_addchr(o, ch);
820} 813}
821 814
822/* belongs in utility.c */ 815/* belongs in utility.c */
823static char *simple_itoa(unsigned int i) 816static char *simple_itoa(unsigned i)
824{ 817{
825 /* 21 digits plus null terminator, good for 64-bit or smaller ints */ 818 static char local[sizeof(int)*3 + 2];
826 static char local[22]; 819 char *p = &local[sizeof(int)*3 + 2 - 1];
827 char *p = &local[21];
828 *p-- = '\0'; 820 *p-- = '\0';
829 do { 821 do {
830 *p-- = '0' + i % 10; 822 *p-- = '0' + i % 10;
@@ -833,19 +825,19 @@ static char *simple_itoa(unsigned int i)
833 return p + 1; 825 return p + 1;
834} 826}
835 827
836static int b_adduint(o_string *o, unsigned int i) 828static int b_adduint(o_string *o, unsigned i)
837{ 829{
838 int r; 830 int r;
839 char *p = simple_itoa(i); 831 char *p = simple_itoa(i);
840 /* no escape checking necessary */ 832 /* no escape checking necessary */
841 do r=b_addchr(o, *p++); while (r==0 && *p); 833 do r = b_addchr(o, *p++); while (r==0 && *p);
842 return r; 834 return r;
843} 835}
844 836
845static int static_get(struct in_str *i) 837static int static_get(struct in_str *i)
846{ 838{
847 int ch=*i->p++; 839 int ch = *i->p++;
848 if (ch=='\0') return EOF; 840 if (ch == '\0') return EOF;
849 return ch; 841 return ch;
850} 842}
851 843
@@ -860,7 +852,7 @@ static void cmdedit_set_initial_prompt(void)
860 PS1 = NULL; 852 PS1 = NULL;
861#else 853#else
862 PS1 = getenv("PS1"); 854 PS1 = getenv("PS1");
863 if(PS1==0) 855 if (PS1 == NULL)
864 PS1 = "\\w \\$ "; 856 PS1 = "\\w \\$ ";
865#endif 857#endif
866} 858}
@@ -872,16 +864,16 @@ static void setup_prompt_string(int promptmode, char **prompt_str)
872 /* Set up the prompt */ 864 /* Set up the prompt */
873 if (promptmode == 1) { 865 if (promptmode == 1) {
874 free(PS1); 866 free(PS1);
875 PS1=xmalloc(strlen(cwd)+4); 867 PS1 = xmalloc(strlen(cwd)+4);
876 sprintf(PS1, "%s %s", cwd, ( geteuid() != 0 ) ? "$ ":"# "); 868 sprintf(PS1, "%s %s", cwd, (geteuid() != 0) ? "$ " : "# ");
877 *prompt_str = PS1; 869 *prompt_str = PS1;
878 } else { 870 } else {
879 *prompt_str = PS2; 871 *prompt_str = PS2;
880 } 872 }
881#else 873#else
882 *prompt_str = (promptmode==1)? PS1 : PS2; 874 *prompt_str = (promptmode == 1) ? PS1 : PS2;
883#endif 875#endif
884 debug_printf("result %s\n",*prompt_str); 876 debug_printf("result %s\n", *prompt_str);
885} 877}
886 878
887#if ENABLE_FEATURE_EDITING 879#if ENABLE_FEATURE_EDITING
@@ -905,8 +897,8 @@ static void get_user_input(struct in_str *i)
905#else 897#else
906 fputs(prompt_str, stdout); 898 fputs(prompt_str, stdout);
907 fflush(stdout); 899 fflush(stdout);
908 the_command[0]=fgetc(i->file); 900 the_command[0] = fgetc(i->file);
909 the_command[1]='\0'; 901 the_command[1] = '\0';
910#endif 902#endif
911 fflush(stdout); 903 fflush(stdout);
912 i->p = the_command; 904 i->p = the_command;
@@ -921,18 +913,18 @@ static int file_get(struct in_str *i)
921 ch = 0; 913 ch = 0;
922 /* If there is data waiting, eat it up */ 914 /* If there is data waiting, eat it up */
923 if (i->p && *i->p) { 915 if (i->p && *i->p) {
924 ch=*i->p++; 916 ch = *i->p++;
925 } else { 917 } else {
926 /* need to double check i->file because we might be doing something 918 /* need to double check i->file because we might be doing something
927 * more complicated by now, like sourcing or substituting. */ 919 * more complicated by now, like sourcing or substituting. */
928 if (i->__promptme && interactive && i->file == stdin) { 920 if (i->__promptme && interactive && i->file == stdin) {
929 while(! i->p || (interactive && strlen(i->p)==0) ) { 921 while (!i->p || !(interactive && strlen(i->p))) {
930 get_user_input(i); 922 get_user_input(i);
931 } 923 }
932 i->promptmode=2; 924 i->promptmode = 2;
933 i->__promptme = 0; 925 i->__promptme = 0;
934 if (i->p && *i->p) { 926 if (i->p && *i->p) {
935 ch=*i->p++; 927 ch = *i->p++;
936 } 928 }
937 } else { 929 } else {
938 ch = fgetc(i->file); 930 ch = fgetc(i->file);
@@ -940,7 +932,8 @@ static int file_get(struct in_str *i)
940 932
941 debug_printf("b_getch: got a %d\n", ch); 933 debug_printf("b_getch: got a %d\n", ch);
942 } 934 }
943 if (ch == '\n') i->__promptme=1; 935 if (ch == '\n')
936 i->__promptme = 1;
944 return ch; 937 return ch;
945} 938}
946 939
@@ -964,8 +957,8 @@ static void setup_file_in_str(struct in_str *i, FILE *f)
964{ 957{
965 i->peek = file_peek; 958 i->peek = file_peek;
966 i->get = file_get; 959 i->get = file_get;
967 i->__promptme=1; 960 i->__promptme = 1;
968 i->promptmode=1; 961 i->promptmode = 1;
969 i->file = f; 962 i->file = f;
970 i->p = NULL; 963 i->p = NULL;
971} 964}
@@ -1000,7 +993,7 @@ static void mark_closed(int fd)
1000static void close_all(void) 993static void close_all(void)
1001{ 994{
1002 struct close_me *c; 995 struct close_me *c;
1003 for (c=close_me_head; c; c=c->next) { 996 for (c = close_me_head; c; c = c->next) {
1004 close(c->fd); 997 close(c->fd);
1005 } 998 }
1006 close_me_head = NULL; 999 close_me_head = NULL;
@@ -1013,13 +1006,13 @@ static int setup_redirects(struct child_prog *prog, int squirrel[])
1013 int openfd, mode; 1006 int openfd, mode;
1014 struct redir_struct *redir; 1007 struct redir_struct *redir;
1015 1008
1016 for (redir=prog->redirects; redir; redir=redir->next) { 1009 for (redir = prog->redirects; redir; redir = redir->next) {
1017 if (redir->dup == -1 && redir->word.gl_pathv == NULL) { 1010 if (redir->dup == -1 && redir->word.gl_pathv == NULL) {
1018 /* something went wrong in the parse. Pretend it didn't happen */ 1011 /* something went wrong in the parse. Pretend it didn't happen */
1019 continue; 1012 continue;
1020 } 1013 }
1021 if (redir->dup == -1) { 1014 if (redir->dup == -1) {
1022 mode=redir_table[redir->type].mode; 1015 mode = redir_table[redir->type].mode;
1023 openfd = open(redir->word.gl_pathv[0], mode, 0666); 1016 openfd = open(redir->word.gl_pathv[0], mode, 0666);
1024 if (openfd < 0) { 1017 if (openfd < 0) {
1025 /* this could get lost if stderr has been redirected, but 1018 /* this could get lost if stderr has been redirected, but
@@ -1050,7 +1043,7 @@ static int setup_redirects(struct child_prog *prog, int squirrel[])
1050static void restore_redirects(int squirrel[]) 1043static void restore_redirects(int squirrel[])
1051{ 1044{
1052 int i, fd; 1045 int i, fd;
1053 for (i=0; i<3; i++) { 1046 for (i = 0; i < 3; i++) {
1054 fd = squirrel[i]; 1047 fd = squirrel[i];
1055 if (fd != -1) { 1048 if (fd != -1) {
1056 /* No error checking. I sure wouldn't know what 1049 /* No error checking. I sure wouldn't know what
@@ -1071,13 +1064,15 @@ static void pseudo_exec(struct child_prog *child)
1071 char *p; 1064 char *p;
1072 const struct built_in_command *x; 1065 const struct built_in_command *x;
1073 if (child->argv) { 1066 if (child->argv) {
1074 for (i=0; is_assignment(child->argv[i]); i++) { 1067 for (i = 0; is_assignment(child->argv[i]); i++) {
1075 debug_printf("pid %d environment modification: %s\n",getpid(),child->argv[i]); 1068 debug_printf("pid %d environment modification: %s\n",
1069 getpid(), child->argv[i]);
1076 p = insert_var_value(child->argv[i]); 1070 p = insert_var_value(child->argv[i]);
1077 putenv(strdup(p)); 1071 putenv(strdup(p));
1078 if (p != child->argv[i]) free(p); 1072 if (p != child->argv[i])
1073 free(p);
1079 } 1074 }
1080 child->argv+=i; /* XXX this hack isn't so horrible, since we are about 1075 child->argv += i; /* XXX this hack isn't so horrible, since we are about
1081 to exit, and therefore don't need to keep data 1076 to exit, and therefore don't need to keep data
1082 structures consistent for free() use. */ 1077 structures consistent for free() use. */
1083 /* If a variable is assigned in a forest, and nobody listens, 1078 /* If a variable is assigned in a forest, and nobody listens,
@@ -1118,19 +1113,20 @@ static void pseudo_exec(struct child_prog *child)
1118 char *name = child->argv[0]; 1113 char *name = child->argv[0];
1119 1114
1120 /* Count argc for use in a second... */ 1115 /* Count argc for use in a second... */
1121 for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++); 1116 for (argc_l = 0; *argv_l; argv_l++, argc_l++)
1117 /**/;
1122 optind = 1; 1118 optind = 1;
1123 debug_printf("running applet %s\n", name); 1119 debug_printf("running applet %s\n", name);
1124 run_applet_by_name(name, argc_l, child->argv); 1120 run_applet_by_name(name, argc_l, child->argv);
1125 } 1121 }
1126#endif 1122#endif
1127 debug_printf("exec of %s\n",child->argv[0]); 1123 debug_printf("exec of %s\n", child->argv[0]);
1128 execvp(child->argv[0],child->argv); 1124 execvp(child->argv[0], child->argv);
1129 bb_perror_msg("cannot exec: %s",child->argv[0]); 1125 bb_perror_msg("cannot exec: %s", child->argv[0]);
1130 _exit(1); 1126 _exit(1);
1131 } else if (child->group) { 1127 } else if (child->group) {
1132 debug_printf("runtime nesting to group\n"); 1128 debug_printf("runtime nesting to group\n");
1133 interactive=0; /* crucial!!!! */ 1129 interactive = 0; /* crucial!!!! */
1134 rcode = run_list_real(child->group); 1130 rcode = run_list_real(child->group);
1135 /* OK to leak memory by not calling free_pipe_list, 1131 /* OK to leak memory by not calling free_pipe_list,
1136 * since this process is about to exit */ 1132 * since this process is about to exit */
@@ -1156,7 +1152,8 @@ static void insert_bg_job(struct pipe *pi)
1156 if (!job_list) { 1152 if (!job_list) {
1157 thejob = job_list = xmalloc(sizeof(*thejob)); 1153 thejob = job_list = xmalloc(sizeof(*thejob));
1158 } else { 1154 } else {
1159 for (thejob = job_list; thejob->next; thejob = thejob->next) /* nothing */; 1155 for (thejob = job_list; thejob->next; thejob = thejob->next)
1156 /* nothing */;
1160 thejob->next = xmalloc(sizeof(*thejob)); 1157 thejob->next = xmalloc(sizeof(*thejob));
1161 thejob = thejob->next; 1158 thejob = thejob->next;
1162 } 1159 }
@@ -1170,11 +1167,11 @@ static void insert_bg_job(struct pipe *pi)
1170 1167
1171 //if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0]) 1168 //if (pi->progs[0] && pi->progs[0].argv && pi->progs[0].argv[0])
1172 { 1169 {
1173 char *bar=thejob->text; 1170 char *bar = thejob->text;
1174 char **foo=pi->progs[0].argv; 1171 char **foo = pi->progs[0].argv;
1175 while(foo && *foo) { 1172 if (foo)
1176 bar += sprintf(bar, "%s ", *foo++); 1173 while (*foo)
1177 } 1174 bar += sprintf(bar, "%s ", *foo++);
1178 } 1175 }
1179 1176
1180 /* we don't wait for background thejobs to return -- append it 1177 /* we don't wait for background thejobs to return -- append it
@@ -1218,18 +1215,18 @@ static int checkjobs(struct pipe* fg_pipe)
1218 pid_t childpid; 1215 pid_t childpid;
1219 1216
1220 attributes = WUNTRACED; 1217 attributes = WUNTRACED;
1221 if (fg_pipe==NULL) { 1218 if (fg_pipe == NULL) {
1222 attributes |= WNOHANG; 1219 attributes |= WNOHANG;
1223 } 1220 }
1224 1221
1225 while ((childpid = waitpid(-1, &status, attributes)) > 0) { 1222 while ((childpid = waitpid(-1, &status, attributes)) > 0) {
1226 if (fg_pipe) { 1223 if (fg_pipe) {
1227 int i, rcode = 0; 1224 int i, rcode = 0;
1228 for (i=0; i < fg_pipe->num_progs; i++) { 1225 for (i = 0; i < fg_pipe->num_progs; i++) {
1229 if (fg_pipe->progs[i].pid == childpid) { 1226 if (fg_pipe->progs[i].pid == childpid) {
1230 if (i==fg_pipe->num_progs-1) 1227 if (i == fg_pipe->num_progs-1)
1231 rcode=WEXITSTATUS(status); 1228 rcode = WEXITSTATUS(status);
1232 (fg_pipe->num_progs)--; 1229 fg_pipe->num_progs--;
1233 return rcode; 1230 return rcode;
1234 } 1231 }
1235 } 1232 }
@@ -1244,8 +1241,9 @@ static int checkjobs(struct pipe* fg_pipe)
1244 break; 1241 break;
1245 } 1242 }
1246 1243
1247 if(pi==NULL) { 1244 if (pi == NULL) {
1248 debug_printf("checkjobs: pid %d was not in our list!\n", childpid); 1245 debug_printf("checkjobs: pid %d was not in our list!\n",
1246 childpid);
1249 continue; 1247 continue;
1250 } 1248 }
1251 1249
@@ -1255,7 +1253,8 @@ static int checkjobs(struct pipe* fg_pipe)
1255 pi->progs[prognum].pid = 0; 1253 pi->progs[prognum].pid = 0;
1256 1254
1257 if (!pi->running_progs) { 1255 if (!pi->running_progs) {
1258 printf(JOB_STATUS_FORMAT, pi->jobid, "Done", pi->text); 1256 printf(JOB_STATUS_FORMAT, pi->jobid,
1257 "Done", pi->text);
1259 remove_bg_job(pi); 1258 remove_bg_job(pi);
1260 } 1259 }
1261 } else { 1260 } else {
@@ -1306,9 +1305,9 @@ static int run_pipe_real(struct pipe *pi)
1306 * Builtins within pipes have to fork anyway, and are handled in 1305 * Builtins within pipes have to fork anyway, and are handled in
1307 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. 1306 * pseudo_exec. "echo foo | read bar" doesn't work on bash, either.
1308 */ 1307 */
1309 child = & (pi->progs[0]); 1308 child = &(pi->progs[0]);
1310 if (pi->num_progs == 1 && child->group && child->subshell == 0) { 1309 if (pi->num_progs == 1 && child->group && child->subshell == 0) {
1311 int squirrel[] = {-1, -1, -1}; 1310 int squirrel[] = { -1, -1, -1 };
1312 int rcode; 1311 int rcode;
1313 debug_printf("non-subshell grouping\n"); 1312 debug_printf("non-subshell grouping\n");
1314 setup_redirects(child, squirrel); 1313 setup_redirects(child, squirrel);
@@ -1318,31 +1317,32 @@ static int run_pipe_real(struct pipe *pi)
1318 restore_redirects(squirrel); 1317 restore_redirects(squirrel);
1319 return rcode; 1318 return rcode;
1320 } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) { 1319 } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
1321 for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ } 1320 for (i = 0; is_assignment(child->argv[i]); i++)
1322 if (i!=0 && child->argv[i]==NULL) { 1321 /* nothing */;
1322 if (i != 0 && child->argv[i] == NULL) {
1323 /* assignments, but no command: set the local environment */ 1323 /* assignments, but no command: set the local environment */
1324 for (i=0; child->argv[i]!=NULL; i++) { 1324 for (i = 0; child->argv[i] != NULL; i++) {
1325
1326 /* Ok, this case is tricky. We have to decide if this is a 1325 /* Ok, this case is tricky. We have to decide if this is a
1327 * local variable, or an already exported variable. If it is 1326 * local variable, or an already exported variable. If it is
1328 * already exported, we have to export the new value. If it is 1327 * already exported, we have to export the new value. If it is
1329 * not exported, we need only set this as a local variable. 1328 * not exported, we need only set this as a local variable.
1330 * This junk is all to decide whether or not to export this 1329 * This junk is all to decide whether or not to export this
1331 * variable. */ 1330 * variable. */
1332 int export_me=0; 1331 int export_me = 0;
1333 char *name, *value; 1332 char *name, *value;
1334 name = xstrdup(child->argv[i]); 1333 name = xstrdup(child->argv[i]);
1335 debug_printf("Local environment set: %s\n", name); 1334 debug_printf("Local environment set: %s\n", name);
1336 value = strchr(name, '='); 1335 value = strchr(name, '=');
1337 if (value) 1336 if (value)
1338 *value=0; 1337 *value = 0;
1339 if ( get_local_var(name)) { 1338 if (get_local_var(name)) {
1340 export_me=1; 1339 export_me = 1;
1341 } 1340 }
1342 free(name); 1341 free(name);
1343 p = insert_var_value(child->argv[i]); 1342 p = insert_var_value(child->argv[i]);
1344 set_local_var(p, export_me); 1343 set_local_var(p, export_me);
1345 if (p != child->argv[i]) free(p); 1344 if (p != child->argv[i])
1345 free(p);
1346 } 1346 }
1347 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ 1347 return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */
1348 } 1348 }
@@ -1355,7 +1355,7 @@ static int run_pipe_real(struct pipe *pi)
1355 } 1355 }
1356 } 1356 }
1357 if (child->sp) { 1357 if (child->sp) {
1358 char * str = NULL; 1358 char *str = NULL;
1359 1359
1360 str = make_string((child->argv + i)); 1360 str = make_string((child->argv + i));
1361 parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); 1361 parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
@@ -1364,9 +1364,9 @@ static int run_pipe_real(struct pipe *pi)
1364 } 1364 }
1365 for (x = bltins; x->cmd; x++) { 1365 for (x = bltins; x->cmd; x++) {
1366 if (strcmp(child->argv[i], x->cmd) == 0 ) { 1366 if (strcmp(child->argv[i], x->cmd) == 0 ) {
1367 int squirrel[] = {-1, -1, -1}; 1367 int squirrel[] = { -1, -1, -1 };
1368 int rcode; 1368 int rcode;
1369 if (x->function == builtin_exec && child->argv[i+1]==NULL) { 1369 if (x->function == builtin_exec && child->argv[i+1] == NULL) {
1370 debug_printf("magic exec\n"); 1370 debug_printf("magic exec\n");
1371 setup_redirects(child,NULL); 1371 setup_redirects(child,NULL);
1372 return EXIT_SUCCESS; 1372 return EXIT_SUCCESS;
@@ -1377,9 +1377,9 @@ static int run_pipe_real(struct pipe *pi)
1377 * Is it really safe for inline use? Experimentally, 1377 * Is it really safe for inline use? Experimentally,
1378 * things seem to work with glibc. */ 1378 * things seem to work with glibc. */
1379 setup_redirects(child, squirrel); 1379 setup_redirects(child, squirrel);
1380 child->argv+=i; /* XXX horrible hack */ 1380 child->argv += i; /* XXX horrible hack */
1381 rcode = x->function(child); 1381 rcode = x->function(child);
1382 child->argv-=i; /* XXX restore hack so free() can work right */ 1382 child->argv -= i; /* XXX restore hack so free() can work right */
1383 restore_redirects(squirrel); 1383 restore_redirects(squirrel);
1384 return rcode; 1384 return rcode;
1385 } 1385 }
@@ -1387,24 +1387,25 @@ static int run_pipe_real(struct pipe *pi)
1387 } 1387 }
1388 1388
1389 for (i = 0; i < pi->num_progs; i++) { 1389 for (i = 0; i < pi->num_progs; i++) {
1390 child = & (pi->progs[i]); 1390 child = &(pi->progs[i]);
1391 1391
1392 /* pipes are inserted between pairs of commands */ 1392 /* pipes are inserted between pairs of commands */
1393 if ((i + 1) < pi->num_progs) { 1393 if ((i + 1) < pi->num_progs) {
1394 if (pipe(pipefds)<0) bb_perror_msg_and_die("pipe"); 1394 if (pipe(pipefds) < 0)
1395 bb_perror_msg_and_die("pipe");
1395 nextout = pipefds[1]; 1396 nextout = pipefds[1];
1396 } else { 1397 } else {
1397 nextout=1; 1398 nextout = 1;
1398 pipefds[0] = -1; 1399 pipefds[0] = -1;
1399 } 1400 }
1400 1401
1401 /* XXX test for failed fork()? */ 1402 /* XXX test for failed fork()? */
1402#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__) 1403#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
1403 if (!(child->pid = fork())) 1404 child->pid = fork();
1404#else 1405#else
1405 if (!(child->pid = vfork())) 1406 child->pid = vfork();
1406#endif 1407#endif
1407 { 1408 if (!child->pid) {
1408 /* Set the handling for job control signals back to the default. */ 1409 /* Set the handling for job control signals back to the default. */
1409 signal(SIGINT, SIG_DFL); 1410 signal(SIGINT, SIG_DFL);
1410 signal(SIGQUIT, SIG_DFL); 1411 signal(SIGQUIT, SIG_DFL);
@@ -1446,7 +1447,6 @@ static int run_pipe_real(struct pipe *pi)
1446 pseudo_exec(child); 1447 pseudo_exec(child);
1447 } 1448 }
1448 1449
1449
1450 /* put our child in the process group whose leader is the 1450 /* put our child in the process group whose leader is the
1451 first process in this pipe */ 1451 first process in this pipe */
1452 if (pi->pgrp < 0) { 1452 if (pi->pgrp < 0) {
@@ -1476,81 +1476,87 @@ static int run_list_real(struct pipe *pi)
1476 struct pipe *rpipe; 1476 struct pipe *rpipe;
1477 int flag_rep = 0; 1477 int flag_rep = 0;
1478 int save_num_progs; 1478 int save_num_progs;
1479 int rcode=0, flag_skip=1; 1479 int rcode = 0, flag_skip = 1;
1480 int flag_restore = 0; 1480 int flag_restore = 0;
1481 int if_code=0, next_if_code=0; /* need double-buffer to handle elif */ 1481 int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */
1482 reserved_style rmode, skip_more_in_this_rmode=RES_XXXX; 1482 reserved_style rmode, skip_more_in_this_rmode = RES_XXXX;
1483 /* check syntax for "for" */ 1483 /* check syntax for "for" */
1484 for (rpipe = pi; rpipe; rpipe = rpipe->next) { 1484 for (rpipe = pi; rpipe; rpipe = rpipe->next) {
1485 if ((rpipe->r_mode == RES_IN || 1485 if ((rpipe->r_mode == RES_IN || rpipe->r_mode == RES_FOR)
1486 rpipe->r_mode == RES_FOR) && 1486 && (rpipe->next == NULL)
1487 (rpipe->next == NULL)) { 1487 ) {
1488 syntax(); 1488 syntax();
1489 return 1; 1489 return 1;
1490 } 1490 }
1491 if ((rpipe->r_mode == RES_IN && 1491 if ((rpipe->r_mode == RES_IN && rpipe->next->r_mode == RES_IN && rpipe->next->progs->argv != NULL)
1492 (rpipe->next->r_mode == RES_IN && 1492 || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN)
1493 rpipe->next->progs->argv != NULL))|| 1493 ) {
1494 (rpipe->r_mode == RES_FOR && 1494 syntax();
1495 rpipe->next->r_mode != RES_IN)) { 1495 return 1;
1496 syntax();
1497 return 1;
1498 } 1496 }
1499 } 1497 }
1500 for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) { 1498 for (; pi; pi = (flag_restore != 0) ? rpipe : pi->next) {
1501 if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL || 1499 if (pi->r_mode == RES_WHILE || pi->r_mode == RES_UNTIL
1502 pi->r_mode == RES_FOR) { 1500 || pi->r_mode == RES_FOR
1503 flag_restore = 0; 1501 ) {
1504 if (!rpipe) { 1502 flag_restore = 0;
1505 flag_rep = 0; 1503 if (!rpipe) {
1506 rpipe = pi; 1504 flag_rep = 0;
1507 } 1505 rpipe = pi;
1506 }
1508 } 1507 }
1509 rmode = pi->r_mode; 1508 rmode = pi->r_mode;
1510 debug_printf("rmode=%d if_code=%d next_if_code=%d skip_more=%d\n", rmode, if_code, next_if_code, skip_more_in_this_rmode); 1509 debug_printf("rmode=%d if_code=%d next_if_code=%d skip_more=%d\n",
1510 rmode, if_code, next_if_code, skip_more_in_this_rmode);
1511 if (rmode == skip_more_in_this_rmode && flag_skip) { 1511 if (rmode == skip_more_in_this_rmode && flag_skip) {
1512 if (pi->followup == PIPE_SEQ) flag_skip=0; 1512 if (pi->followup == PIPE_SEQ)
1513 flag_skip = 0;
1513 continue; 1514 continue;
1514 } 1515 }
1515 flag_skip = 1; 1516 flag_skip = 1;
1516 skip_more_in_this_rmode = RES_XXXX; 1517 skip_more_in_this_rmode = RES_XXXX;
1517 if (rmode == RES_THEN || rmode == RES_ELSE) if_code = next_if_code; 1518 if (rmode == RES_THEN || rmode == RES_ELSE)
1518 if (rmode == RES_THEN && if_code) continue; 1519 if_code = next_if_code;
1519 if (rmode == RES_ELSE && !if_code) continue; 1520 if (rmode == RES_THEN && if_code)
1520 if (rmode == RES_ELIF && !if_code) break; 1521 continue;
1522 if (rmode == RES_ELSE && !if_code)
1523 continue;
1524 if (rmode == RES_ELIF && !if_code)
1525 break;
1521 if (rmode == RES_FOR && pi->num_progs) { 1526 if (rmode == RES_FOR && pi->num_progs) {
1522 if (!list) { 1527 if (!list) {
1523 /* if no variable values after "in" we skip "for" */ 1528 /* if no variable values after "in" we skip "for" */
1524 if (!pi->next->progs->argv) continue; 1529 if (!pi->next->progs->argv)
1530 continue;
1525 /* create list of variable values */ 1531 /* create list of variable values */
1526 list = make_list_in(pi->next->progs->argv, 1532 list = make_list_in(pi->next->progs->argv,
1527 pi->progs->argv[0]); 1533 pi->progs->argv[0]);
1528 save_list = list; 1534 save_list = list;
1529 save_name = pi->progs->argv[0]; 1535 save_name = pi->progs->argv[0];
1530 pi->progs->argv[0] = NULL; 1536 pi->progs->argv[0] = NULL;
1531 flag_rep = 1; 1537 flag_rep = 1;
1532 } 1538 }
1533 if (!(*list)) { 1539 if (!*list) {
1534 free(pi->progs->argv[0]); 1540 free(pi->progs->argv[0]);
1535 free(save_list); 1541 free(save_list);
1536 list = NULL; 1542 list = NULL;
1537 flag_rep = 0; 1543 flag_rep = 0;
1538 pi->progs->argv[0] = save_name; 1544 pi->progs->argv[0] = save_name;
1539 pi->progs->glob_result.gl_pathv[0] = 1545 pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
1540 pi->progs->argv[0];
1541 continue; 1546 continue;
1542 } else { 1547 } else {
1543 /* insert new value from list for variable */ 1548 /* insert new value from list for variable */
1544 if (pi->progs->argv[0]) 1549 if (pi->progs->argv[0])
1545 free(pi->progs->argv[0]); 1550 free(pi->progs->argv[0]);
1546 pi->progs->argv[0] = *list++; 1551 pi->progs->argv[0] = *list++;
1547 pi->progs->glob_result.gl_pathv[0] = 1552 pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
1548 pi->progs->argv[0];
1549 } 1553 }
1550 } 1554 }
1551 if (rmode == RES_IN) continue; 1555 if (rmode == RES_IN)
1556 continue;
1552 if (rmode == RES_DO) { 1557 if (rmode == RES_DO) {
1553 if (!flag_rep) continue; 1558 if (!flag_rep)
1559 continue;
1554 } 1560 }
1555 if ((rmode == RES_DONE)) { 1561 if ((rmode == RES_DONE)) {
1556 if (flag_rep) { 1562 if (flag_rep) {
@@ -1559,14 +1565,15 @@ static int run_list_real(struct pipe *pi)
1559 rpipe = NULL; 1565 rpipe = NULL;
1560 } 1566 }
1561 } 1567 }
1562 if (pi->num_progs == 0) continue; 1568 if (pi->num_progs == 0)
1569 continue;
1563 save_num_progs = pi->num_progs; /* save number of programs */ 1570 save_num_progs = pi->num_progs; /* save number of programs */
1564 rcode = run_pipe_real(pi); 1571 rcode = run_pipe_real(pi);
1565 debug_printf("run_pipe_real returned %d\n",rcode); 1572 debug_printf("run_pipe_real returned %d\n",rcode);
1566 if (rcode!=-1) { 1573 if (rcode != -1) {
1567 /* We only ran a builtin: rcode was set by the return value 1574 /* We only ran a builtin: rcode was set by the return value
1568 * of run_pipe_real(), and we don't need to wait for anything. */ 1575 * of run_pipe_real(), and we don't need to wait for anything. */
1569 } else if (pi->followup==PIPE_BG) { 1576 } else if (pi->followup == PIPE_BG) {
1570 /* XXX check bash's behavior with nontrivial pipes */ 1577 /* XXX check bash's behavior with nontrivial pipes */
1571 /* XXX compute jobid */ 1578 /* XXX compute jobid */
1572 /* XXX what does bash do with attempts to background builtins? */ 1579 /* XXX what does bash do with attempts to background builtins? */
@@ -1586,17 +1593,19 @@ static int run_list_real(struct pipe *pi)
1586 } 1593 }
1587 debug_printf("checkjobs returned %d\n",rcode); 1594 debug_printf("checkjobs returned %d\n",rcode);
1588 } 1595 }
1589 last_return_code=rcode; 1596 last_return_code = rcode;
1590 pi->num_progs = save_num_progs; /* restore number of programs */ 1597 pi->num_progs = save_num_progs; /* restore number of programs */
1591 if ( rmode == RES_IF || rmode == RES_ELIF ) 1598 if ( rmode == RES_IF || rmode == RES_ELIF )
1592 next_if_code=rcode; /* can be overwritten a number of times */ 1599 next_if_code = rcode; /* can be overwritten a number of times */
1593 if (rmode == RES_WHILE) 1600 if (rmode == RES_WHILE)
1594 flag_rep = !last_return_code; 1601 flag_rep = !last_return_code;
1595 if (rmode == RES_UNTIL) 1602 if (rmode == RES_UNTIL)
1596 flag_rep = last_return_code; 1603 flag_rep = last_return_code;
1597 if ( (rcode==EXIT_SUCCESS && pi->followup==PIPE_OR) || 1604 if ((rcode == EXIT_SUCCESS && pi->followup == PIPE_OR)
1598 (rcode!=EXIT_SUCCESS && pi->followup==PIPE_AND) ) 1605 || (rcode != EXIT_SUCCESS && pi->followup == PIPE_AND)
1599 skip_more_in_this_rmode=rmode; 1606 ) {
1607 skip_more_in_this_rmode = rmode;
1608 }
1600 checkjobs(NULL); 1609 checkjobs(NULL);
1601 } 1610 }
1602 return rcode; 1611 return rcode;
@@ -1608,28 +1617,28 @@ static int free_pipe(struct pipe *pi, int indent)
1608 char **p; 1617 char **p;
1609 struct child_prog *child; 1618 struct child_prog *child;
1610 struct redir_struct *r, *rnext; 1619 struct redir_struct *r, *rnext;
1611 int a, i, ret_code=0; 1620 int a, i, ret_code = 0;
1612 1621
1613 if (pi->stopped_progs > 0) 1622 if (pi->stopped_progs > 0)
1614 return ret_code; 1623 return ret_code;
1615 final_printf("%s run pipe: (pid %d)\n",indenter(indent),getpid()); 1624 final_printf("%s run pipe: (pid %d)\n", indenter(indent), getpid());
1616 for (i=0; i<pi->num_progs; i++) { 1625 for (i = 0; i < pi->num_progs; i++) {
1617 child = &pi->progs[i]; 1626 child = &pi->progs[i];
1618 final_printf("%s command %d:\n",indenter(indent),i); 1627 final_printf("%s command %d:\n", indenter(indent), i);
1619 if (child->argv) { 1628 if (child->argv) {
1620 for (a=0,p=child->argv; *p; a++,p++) { 1629 for (a = 0, p = child->argv; *p; a++, p++) {
1621 final_printf("%s argv[%d] = %s\n",indenter(indent),a,*p); 1630 final_printf("%s argv[%d] = %s\n", indenter(indent), a, *p);
1622 } 1631 }
1623 globfree(&child->glob_result); 1632 globfree(&child->glob_result);
1624 child->argv=NULL; 1633 child->argv = NULL;
1625 } else if (child->group) { 1634 } else if (child->group) {
1626 final_printf("%s begin group (subshell:%d)\n",indenter(indent), child->subshell); 1635 final_printf("%s begin group (subshell:%d)\n", indenter(indent), child->subshell);
1627 ret_code = free_pipe_list(child->group,indent+3); 1636 ret_code = free_pipe_list(child->group, indent+3);
1628 final_printf("%s end group\n",indenter(indent)); 1637 final_printf("%s end group\n", indenter(indent));
1629 } else { 1638 } else {
1630 final_printf("%s (nil)\n",indenter(indent)); 1639 final_printf("%s (nil)\n", indenter(indent));
1631 } 1640 }
1632 for (r=child->redirects; r; r=rnext) { 1641 for (r = child->redirects; r; r = rnext) {
1633 final_printf("%s redirect %d%s", indenter(indent), r->fd, redir_table[r->type].descrip); 1642 final_printf("%s redirect %d%s", indenter(indent), r->fd, redir_table[r->type].descrip);
1634 if (r->dup == -1) { 1643 if (r->dup == -1) {
1635 /* guard against the case >$FOO, where foo is unset or blank */ 1644 /* guard against the case >$FOO, where foo is unset or blank */
@@ -1640,26 +1649,26 @@ static int free_pipe(struct pipe *pi, int indent)
1640 } else { 1649 } else {
1641 final_printf("&%d\n", r->dup); 1650 final_printf("&%d\n", r->dup);
1642 } 1651 }
1643 rnext=r->next; 1652 rnext = r->next;
1644 free(r); 1653 free(r);
1645 } 1654 }
1646 child->redirects=NULL; 1655 child->redirects = NULL;
1647 } 1656 }
1648 free(pi->progs); /* children are an array, they get freed all at once */ 1657 free(pi->progs); /* children are an array, they get freed all at once */
1649 pi->progs=NULL; 1658 pi->progs = NULL;
1650 return ret_code; 1659 return ret_code;
1651} 1660}
1652 1661
1653static int free_pipe_list(struct pipe *head, int indent) 1662static int free_pipe_list(struct pipe *head, int indent)
1654{ 1663{
1655 int rcode=0; /* if list has no members */ 1664 int rcode = 0; /* if list has no members */
1656 struct pipe *pi, *next; 1665 struct pipe *pi, *next;
1657 for (pi=head; pi; pi=next) { 1666 for (pi = head; pi; pi = next) {
1658 final_printf("%s pipe reserved mode %d\n", indenter(indent), pi->r_mode); 1667 final_printf("%s pipe reserved mode %d\n", indenter(indent), pi->r_mode);
1659 rcode = free_pipe(pi, indent); 1668 rcode = free_pipe(pi, indent);
1660 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);
1661 next=pi->next; 1670 next = pi->next;
1662 pi->next=NULL; 1671 pi->next = NULL;
1663 free(pi); 1672 free(pi);
1664 } 1673 }
1665 return rcode; 1674 return rcode;
@@ -1668,8 +1677,8 @@ static int free_pipe_list(struct pipe *head, int indent)
1668/* Select which version we will use */ 1677/* Select which version we will use */
1669static int run_list(struct pipe *pi) 1678static int run_list(struct pipe *pi)
1670{ 1679{
1671 int rcode=0; 1680 int rcode = 0;
1672 if (fake_mode==0) { 1681 if (fake_mode == 0) {
1673 rcode = run_list_real(pi); 1682 rcode = run_list_real(pi);
1674 } 1683 }
1675 /* free_pipe_list has the side effect of clearing memory 1684 /* free_pipe_list has the side effect of clearing memory
@@ -1688,31 +1697,31 @@ static int run_list(struct pipe *pi)
1688 */ 1697 */
1689static int globhack(const char *src, int flags, glob_t *pglob) 1698static int globhack(const char *src, int flags, glob_t *pglob)
1690{ 1699{
1691 int cnt=0, pathc; 1700 int cnt = 0, pathc;
1692 const char *s; 1701 const char *s;
1693 char *dest; 1702 char *dest;
1694 for (cnt=1, s=src; s && *s; s++) { 1703 for (cnt = 1, s = src; s && *s; s++) {
1695 if (*s == '\\') s++; 1704 if (*s == '\\') s++;
1696 cnt++; 1705 cnt++;
1697 } 1706 }
1698 dest = malloc(cnt); 1707 dest = malloc(cnt);
1699 if (!dest) return GLOB_NOSPACE; 1708 if (!dest) return GLOB_NOSPACE;
1700 if (!(flags & GLOB_APPEND)) { 1709 if (!(flags & GLOB_APPEND)) {
1701 pglob->gl_pathv=NULL; 1710 pglob->gl_pathv = NULL;
1702 pglob->gl_pathc=0; 1711 pglob->gl_pathc = 0;
1703 pglob->gl_offs=0; 1712 pglob->gl_offs = 0;
1704 pglob->gl_offs=0; 1713 pglob->gl_offs = 0;
1705 } 1714 }
1706 pathc = ++pglob->gl_pathc; 1715 pathc = ++pglob->gl_pathc;
1707 pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv)); 1716 pglob->gl_pathv = realloc(pglob->gl_pathv, (pathc+1)*sizeof(*pglob->gl_pathv));
1708 if (pglob->gl_pathv == NULL) return GLOB_NOSPACE; 1717 if (pglob->gl_pathv == NULL) return GLOB_NOSPACE;
1709 pglob->gl_pathv[pathc-1]=dest; 1718 pglob->gl_pathv[pathc-1] = dest;
1710 pglob->gl_pathv[pathc]=NULL; 1719 pglob->gl_pathv[pathc] = NULL;
1711 for (s=src; s && *s; s++, dest++) { 1720 for (s = src; s && *s; s++, dest++) {
1712 if (*s == '\\') s++; 1721 if (*s == '\\') s++;
1713 *dest = *s; 1722 *dest = *s;
1714 } 1723 }
1715 *dest='\0'; 1724 *dest = '\0';
1716 return 0; 1725 return 0;
1717} 1726}
1718 1727
@@ -1721,7 +1730,7 @@ static int glob_needed(const char *s)
1721{ 1730{
1722 for (; *s; s++) { 1731 for (; *s; s++) {
1723 if (*s == '\\') s++; 1732 if (*s == '\\') s++;
1724 if (strchr("*[?",*s)) return 1; 1733 if (strchr("*[?", *s)) return 1;
1725 } 1734 }
1726 return 0; 1735 return 0;
1727} 1736}
@@ -1736,26 +1745,26 @@ static int xglob(o_string *dest, int flags, glob_t *pglob)
1736 if (dest->nonnull) { 1745 if (dest->nonnull) {
1737 /* bash man page calls this an "explicit" null */ 1746 /* bash man page calls this an "explicit" null */
1738 gr = globhack(dest->data, flags, pglob); 1747 gr = globhack(dest->data, flags, pglob);
1739 debug_printf("globhack returned %d\n",gr); 1748 debug_printf("globhack returned %d\n", gr);
1740 } else { 1749 } else {
1741 return 0; 1750 return 0;
1742 } 1751 }
1743 } else if (glob_needed(dest->data)) { 1752 } else if (glob_needed(dest->data)) {
1744 gr = glob(dest->data, flags, NULL, pglob); 1753 gr = glob(dest->data, flags, NULL, pglob);
1745 debug_printf("glob returned %d\n",gr); 1754 debug_printf("glob returned %d\n", gr);
1746 if (gr == GLOB_NOMATCH) { 1755 if (gr == GLOB_NOMATCH) {
1747 /* quote removal, or more accurately, backslash removal */ 1756 /* quote removal, or more accurately, backslash removal */
1748 gr = globhack(dest->data, flags, pglob); 1757 gr = globhack(dest->data, flags, pglob);
1749 debug_printf("globhack returned %d\n",gr); 1758 debug_printf("globhack returned %d\n", gr);
1750 } 1759 }
1751 } else { 1760 } else {
1752 gr = globhack(dest->data, flags, pglob); 1761 gr = globhack(dest->data, flags, pglob);
1753 debug_printf("globhack returned %d\n",gr); 1762 debug_printf("globhack returned %d\n", gr);
1754 } 1763 }
1755 if (gr == GLOB_NOSPACE) 1764 if (gr == GLOB_NOSPACE)
1756 bb_error_msg_and_die("out of memory during glob"); 1765 bb_error_msg_and_die("out of memory during glob");
1757 if (gr != 0) { /* GLOB_ABORTED ? */ 1766 if (gr != 0) { /* GLOB_ABORTED ? */
1758 bb_error_msg("glob(3) error %d",gr); 1767 bb_error_msg("glob(3) error %d", gr);
1759 } 1768 }
1760 /* globprint(glob_target); */ 1769 /* globprint(glob_target); */
1761 return gr; 1770 return gr;
@@ -1768,8 +1777,8 @@ static const char *get_local_var(const char *s)
1768 1777
1769 if (!s) 1778 if (!s)
1770 return NULL; 1779 return NULL;
1771 for (cur = top_vars; cur; cur=cur->next) 1780 for (cur = top_vars; cur; cur = cur->next)
1772 if(strcmp(cur->name, s)==0) 1781 if (strcmp(cur->name, s) == 0)
1773 return cur->value; 1782 return cur->value;
1774 return NULL; 1783 return NULL;
1775} 1784}
@@ -1781,39 +1790,39 @@ static const char *get_local_var(const char *s)
1781static int set_local_var(const char *s, int flg_export) 1790static int set_local_var(const char *s, int flg_export)
1782{ 1791{
1783 char *name, *value; 1792 char *name, *value;
1784 int result=0; 1793 int result = 0;
1785 struct variables *cur; 1794 struct variables *cur;
1786 1795
1787 name=strdup(s); 1796 name = strdup(s);
1788 1797
1789 /* Assume when we enter this function that we are already in 1798 /* Assume when we enter this function that we are already in
1790 * NAME=VALUE format. So the first order of business is to 1799 * NAME=VALUE format. So the first order of business is to
1791 * split 's' on the '=' into 'name' and 'value' */ 1800 * split 's' on the '=' into 'name' and 'value' */
1792 value = strchr(name, '='); 1801 value = strchr(name, '=');
1793 if (value==0 && ++value==0) { 1802 if (value == 0 && ++value == 0) {
1794 free(name); 1803 free(name);
1795 return -1; 1804 return -1;
1796 } 1805 }
1797 *value++ = 0; 1806 *value++ = 0;
1798 1807
1799 for(cur = top_vars; cur; cur = cur->next) { 1808 for (cur = top_vars; cur; cur = cur->next) {
1800 if(strcmp(cur->name, name)==0) 1809 if (strcmp(cur->name, name) == 0)
1801 break; 1810 break;
1802 } 1811 }
1803 1812
1804 if(cur) { 1813 if (cur) {
1805 if(strcmp(cur->value, value)==0) { 1814 if (strcmp(cur->value, value) == 0) {
1806 if(flg_export>0 && cur->flg_export==0) 1815 if (flg_export>0 && cur->flg_export == 0)
1807 cur->flg_export = flg_export; 1816 cur->flg_export = flg_export;
1808 else 1817 else
1809 result++; 1818 result++;
1810 } else { 1819 } else {
1811 if(cur->flg_read_only) { 1820 if (cur->flg_read_only) {
1812 bb_error_msg("%s: readonly variable", name); 1821 bb_error_msg("%s: readonly variable", name);
1813 result = -1; 1822 result = -1;
1814 } else { 1823 } else {
1815 if(flg_export>0 || cur->flg_export>1) 1824 if (flg_export > 0 || cur->flg_export>1)
1816 cur->flg_export=1; 1825 cur->flg_export = 1;
1817 free((char*)cur->value); 1826 free((char*)cur->value);
1818 1827
1819 cur->value = strdup(value); 1828 cur->value = strdup(value);
@@ -1821,11 +1830,11 @@ static int set_local_var(const char *s, int flg_export)
1821 } 1830 }
1822 } else { 1831 } else {
1823 cur = malloc(sizeof(struct variables)); 1832 cur = malloc(sizeof(struct variables));
1824 if(!cur) { 1833 if (!cur) {
1825 result = -1; 1834 result = -1;
1826 } else { 1835 } else {
1827 cur->name = strdup(name); 1836 cur->name = strdup(name);
1828 if(cur->name == 0) { 1837 if (cur->name) {
1829 free(cur); 1838 free(cur);
1830 result = -1; 1839 result = -1;
1831 } else { 1840 } else {
@@ -1834,18 +1843,19 @@ static int set_local_var(const char *s, int flg_export)
1834 cur->next = 0; 1843 cur->next = 0;
1835 cur->flg_export = flg_export; 1844 cur->flg_export = flg_export;
1836 cur->flg_read_only = 0; 1845 cur->flg_read_only = 0;
1837 while(bottom->next) bottom=bottom->next; 1846 while (bottom->next)
1847 bottom = bottom->next;
1838 bottom->next = cur; 1848 bottom->next = cur;
1839 } 1849 }
1840 } 1850 }
1841 } 1851 }
1842 1852
1843 if(result==0 && cur->flg_export==1) { 1853 if (result == 0 && cur->flg_export == 1) {
1844 *(value-1) = '='; 1854 *(value-1) = '=';
1845 result = putenv(name); 1855 result = putenv(name);
1846 } else { 1856 } else {
1847 free(name); 1857 free(name);
1848 if(result>0) /* equivalent to previous set */ 1858 if (result > 0) /* equivalent to previous set */
1849 result = 0; 1859 result = 0;
1850 } 1860 }
1851 return result; 1861 return result;
@@ -1856,24 +1866,23 @@ static void unset_local_var(const char *name)
1856 struct variables *cur; 1866 struct variables *cur;
1857 1867
1858 if (name) { 1868 if (name) {
1859 for (cur = top_vars; cur; cur=cur->next) { 1869 for (cur = top_vars; cur; cur = cur->next) {
1860 if(strcmp(cur->name, name)==0) 1870 if (strcmp(cur->name, name) == 0)
1861 break; 1871 break;
1862 } 1872 }
1863 if(cur!=0) { 1873 if (cur != 0) {
1864 struct variables *next = top_vars; 1874 struct variables *next = top_vars;
1865 if(cur->flg_read_only) { 1875 if (cur->flg_read_only) {
1866 bb_error_msg("%s: readonly variable", name); 1876 bb_error_msg("%s: readonly variable", name);
1867 return; 1877 return;
1868 } else {
1869 if(cur->flg_export)
1870 unsetenv(cur->name);
1871 free((char*)cur->name);
1872 free((char*)cur->value);
1873 while (next->next != cur)
1874 next = next->next;
1875 next->next = cur->next;
1876 } 1878 }
1879 if (cur->flg_export)
1880 unsetenv(cur->name);
1881 free((char*)cur->name);
1882 free((char*)cur->value);
1883 while (next->next != cur)
1884 next = next->next;
1885 next->next = cur->next;
1877 free(cur); 1886 free(cur);
1878 } 1887 }
1879 } 1888 }
@@ -1881,10 +1890,12 @@ static void unset_local_var(const char *name)
1881 1890
1882static int is_assignment(const char *s) 1891static int is_assignment(const char *s)
1883{ 1892{
1884 if (s==NULL || !isalpha(*s)) return 0; 1893 if (!s || !isalpha(*s))
1885 ++s; 1894 return 0;
1886 while(isalnum(*s) || *s=='_') ++s; 1895 s++;
1887 return *s=='='; 1896 while (isalnum(*s) || *s == '_')
1897 s++;
1898 return *s == '=';
1888} 1899}
1889 1900
1890/* the src parameter allows us to peek forward to a possible &n syntax 1901/* the src parameter allows us to peek forward to a possible &n syntax
@@ -1894,26 +1905,26 @@ static int is_assignment(const char *s)
1894static int setup_redirect(struct p_context *ctx, int fd, redir_type style, 1905static int setup_redirect(struct p_context *ctx, int fd, redir_type style,
1895 struct in_str *input) 1906 struct in_str *input)
1896{ 1907{
1897 struct child_prog *child=ctx->child; 1908 struct child_prog *child = ctx->child;
1898 struct redir_struct *redir = child->redirects; 1909 struct redir_struct *redir = child->redirects;
1899 struct redir_struct *last_redir=NULL; 1910 struct redir_struct *last_redir = NULL;
1900 1911
1901 /* Create a new redir_struct and drop it onto the end of the linked list */ 1912 /* Create a new redir_struct and drop it onto the end of the linked list */
1902 while(redir) { 1913 while (redir) {
1903 last_redir=redir; 1914 last_redir = redir;
1904 redir=redir->next; 1915 redir = redir->next;
1905 } 1916 }
1906 redir = xmalloc(sizeof(struct redir_struct)); 1917 redir = xmalloc(sizeof(struct redir_struct));
1907 redir->next=NULL; 1918 redir->next = NULL;
1908 redir->word.gl_pathv=NULL; 1919 redir->word.gl_pathv = NULL;
1909 if (last_redir) { 1920 if (last_redir) {
1910 last_redir->next=redir; 1921 last_redir->next = redir;
1911 } else { 1922 } else {
1912 child->redirects=redir; 1923 child->redirects = redir;
1913 } 1924 }
1914 1925
1915 redir->type=style; 1926 redir->type = style;
1916 redir->fd= (fd==-1) ? redir_table[style].default_fd : fd ; 1927 redir->fd = (fd == -1) ? redir_table[style].default_fd : fd;
1917 1928
1918 debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip); 1929 debug_printf("Redirect type %d%s\n", redir->fd, redir_table[style].descrip);
1919 1930
@@ -1949,14 +1960,14 @@ static struct pipe *new_pipe(void) {
1949 1960
1950static void initialize_context(struct p_context *ctx) 1961static void initialize_context(struct p_context *ctx)
1951{ 1962{
1952 ctx->pipe=NULL; 1963 ctx->pipe = NULL;
1953 ctx->pending_redirect=NULL; 1964 ctx->pending_redirect = NULL;
1954 ctx->child=NULL; 1965 ctx->child = NULL;
1955 ctx->list_head=new_pipe(); 1966 ctx->list_head = new_pipe();
1956 ctx->pipe=ctx->list_head; 1967 ctx->pipe = ctx->list_head;
1957 ctx->w=RES_NONE; 1968 ctx->w = RES_NONE;
1958 ctx->stack=NULL; 1969 ctx->stack = NULL;
1959 ctx->old_flag=0; 1970 ctx->old_flag = 0;
1960 done_command(ctx); /* creates the memory for working child */ 1971 done_command(ctx); /* creates the memory for working child */
1961} 1972}
1962 1973
@@ -1991,9 +2002,8 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
1991 { "done", RES_DONE, FLAG_END } 2002 { "done", RES_DONE, FLAG_END }
1992 }; 2003 };
1993 struct reserved_combo *r; 2004 struct reserved_combo *r;
1994 for (r=reserved_list;
1995#define NRES sizeof(reserved_list)/sizeof(struct reserved_combo) 2005#define NRES sizeof(reserved_list)/sizeof(struct reserved_combo)
1996 r<reserved_list+NRES; r++) { 2006 for (r = reserved_list; r < reserved_list+NRES; r++) {
1997 if (strcmp(dest->data, r->literal) == 0) { 2007 if (strcmp(dest->data, r->literal) == 0) {
1998 debug_printf("found reserved word %s, code %d\n",r->literal,r->code); 2008 debug_printf("found reserved word %s, code %d\n",r->literal,r->code);
1999 if (r->flag & FLAG_START) { 2009 if (r->flag & FLAG_START) {
@@ -2180,7 +2190,7 @@ static int redirect_opt_num(o_string *o)
2180 int num; 2190 int num;
2181 2191
2182 if (o->length==0) return -1; 2192 if (o->length==0) return -1;
2183 for(num=0; num<o->length; num++) { 2193 for (num=0; num<o->length; num++) {
2184 if (!isdigit(*(o->data+num))) { 2194 if (!isdigit(*(o->data+num))) {
2185 return -1; 2195 return -1;
2186 } 2196 }
@@ -2310,7 +2320,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
2310 if (isalpha(ch)) { 2320 if (isalpha(ch)) {
2311 b_addchr(dest, SPECIAL_VAR_SYMBOL); 2321 b_addchr(dest, SPECIAL_VAR_SYMBOL);
2312 ctx->child->sp++; 2322 ctx->child->sp++;
2313 while(ch=b_peek(input),isalnum(ch) || ch=='_') { 2323 while (ch=b_peek(input),isalnum(ch) || ch=='_') {
2314 b_getch(input); 2324 b_getch(input);
2315 b_addchr(dest,ch); 2325 b_addchr(dest,ch);
2316 } 2326 }
@@ -2343,7 +2353,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
2343 ctx->child->sp++; 2353 ctx->child->sp++;
2344 b_getch(input); 2354 b_getch(input);
2345 /* XXX maybe someone will try to escape the '}' */ 2355 /* XXX maybe someone will try to escape the '}' */
2346 while(ch=b_getch(input),ch!=EOF && ch!='}') { 2356 while (ch=b_getch(input),ch!=EOF && ch!='}') {
2347 b_addchr(dest,ch); 2357 b_addchr(dest,ch);
2348 } 2358 }
2349 if (ch != '}') { 2359 if (ch != '}') {
@@ -2427,7 +2437,12 @@ int parse_stream(o_string *dest, struct p_context *ctx,
2427 if (m!=2) switch (ch) { 2437 if (m!=2) switch (ch) {
2428 case '#': 2438 case '#':
2429 if (dest->length == 0 && !dest->quote) { 2439 if (dest->length == 0 && !dest->quote) {
2430 while(ch=b_peek(input),ch!=EOF && ch!='\n') { b_getch(input); } 2440 while (1) {
2441 ch = b_peek(input);
2442 if (ch == EOF || ch == '\n')
2443 break;
2444 b_getch(input);
2445 }
2431 } else { 2446 } else {
2432 b_addqchr(dest, ch, dest->quote); 2447 b_addqchr(dest, ch, dest->quote);
2433 } 2448 }
@@ -2445,10 +2460,13 @@ int parse_stream(o_string *dest, struct p_context *ctx,
2445 break; 2460 break;
2446 case '\'': 2461 case '\'':
2447 dest->nonnull = 1; 2462 dest->nonnull = 1;
2448 while(ch=b_getch(input),ch!=EOF && ch!='\'') { 2463 while (1) {
2464 ch = b_getch(input);
2465 if (ch == EOF || ch == '\'')
2466 break;
2449 b_addchr(dest,ch); 2467 b_addchr(dest,ch);
2450 } 2468 }
2451 if (ch==EOF) { 2469 if (ch == EOF) {
2452 syntax(); 2470 syntax();
2453 return 1; 2471 return 1;
2454 } 2472 }
@@ -2766,7 +2784,7 @@ int hush_main(int argc, char **argv)
2766 free((char*)cwd); 2784 free((char*)cwd);
2767 { 2785 {
2768 struct variables *cur, *tmp; 2786 struct variables *cur, *tmp;
2769 for(cur = top_vars; cur; cur = tmp) { 2787 for (cur = top_vars; cur; cur = tmp) {
2770 tmp = cur->next; 2788 tmp = cur->next;
2771 if (!cur->flg_read_only) { 2789 if (!cur->flg_read_only) {
2772 free(cur->name); 2790 free(cur->name);