X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=shell%2Fmsh.c;h=dffacf02adac12befb6f19d093b60b185f532ce5;hb=e19e1935a33b117e2ee6daf9b2d79c00603333c7;hp=63f365962e293ed744a97a57fd2923da46b5c4d0;hpb=68404f13d4bf4826e3609703dad5375763db28ab;p=oweals%2Fbusybox.git diff --git a/shell/msh.c b/shell/msh.c index 63f365962..dffacf02a 100644 --- a/shell/msh.c +++ b/shell/msh.c @@ -12,7 +12,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ - #include #include @@ -35,7 +34,6 @@ # include # define bb_dev_null "/dev/null" # define DEFAULT_SHELL "/proc/self/exe" -# define CONFIG_BUSYBOX_EXEC_PATH "/proc/self/exe" # define bb_banner "busybox standalone" # define ENABLE_FEATURE_SH_STANDALONE 0 # define bb_msg_memory_exhausted "memory exhausted" @@ -45,7 +43,7 @@ # define nonblock_safe_read(fd,buf,count) read(fd,buf,count) # define NOT_LONE_DASH(s) ((s)[0] != '-' || (s)[1]) # define LONE_CHAR(s,c) ((s)[0] == (c) && !(s)[1]) -# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) +# define NORETURN __attribute__ ((__noreturn__)) static int find_applet_by_name(const char *applet) { return -1; @@ -92,17 +90,17 @@ static char *itoa(int n) #ifdef MSHDEBUG static int mshdbg = MSHDEBUG; -#define DBGPRINTF(x) if (mshdbg>0) printf x -#define DBGPRINTF0(x) if (mshdbg>0) printf x -#define DBGPRINTF1(x) if (mshdbg>1) printf x -#define DBGPRINTF2(x) if (mshdbg>2) printf x -#define DBGPRINTF3(x) if (mshdbg>3) printf x -#define DBGPRINTF4(x) if (mshdbg>4) printf x -#define DBGPRINTF5(x) if (mshdbg>5) printf x -#define DBGPRINTF6(x) if (mshdbg>6) printf x -#define DBGPRINTF7(x) if (mshdbg>7) printf x -#define DBGPRINTF8(x) if (mshdbg>8) printf x -#define DBGPRINTF9(x) if (mshdbg>9) printf x +#define DBGPRINTF(x) if (mshdbg > 0) printf x +#define DBGPRINTF0(x) if (mshdbg > 0) printf x +#define DBGPRINTF1(x) if (mshdbg > 1) printf x +#define DBGPRINTF2(x) if (mshdbg > 2) printf x +#define DBGPRINTF3(x) if (mshdbg > 3) printf x +#define DBGPRINTF4(x) if (mshdbg > 4) printf x +#define DBGPRINTF5(x) if (mshdbg > 5) printf x +#define DBGPRINTF6(x) if (mshdbg > 6) printf x +#define DBGPRINTF7(x) if (mshdbg > 7) printf x +#define DBGPRINTF8(x) if (mshdbg > 8) printf x +#define DBGPRINTF9(x) if (mshdbg > 9) printf x static int mshdbg_rc = 0; @@ -124,7 +122,7 @@ static int mshdbg_rc = 0; #define RCPRINTF(x) ((void)0) -#endif /* MSHDEBUG */ +#endif /* MSHDEBUG */ #if ENABLE_FEATURE_EDITING_FANCY_PROMPT @@ -141,13 +139,13 @@ static int mshdbg_rc = 0; * shell */ -#define LINELIM 2100 -#define NPUSH 8 /* limit to input nesting */ +#define LINELIM 2100 +#define NPUSH 8 /* limit to input nesting */ #undef NOFILE -#define NOFILE 20 /* Number of open files */ -#define NUFILE 10 /* Number of user-accessible files */ -#define FDBASE 10 /* First file usable by Shell */ +#define NOFILE 20 /* Number of open files */ +#define NUFILE 10 /* Number of user-accessible files */ +#define FDBASE 10 /* First file usable by Shell */ /* * values returned by wait @@ -159,7 +157,7 @@ static int mshdbg_rc = 0; /* * library and system definitions */ -typedef void xint; /* base type of jmp_buf, for not broken compilers */ +typedef void xint; /* base type of jmp_buf, for not broken compilers */ /* * shell components @@ -588,14 +586,13 @@ static const struct builtincmd builtincmds[] = { { NULL , NULL }, }; -static struct op *scantree(struct op *); static struct op *dowholefile(int /*, int*/); /* Globals */ static char **dolv; static int dolc; -static int exstat; +static uint8_t exstat; static smallint gflg; /* (seems to be a parse error indicator) */ static smallint interactive; /* Is this an interactive shell */ static smallint execflg; @@ -726,7 +723,7 @@ static void print_tree(struct op *head) return; } - DBGPRINTF(("NODE: %p, left %p, right %p\n", head, head->left, + DBGPRINTF(("NODE: %p, left %p, right %p\n", head, head->left, head->right)); if (head->left) @@ -744,7 +741,7 @@ static void print_tree(struct op *head) static void prs(const char *s) { if (*s) - write(2, s, strlen(s)); + xwrite_str(STDERR_FILENO, s); } static void prn(unsigned u) @@ -781,7 +778,7 @@ static void closeall(void) /* fail but return to process next command */ -static void fail(void) ATTRIBUTE_NORETURN; +static void fail(void) NORETURN; static void fail(void) { longjmp(failpt, 1); @@ -789,7 +786,7 @@ static void fail(void) } /* abort shell (or fail in subshell) */ -static void leave(void) ATTRIBUTE_NORETURN; +static void leave(void) NORETURN; static void leave(void) { DBGPRINTF(("LEAVE: leave called!\n")); @@ -807,7 +804,8 @@ static void warn(const char *s) { if (*s) { prs(s); - exstat = -1; + if (!exstat) + exstat = 255; } prs("\n"); if (FLAG['e']) @@ -1268,7 +1266,7 @@ static int newfile(char *s) f = open(s, O_RDONLY); if (f < 0) { prs(s); - err(": cannot open"); + err(": can't open"); return 1; } } @@ -1278,6 +1276,7 @@ static int newfile(char *s) } +#ifdef UNUSED struct op *scantree(struct op *head) { struct op *dotnode; @@ -1309,6 +1308,7 @@ struct op *scantree(struct op *head) return NULL; } +#endif static void onecommand(void) @@ -1448,7 +1448,7 @@ static void next(int f) PUSHIO(afile, f, filechar); } -static void onintr(int s ATTRIBUTE_UNUSED) /* ANSI C requires a parameter */ +static void onintr(int s UNUSED_PARAM) /* ANSI C requires a parameter */ { signal(SIGINT, onintr); intr = 1; @@ -1543,7 +1543,7 @@ static int gmatch(const char *s, const char *p) * shell: syntax (C version) */ -static void yyerror(const char *s) ATTRIBUTE_NORETURN; +static void yyerror(const char *s) NORETURN; static void yyerror(const char *s) { yynerrs = 1; @@ -1556,7 +1556,7 @@ static void yyerror(const char *s) fail(); } -static void zzerr(void) ATTRIBUTE_NORETURN; +static void zzerr(void) NORETURN; static void zzerr(void) { yyerror("syntax error"); @@ -2571,6 +2571,10 @@ static int execute(struct op *t, int *pin, int *pout, int no_fork) while (setjmp(bc.brkpt)) if (isbreak) goto broken; + /* Restore areanum value. It may be incremented by execute() + * below, and then "continue" may jump back to setjmp above */ + areanum = a + 1; + freearea(areanum + 1); brkset(&bc); for (t1 = t->left; i-- && *wp != NULL;) { setval(vp, *wp++); @@ -2584,6 +2588,10 @@ static int execute(struct op *t, int *pin, int *pout, int no_fork) while (setjmp(bc.brkpt)) if (isbreak) goto broken; + /* Restore areanum value. It may be incremented by execute() + * below, and then "continue" may jump back to setjmp above */ + areanum = a + 1; + freearea(areanum + 1); brkset(&bc); t1 = t->left; while ((execute(t1, pin, pout, /* no_fork: */ 0) == 0) == (t->op_type == TWHILE)) @@ -2740,7 +2748,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp) // longjmps away (at "Run builtin" below), leaving t->op_words clobbered! // See http://bugs.busybox.net/view.php?id=846. // Now we do not touch t->op_words, but separately pass wp as param list - // to builtins + // to builtins DBGPRINTF(("FORKEXEC: bltin %p, no_fork %d, owp %p\n", bltin, no_fork, owp)); /* Don't fork if it is a lone builtin (not in pipe) @@ -2760,7 +2768,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp) DBGPRINTF3(("FORKEXEC: calling vfork()...\n")); newpid = vfork(); if (newpid == -1) { - DBGPRINTF(("FORKEXEC: ERROR, cannot vfork()!\n")); + DBGPRINTF(("FORKEXEC: ERROR, can't vfork()!\n")); return -1; } @@ -2810,7 +2818,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp) if (iopp) { if (bltin && bltin != doexec) { prs(bltin_name); - err(": cannot redirect shell command"); + err(": can't redirect shell command"); if (forked) _exit(-1); return -1; @@ -2830,7 +2838,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp) /* Builtin in pipe: disallowed */ /* TODO: allow "exec"? */ prs(bltin_name); - err(": cannot run builtin as part of pipe"); + err(": can't run builtin as part of pipe"); if (forked) _exit(-1); return -1; @@ -2854,7 +2862,7 @@ static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp) if (t->op_type == TPAREN) _exit(execute(t->left, NOPIPE, NOPIPE, /* no_fork: */ 1)); if (wp[0] == NULL) - _exit(0); + _exit(EXIT_SUCCESS); cp = rexecve(wp[0], wp, makenv(0, NULL)); prs(wp[0]); @@ -2945,7 +2953,7 @@ static int iosetup(struct ioword *iop, int pipein, int pipeout) if (u < 0) { prs(cp); - prs(": cannot "); + prs(": can't "); warn(msg); return 1; } @@ -3006,7 +3014,7 @@ static int waitfor(int lastpid, int canintr) prs(" - core dumped"); if (rv >= ARRAY_SIZE(signame) || signame[rv]) prs("\n"); - rv = -1; + rv |= 0x80; } else rv = WAITVAL(s); } @@ -3070,8 +3078,6 @@ static const char *rexecve(char *c, char **v, char **envp) if (tp != global_env.linep) *tp++ = '/'; strcpy(tp, c); - //for (i = 0; (*tp++ = c[i++]) != '\0';) - // continue; DBGPRINTF3(("REXECVE: global_env.linep is %s\n", global_env.linep)); @@ -3079,10 +3085,13 @@ static const char *rexecve(char *c, char **v, char **envp) switch (errno) { case ENOEXEC: + /* File is executable but file format isnt recognized */ + /* Run it as a shell script */ + /* (execve above didnt do it itself, unlike execvp) */ *v = global_env.linep; v--; tp = *v; - *v = global_env.linep; + *v = (char*)DEFAULT_SHELL; execve(DEFAULT_SHELL, v, envp); *v = tp; return "no shell"; @@ -3094,7 +3103,12 @@ static const char *rexecve(char *c, char **v, char **envp) return "argument list too long"; } } - return errno == ENOENT ? "not found" : "cannot execute"; + if (errno == ENOENT) { + exstat = 127; /* standards require this */ + return "not found"; + } + exstat = 126; /* mimic bash */ + return "can't execute"; } /* @@ -3155,13 +3169,14 @@ static int run(struct ioarg *argp, int (*f) (struct ioarg *)) * built-in commands: doX */ -static int dohelp(struct op *t ATTRIBUTE_UNUSED, char **args ATTRIBUTE_UNUSED) +static int dohelp(struct op *t UNUSED_PARAM, char **args UNUSED_PARAM) { int col; const struct builtincmd *x; - puts("\nBuilt-in commands:\n" - "-------------------"); + printf("\n" + "Built-in commands:\n" + "------------------\n"); col = 0; x = builtincmds; @@ -3191,12 +3206,12 @@ static int dohelp(struct op *t ATTRIBUTE_UNUSED, char **args ATTRIBUTE_UNUSED) return EXIT_SUCCESS; } -static int dolabel(struct op *t ATTRIBUTE_UNUSED, char **args ATTRIBUTE_UNUSED) +static int dolabel(struct op *t UNUSED_PARAM, char **args UNUSED_PARAM) { return 0; } -static int dochdir(struct op *t ATTRIBUTE_UNUSED, char **args) +static int dochdir(struct op *t UNUSED_PARAM, char **args) { const char *cp, *er; @@ -3217,7 +3232,7 @@ static int dochdir(struct op *t ATTRIBUTE_UNUSED, char **args) return 1; } -static int doshift(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doshift(struct op *t UNUSED_PARAM, char **args) { int n; @@ -3236,7 +3251,7 @@ static int doshift(struct op *t ATTRIBUTE_UNUSED, char **args) /* * execute login and newgrp directly */ -static int dologin(struct op *t ATTRIBUTE_UNUSED, char **args) +static int dologin(struct op *t UNUSED_PARAM, char **args) { const char *cp; @@ -3251,7 +3266,7 @@ static int dologin(struct op *t ATTRIBUTE_UNUSED, char **args) return 1; } -static int doumask(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doumask(struct op *t UNUSED_PARAM, char **args) { int i; char *cp; @@ -3301,7 +3316,7 @@ static int doexec(struct op *t, char **args) return 1; } -static int dodot(struct op *t ATTRIBUTE_UNUSED, char **args) +static int dodot(struct op *t UNUSED_PARAM, char **args) { int i; const char *sp; @@ -3355,7 +3370,7 @@ static int dodot(struct op *t ATTRIBUTE_UNUSED, char **args) return -1; } -static int dowait(struct op *t ATTRIBUTE_UNUSED, char **args) +static int dowait(struct op *t UNUSED_PARAM, char **args) { int i; char *cp; @@ -3371,7 +3386,7 @@ static int dowait(struct op *t ATTRIBUTE_UNUSED, char **args) return 0; } -static int doread(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doread(struct op *t UNUSED_PARAM, char **args) { char *cp, **wp; int nb = 0; @@ -3383,7 +3398,7 @@ static int doread(struct op *t ATTRIBUTE_UNUSED, char **args) } for (wp = args + 1; *wp; wp++) { for (cp = global_env.linep; !nl && cp < elinep - 1; cp++) { - nb = nonblock_safe_read(0, cp, sizeof(*cp)); + nb = nonblock_safe_read(STDIN_FILENO, cp, sizeof(*cp)); if (nb != sizeof(*cp)) break; nl = (*cp == '\n'); @@ -3398,12 +3413,12 @@ static int doread(struct op *t ATTRIBUTE_UNUSED, char **args) return nb <= 0; } -static int doeval(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doeval(struct op *t UNUSED_PARAM, char **args) { return RUN(awordlist, args + 1, wdchar); } -static int dotrap(struct op *t ATTRIBUTE_UNUSED, char **args) +static int dotrap(struct op *t UNUSED_PARAM, char **args) { int n, i; int resetsig; @@ -3484,12 +3499,12 @@ static int getn(char *as) return n * m; } -static int dobreak(struct op *t ATTRIBUTE_UNUSED, char **args) +static int dobreak(struct op *t UNUSED_PARAM, char **args) { return brkcontin(args[1], 1); } -static int docontinue(struct op *t ATTRIBUTE_UNUSED, char **args) +static int docontinue(struct op *t UNUSED_PARAM, char **args) { return brkcontin(args[1], 0); } @@ -3517,7 +3532,7 @@ static int brkcontin(char *cp, int val) /* NOTREACHED */ } -static int doexit(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doexit(struct op *t UNUSED_PARAM, char **args) { char *cp; @@ -3533,13 +3548,13 @@ static int doexit(struct op *t ATTRIBUTE_UNUSED, char **args) return 0; } -static int doexport(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doexport(struct op *t UNUSED_PARAM, char **args) { rdexp(args + 1, export, EXPORT); return 0; } -static int doreadonly(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doreadonly(struct op *t UNUSED_PARAM, char **args) { rdexp(args + 1, ronly, RONLY); return 0; @@ -3575,7 +3590,7 @@ static void badid(char *s) err(": bad identifier"); } -static int doset(struct op *t ATTRIBUTE_UNUSED, char **args) +static int doset(struct op *t UNUSED_PARAM, char **args) { struct var *vp; char *cp; @@ -3584,7 +3599,7 @@ static int doset(struct op *t ATTRIBUTE_UNUSED, char **args) cp = args[1]; if (cp == NULL) { for (vp = vlist; vp; vp = vp->next) - varput(vp->name, 1); + varput(vp->name, STDOUT_FILENO); return 0; } if (*cp == '-') { @@ -3623,8 +3638,8 @@ static int doset(struct op *t ATTRIBUTE_UNUSED, char **args) static void varput(char *s, int out) { if (isalnum(*s) || *s == '_') { - write(out, s, strlen(s)); - write(out, "\n", 1); + xwrite_str(out, s); + xwrite(out, "\n", 1); } } @@ -3650,7 +3665,7 @@ static void times_fmt(char *buf, clock_t val, unsigned clk_tck) #endif } -static int dotimes(struct op *t ATTRIBUTE_UNUSED, char **args ATTRIBUTE_UNUSED) +static int dotimes(struct op *t UNUSED_PARAM, char **args UNUSED_PARAM) { struct tms buf; unsigned clk_tck = sysconf(_SC_CLK_TCK); @@ -3980,7 +3995,7 @@ static int dollar(int quoted) switch (c) { case '=': if (isdigit(*s)) { - err("cannot use ${...=...} with $n"); + err("can't use ${...=...} with $n"); gflg = 1; break; } @@ -4206,7 +4221,7 @@ static int grave(int quoted) prs(argument_list[0]); prs(": "); err(cp); - _exit(1); + _exit(EXIT_FAILURE); } @@ -4308,9 +4323,7 @@ static void globname(char *we, char *pp) dname[NAME_MAX] = '\0'; while ((de = readdir(dirp)) != NULL) { /* XXX Hmmm... What this could be? (abial) */ - /* - if (ent[j].d_ino == 0) - continue; + /* if (ent[j].d_ino == 0) continue; */ strncpy(dname, de->d_name, NAME_MAX); if (dname[0] == '.') @@ -4521,7 +4534,7 @@ static int readc(void) static void ioecho(char c) { if (FLAG['v']) - write(2, &c, sizeof c); + write(STDERR_FILENO, &c, sizeof c); } static void pushio(struct ioarg *argp, int (*fn) (struct ioarg *)) @@ -4732,7 +4745,7 @@ static int filechar(struct ioarg *ap) while (size == 0 || position >= size) { size = read_line_input(current_prompt, filechar_cmdbuf, BUFSIZ, line_input_state); if (size < 0) /* Error/EOF */ - exit(0); + exit(EXIT_SUCCESS); position = 0; /* if Ctrl-C, size == 0 and loop will repeat */ } @@ -4817,7 +4830,7 @@ static int linechar(struct ioarg *ap) } /* - * remap fd into Shell's fd space + * Remap fd into shell's fd space */ static int remap(int fd) { @@ -5203,7 +5216,7 @@ int msh_main(int argc, char **argv) /* Shell is non-interactive, activate printf-based debug */ #ifdef MSHDEBUG - mshdbg = (int) (((char) (mshdbg_var->value[0])) - '0'); + mshdbg = mshdbg_var->value[0] - '0'; if (mshdbg < 0) mshdbg = 0; #endif @@ -5211,7 +5224,7 @@ int msh_main(int argc, char **argv) name = *++argv; if (newfile(name)) - exit(1); /* Exit on error */ + exit(EXIT_FAILURE); /* Exit on error */ } }