Do not use the _syscall5 macro -- use syscall(2) instead
[oweals/busybox.git] / shell / ash.c
index 547ad906b4ac59153b17486d6e6a7b4729767abe..fe99b02cb4605c1fd9a237b6ae743bd997012fdf 100644 (file)
@@ -550,6 +550,29 @@ static int parselleft;                  /* copy of parsefile->lleft */
 
 /* next character in input buffer */
 static char *parsenextc;                /* copy of parsefile->nextc */
+
+struct strpush {
+       struct strpush *prev;   /* preceding string on stack */
+       char *prevstring;
+       int prevnleft;
+#ifdef CONFIG_ASH_ALIAS
+       struct alias *ap;       /* if push was associated with an alias */
+#endif
+       char *string;           /* remember the string since it may change */
+};
+
+struct parsefile {
+       struct parsefile *prev; /* preceding file on stack */
+       int linno;              /* current line */
+       int fd;                 /* file descriptor (or -1 if string) */
+       int nleft;              /* number of chars left in this line */
+       int lleft;              /* number of chars left in this buffer */
+       char *nextc;            /* next char in buffer */
+       char *buf;              /* input buffer */
+       struct strpush *strpush; /* for pushing strings at this level */
+       struct strpush basestrpush; /* so pushing one is fast */
+};
+
 static struct parsefile basepf;         /* top level input file */
 static char basebuf[IBUFSIZ];           /* buffer for top level input file */
 static struct parsefile *parsefile = &basepf;  /* current input file */
@@ -1573,28 +1596,6 @@ static inline int varequal(const char *a, const char *b) {
 
 static int loopnest;            /* current loop nesting level */
 
-struct strpush {
-       struct strpush *prev;   /* preceding string on stack */
-       char *prevstring;
-       int prevnleft;
-#ifdef CONFIG_ASH_ALIAS
-       struct alias *ap;       /* if push was associated with an alias */
-#endif
-       char *string;           /* remember the string since it may change */
-};
-
-struct parsefile {
-       struct parsefile *prev; /* preceding file on stack */
-       int linno;              /* current line */
-       int fd;                 /* file descriptor (or -1 if string) */
-       int nleft;              /* number of chars left in this line */
-       int lleft;              /* number of chars left in this buffer */
-       char *nextc;            /* next char in buffer */
-       char *buf;              /* input buffer */
-       struct strpush *strpush; /* for pushing strings at this level */
-       struct strpush basestrpush; /* so pushing one is fast */
-};
-
 /*
  * The parsefile structure pointed to by the global variable parsefile
  * contains information about the current file being read.
@@ -1625,9 +1626,8 @@ static int fmtstr(char *, size_t, const char *, ...)
     __attribute__((__format__(__printf__,3,4)));
 static void xwrite(int, const void *, size_t);
 
+static int preverrout_fd;   /* save fd2 before print debug if xflag is set. */
 
-#define outerr(f)       ferror(f)
-#define out2c(c)        outcslow((c), stderr)
 
 static void out1str(const char *p)
 {
@@ -1637,15 +1637,7 @@ static void out1str(const char *p)
 static void out2str(const char *p)
 {
        outstr(p, stderr);
-}
-
-static void out1c(char c)
-{
-       char s[2];
-
-       s[0] = c;
-       s[1] = 0;
-       outstr(s, stdout);
+       flushout(stderr);
 }
 
 /*
@@ -1988,6 +1980,7 @@ static int nextopt(const char *);
 
 /* flags passed to redirect */
 #define REDIR_PUSH 01           /* save previous values of file descriptors */
+#define REDIR_SAVEFD2 03       /* set preverrout */
 
 union node;
 static void redirect(union node *, int);
@@ -2674,7 +2667,6 @@ static void evalcommand(union node *, int);
 static int evalbltin(const struct builtincmd *, int, char **);
 static int evalfun(struct funcnode *, int, char **, int);
 static void prehash(union node *);
-static int eprintlist(struct strlist *, int);
 static int bltincmd(int, char **);
 
 
@@ -2765,7 +2757,7 @@ evaltree(union node *n, int flags)
        default:
 #ifdef DEBUG
                out1fmt("Node type = %d\n", n->type);
-               flushout(stdout);
+               fflush(stdout);
                break;
 #endif
        case NNOT:
@@ -3201,7 +3193,7 @@ evalcommand(union node *cmd, int flags)
        struct arglist varlist;
        char **argv;
        int argc;
-       struct strlist *sp;
+       const struct strlist *sp;
        struct cmdentry cmdentry;
        struct job *jp;
        char *lastarg;
@@ -3244,8 +3236,9 @@ evalcommand(union node *cmd, int flags)
        if (iflag && funcnest == 0 && argc > 0)
                lastarg = nargv[-1];
 
+       preverrout_fd = 2;
        expredir(cmd->ncmd.redirect);
-       status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH);
+       status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH|REDIR_SAVEFD2);
 
        path = vpath.text;
        for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
