Patch from Rogelio Serrano to defer checking whether the tty exists until
[oweals/busybox.git] / shell / msh.c
index 22a617095365f25c4cf65f62848d161cf85aa199..b3bb06b28fb45df90430ad8dea2bf35550754c99 100644 (file)
@@ -162,7 +162,8 @@ struct op {
 #define        TDOT    17
 
 /* Strings for names to make debug easier */
-char *T_CMD_NAMES[] = {
+#ifdef MSHDEBUG
+static char *T_CMD_NAMES[] = {
        "PLACEHOLDER",
        "TCOM",
        "TPAREN",
@@ -182,7 +183,7 @@ char *T_CMD_NAMES[] = {
        "TASYNC",
        "TDOT",
 };
-
+#endif
 
 /*
  * actions determining the environment of a process
@@ -299,7 +300,7 @@ static int rlookup(char *n);
 static struct wdblock *glob(char *cp, struct wdblock *wb);
 static int my_getc(int ec);
 static int subgetc(int ec, int quoted);
-static char **makenv(int all);
+static char **makenv(int all, struct wdblock *wb);
 static char **eval(char **ap, int f);
 static int setstatus(int s);
 static int waitfor(int lastpid, int canintr);
@@ -334,9 +335,9 @@ static void sig(int i);                     /* default signal handler */
 #define GROWBY   (256)
 /* #define     SHRINKBY   (64) */
 #undef SHRINKBY
-#define FREE     (32767)
-#define BUSY     (0)
-#define        ALIGN     (sizeof(int)-1)
+#define FREE     (32767)
+#define BUSY     (0)
+#define        ALIGN     (sizeof(int)-1)
 
 
 struct region {
@@ -513,7 +514,7 @@ static int eofc(void);
 static int readc(void);
 static void unget(int c);
 static void ioecho(int c);
-static void prs(char *s);
+static void prs(const char *s);
 static void prn(unsigned u);
 static void closef(int i);
 static void closeall(void);
@@ -621,7 +622,7 @@ struct here {
        struct here *h_next;
 };
 
-static char *signame[] = {
+static const char * const signame[] = {
        "Signal 0",
        "Hangup",
        (char *) NULL,                          /* interrupt */
@@ -643,10 +644,10 @@ static char *signame[] = {
 #define        NSIGNAL (sizeof(signame)/sizeof(signame[0]))
 
 struct res {
-       char *r_name;
+       const char *r_name;
        int r_val;
 };
-static struct res restab[] = {
+static const struct res restab[] = {
        {"for", FOR},
        {"case", CASE},
        {"esac", ESAC},
@@ -698,8 +699,7 @@ static const struct builtincmd builtincmds[] = {
        {0, 0}
 };
 
-static int expand_dotnode(struct op *);
-struct op *scantree(struct op *);
+static struct op *scantree(struct op *);
 static struct op *dowholefile(int, int);
 
 /* Globals */
@@ -709,7 +709,7 @@ static char **dolv;
 static int dolc;
 static int exstat;
 static char gflg;
-static int interactive = 0;            /* Is this an interactive shell */
+static int interactive;                        /* Is this an interactive shell */
 static int execflg;
 static int multiline;                  /* \n changed to ; */
 static struct op *outtree;             /* result from parser */
@@ -819,7 +819,7 @@ static char *current_prompt;
  */
 
 
-extern int msh_main(int argc, char **argv)
+int msh_main(int argc, char **argv)
 {
        REGISTER int f;
        REGISTER char *s;
@@ -841,7 +841,7 @@ extern int msh_main(int argc, char **argv)
 
        shell = lookup("SHELL");
        if (shell->value == null)
-               setval(shell, DEFAULT_SHELL);
+               setval(shell, (char *)DEFAULT_SHELL);
        export(shell);
 
        homedir = lookup("HOME");
@@ -956,9 +956,9 @@ extern int msh_main(int argc, char **argv)
                        interactive++;
 #ifndef CONFIG_FEATURE_SH_EXTRA_QUIET
 #ifdef MSHDEBUG
-                       printf("\n\n" BB_BANNER " Built-in shell (msh with debug)\n");
+                       printf("\n\n%s Built-in shell (msh with debug)\n", BB_BANNER);
 #else
-                       printf("\n\n" BB_BANNER " Built-in shell (msh)\n");
+                       printf("\n\n%s Built-in shell (msh)\n", BB_BANNER);
 #endif
                        printf("Enter 'help' for a list of built-in commands.\n\n");
 #endif
@@ -1047,23 +1047,6 @@ REGISTER char *s;
 }
 
 
-static int expand_dotnode(node)
-struct op *node;
-{
-       struct op *outtree_save = outtree;
-
-       node->type = TDOT;
-       newfile(node->words[1]);
-
-       node->left = dowholefile(TDOT, 0);
-
-       node->right = NULL;
-
-       outtree = outtree_save;
-
-       return (1);
-}
-
 struct op *scantree(head)
 struct op *head;
 {
@@ -1639,7 +1622,7 @@ static void initarea()
        brkaddr = malloc(AREASIZE);
        brktop = brkaddr + AREASIZE;
 
-       while ((int) sbrk(0) & ALIGN)
+       while ((long) sbrk(0) & ALIGN)
                sbrk(1);
        areabot = (struct region *) sbrk(REGSIZE);
 
@@ -2262,7 +2245,7 @@ char **wp;
 static int rlookup(n)
 REGISTER char *n;
 {
-       REGISTER struct res *rp;
+       REGISTER const struct res *rp;
 
        DBGPRINTF7(("RLOOKUP: enter, n is %s\n", n));
 
@@ -2731,7 +2714,7 @@ int act;
                                interactive = 0;
                                if (pin == NULL) {
                                        close(0);
-                                       open("/dev/null", 0);
+                                       open(bb_dev_null, 0);
                                }
                                _exit(execute(t->left, pin, pout, FEXEC));
                        }
@@ -3050,7 +3033,7 @@ forkexec(REGISTER struct op *t, int *pin, int *pout, int act, char **wp)
        if (wp[0] == NULL)
                _exit(0);
 
-       cp = rexecve(wp[0], wp, makenv(0));
+       cp = rexecve(wp[0], wp, makenv(0, NULL));
        prs(wp[0]);
        prs(": ");
        err(cp);
@@ -3504,7 +3487,7 @@ struct op *t;
                signal(SIGINT, SIG_DFL);
                signal(SIGQUIT, SIG_DFL);
        }
-       cp = rexecve(t->words[0], t->words, makenv(0));
+       cp = rexecve(t->words[0], t->words, makenv(0, NULL));
        prs(t->words[0]);
        prs(": ");
        err(cp);
@@ -3972,14 +3955,12 @@ static char **eval(char **ap, int f)
  * names in the dictionary. Keyword assignments
  * will already have been done.
  */
-static char **makenv(int all)
+static char **makenv(int all, struct wdblock *wb)
 {
-       REGISTER struct wdblock *wb;
        REGISTER struct var *vp;
 
        DBGPRINTF5(("MAKENV: enter, all=%d\n", all));
 
-       wb = NULL;
        for (vp = vlist; vp; vp = vp->next)
                if (all || vp->status & EXPORT)
                        wb = addword(vp->name, wb);
@@ -4269,6 +4250,7 @@ int quoted;
        int ignore;
        int ignore_once;
        char *argument_list[4];
+       struct wdblock *wb = NULL;
 
 #if __GNUC__
        /* Avoid longjmp clobbering */
@@ -4309,7 +4291,7 @@ int quoted;
                        }
 
                        var_name[var_index++] = *src++;
-                       while (isalnum(*src))
+                       while (isalnum(*src) || *src=='_')
                                var_name[var_index++] = *src++;
                        var_name[var_index] = 0;
 
@@ -4341,22 +4323,47 @@ int quoted;
                                src++;
                        }
 
-                       vp = lookup(var_name);
-                       if (vp->value != null)
-                               value = (operator == '+') ? alt_value : vp->value;
-                       else if (operator == '?') {
-                               err(alt_value);
-                               return (0);
-                       } else if (alt_index && (operator != '+')) {
-                               value = alt_value;
-                               if (operator == '=')
-                                       setval(vp, value);
-                       } else
-                               continue;
+                       if (isalpha(*var_name)) {
+                               /* let subshell handle it instead */
+
+                               char *namep = var_name;
+
+                               *dest++ = '$';
+                               if (braces)
+                                       *dest++ = '{';
+                               while (*namep)
+                                       *dest++ = *namep++;
+                               if (operator) {
+                                       char *altp = alt_value;
+                                       *dest++ = operator;
+                                       while (*altp)
+                                               *dest++ = *altp++;
+                               }
+                               if (braces)
+                                       *dest++ = '}';
 
-                       while (*value && (count < LINELIM)) {
-                               *dest++ = *value++;
-                               count++;
+                               wb = addword(lookup(var_name)->name, wb);
+                       } else {
+                               /* expand */
+
+                               vp = lookup(var_name);
+                               if (vp->value != null)
+                                       value = (operator == '+') ?
+                                               alt_value : vp->value;
+                               else if (operator == '?') {
+                                       err(alt_value);
+                                       return (0);
+                               } else if (alt_index && (operator != '+')) {
+                                       value = alt_value;
+                                       if (operator == '=')
+                                               setval(vp, value);
+                               } else
+                                       continue;
+
+                               while (*value && (count < LINELIM)) {
+                                       *dest++ = *value++;
+                                       count++;
+                               }
                        }
                } else {
                        *dest++ = *src++;
@@ -4401,7 +4408,7 @@ int quoted;
        argument_list[2] = child_cmd;
        argument_list[3] = 0;
 
-       cp = rexecve(argument_list[0], argument_list, makenv(1));
+       cp = rexecve(argument_list[0], argument_list, makenv(1, wb));
        prs(argument_list[0]);
        prs(": ");
        err(cp);
@@ -4632,8 +4639,8 @@ REGISTER struct wdblock *wb;
        return (wd);
 }
 
-int (*func) (char *, char *);
-int globv;
+static int (*func) (char *, char *);
+static int globv;
 
 static void glob0(a0, a1, a2, a3)
 char *a0;
@@ -5159,7 +5166,7 @@ REGISTER struct ioarg *ap;
 }
 
 static void prs(s)
-REGISTER char *s;
+REGISTER const char *s;
 {
        if (*s)
                write(2, s, strlen(s));