@@ -3266,14 +3259,24 @@ evalcommand(union node *cmd, int flags)
 
        /* Print the command if xflag is set. */
        if (xflag) {
-               int sep;
+               int n;
+               const char *p = " %s";
 
-               out2str(ps4val());
-               sep = 0;
-               sep = eprintlist(varlist.list, sep);
-               eprintlist(arglist.list, sep);
-               out2c('\n');
-               flushall();
+               p++;
+               dprintf(preverrout_fd, p, ps4val());
+
+               sp = varlist.list;
+               for(n = 0; n < 2; n++) {
+                       while (sp) {
+                               dprintf(preverrout_fd, p, sp->text);
+                               sp = sp->next;
+                               if(*p == '%') {
+                                       p--;
+                               }
+                       }
+                       sp = arglist.list;
+               }
+               xwrite(preverrout_fd, "\n", 1);
        }
 
        cmd_is_exec = 0;
@@ -3418,7 +3421,7 @@ evalbltin(const struct builtincmd *cmd, int argc, char **argv) {
        exitstatus = (*cmd->builtin)(argc, argv);
        flushall();
 cmddone:
-       exitstatus |= outerr(stdout);
+       exitstatus |= ferror(stdout);
        commandname = savecmdname;
        exsig = 0;
        handler = savehandler;
@@ -3588,20 +3591,6 @@ execcmd(int argc, char **argv)
 }
 
 
-static int
-eprintlist(struct strlist *sp, int sep)
-{
-       while (sp) {
-               const char *p;
-
-               p = " %s" + (1 - sep);
-               sep |= 1;
-               fprintf(stderr, p, sp->text);
-               sp = sp->next;
-       }
-
-       return sep;
-}
 /*      $NetBSD: exec.c,v 1.35 2003/01/22 20:36:04 dsl Exp $    */
 
 /*
@@ -3632,7 +3621,6 @@ static int builtinloc = -1;             /* index in path of %builtin, or -1 */
 
 
 static void tryexec(char *, char **, char **);
-static void printentry(struct tblentry *);
 static void clearcmdentry(int);
 static struct tblentry *cmdlookup(const char *, int);
 static void delete_cmd_entry(void);
@@ -3742,7 +3730,10 @@ repeat:
                for (ap = argv; *ap; ap++)
                        ;
                ap = new = ckmalloc((ap - argv + 2) * sizeof(char *));
-               *ap++ = cmd = "/bin/sh";
+               ap[1] = cmd;
+               *ap = cmd = (char *)DEFAULT_SHELL;
+               ap += 2;
+               argv++;
                while ((*ap++ = *argv++))
                        ;
                argv = new;
@@ -3797,9 +3788,24 @@ padvance(const char **path, const char *name)
 }
 
 
-
 /*** Command hashing code ***/
 
+static void
+printentry(struct tblentry *cmdp)
+{
+       int idx;
+       const char *path;
+       char *name;
+
+       idx = cmdp->param.index;
+       path = pathval();
+       do {
+               name = padvance(&path, cmdp->cmdname);
+               stunalloc(name);
+       } while (--idx >= 0);
+       out1fmt("%s%s\n", name, (cmdp->rehash ? "*" : nullstr));
+}
+
 
 static int
 hashcmd(int argc, char **argv)
@@ -3838,25 +3844,6 @@ hashcmd(int argc, char **argv)
 }
 
 
-static void
-printentry(struct tblentry *cmdp)
-{
-       int idx;
-       const char *path;
-       char *name;
-
-       idx = cmdp->param.index;
-       path = pathval();
-       do {
-               name = padvance(&path, cmdp->cmdname);
-               stunalloc(name);
-       } while (--idx >= 0);
-       out1str(name);
-       out1fmt(snlfmt, cmdp->rehash ? "*" : nullstr);
-}
-
-
-
 /*
  * Resolve a command name.  If you change this routine, you may have to
  * change the shellexec routine as well.
@@ -4401,7 +4388,7 @@ describe_command(char *command)
        }
 
 out:
-       out1c('\n');
+       outstr("\n", stdout);
        return 0;
 }
 
@@ -5645,7 +5632,7 @@ expmeta(char *enddir, char *name)
        char *start;
        char *endname;
        int metaflag;
-       struct stat64 statb;
+       struct stat statb;
        DIR *dirp;
        struct dirent *dp;
        int atend;
@@ -5688,7 +5675,7 @@ out:
                                p++;
                        *enddir++ = *p;
                } while (*p++);
-               if (metaflag == 0 || lstat64(expdir, &statb) >= 0)
+               if (metaflag == 0 || lstat(expdir, &statb) >= 0)
                        addfname(expdir);
                return;
        }
@@ -6155,7 +6142,6 @@ check:
 
        if (vflag) {
                out2str(parsenextc);
-               flushout(stderr);
        }
 
        *q = savec;
@@ -6696,25 +6682,28 @@ sprint_status(char *s, int status, int sigonly)
        int st;
 
        col = 0;
-       st = WEXITSTATUS(status);
        if (!WIFEXITED(status)) {
-               st = WSTOPSIG(status);
 #if JOBS
-               if (!WIFSTOPPED(status))
-                       st = WTERMSIG(status);
+               if (WIFSTOPPED(status))
+                       st = WSTOPSIG(status);
+               else
 #endif
+                       st = WTERMSIG(status);
                if (sigonly) {
                        if (st == SIGINT || st == SIGPIPE)
                                goto out;
+#if JOBS
                        if (WIFSTOPPED(status))
                                goto out;
+#endif
                }
                st &= 0x7f;
-               col = fmtstr(s, 32, u_signal_names(NULL, &st, 0));
+               col = fmtstr(s, 32, strsignal(st));
                if (WCOREDUMP(status)) {
                        col += fmtstr(s + col, 16, " (core dumped)");
                }
        } else if (!sigonly) {
+               st = WEXITSTATUS(status);
                if (st)
                        col = fmtstr(s, 16, "Done(%d)", st);
                else
@@ -9050,18 +9039,19 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt
        char c = '?';
        int done = 0;
        int err = 0;
-       char s[10];
-       char **optnext = optfirst + *param_optind - 1;
+       char s[12];
+       char **optnext;
+
+       if(*param_optind < 1)
+               return 1;
+       optnext = optfirst + *param_optind - 1;
 
-       if (*param_optind <= 1 || *optoff < 0 || !(*(optnext - 1)) ||
-           strlen(*(optnext - 1)) < *optoff)
+       if (*param_optind <= 1 || *optoff < 0 || strlen(optnext[-1]) < *optoff)
                p = NULL;
        else
-               p = *(optnext - 1) + *optoff;
+               p = optnext[-1] + *optoff;
        if (p == NULL || *p == '\0') {
                /* Current word is done, advance */
-               if (optnext == NULL)
-                       return 1;
                p = *optnext;
                if (p == NULL || *p != '-' || *++p == '\0') {
 atend:
@@ -9208,9 +9198,8 @@ nextopt(const char *optstring)
        return c;
 }
 
-/*      $NetBSD: output.c,v 1.27 2002/11/24 22:35:42 christos Exp $     */
-
 
+/*      $NetBSD: output.c,v 1.27 2002/11/24 22:35:42 christos Exp $     */
 
 void
 outstr(const char *p, FILE *file)
@@ -9229,7 +9218,6 @@ flushall(void)
        INTON;
 }
 
-
 void
 flushout(FILE *dest)
 {
@@ -11119,6 +11107,8 @@ redirect(union node *redir, int flags)
                dupredirect(n, newfd);
        } while ((n = n->nfile.next));
        INTON;
+       if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0)
+               preverrout_fd = sv->renamed[2];
 }
 
 
@@ -12544,7 +12534,6 @@ readcmd(int argc, char **argv)
        }
        if (prompt && isatty(0)) {
                out2str(prompt);
-               flushall();
        }
        if (*(ap = argptr) == NULL)
                error("arg count");