diff options
| author | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-05 13:25:11 +0000 |
|---|---|---|
| committer | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-09-05 13:25:11 +0000 |
| commit | bef14d7a878049a01f1fb9b412611a2d64c2b154 (patch) | |
| tree | 064bf486a768a14ca0f9d583e1e6d0608c9c8b32 /shell | |
| parent | 10a1fe6169cc0c1868715f5baf752b818cdfdc1c (diff) | |
| download | busybox-w32-bef14d7a878049a01f1fb9b412611a2d64c2b154.tar.gz busybox-w32-bef14d7a878049a01f1fb9b412611a2d64c2b154.tar.bz2 busybox-w32-bef14d7a878049a01f1fb9b412611a2d64c2b154.zip | |
1) sync with dash_0.5.2-7
2) but expand PS# as config option
3) correct kill error message again
4) remove show "line number" for interactive run (patch pending for dash)
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/Config.in | 9 | ||||
| -rw-r--r-- | shell/ash.c | 153 |
2 files changed, 103 insertions, 59 deletions
diff --git a/shell/Config.in b/shell/Config.in index 813044e2c..f9fb8488f 100644 --- a/shell/Config.in +++ b/shell/Config.in | |||
| @@ -143,6 +143,15 @@ config CONFIG_ASH_RANDOM_SUPPORT | |||
| 143 | After "unset RANDOM" then generator will switch off and this | 143 | After "unset RANDOM" then generator will switch off and this |
| 144 | variable will no longer have special treatment. | 144 | variable will no longer have special treatment. |
| 145 | 145 | ||
| 146 | config CONFIG_ASH_EXPAND_PRMT | ||
| 147 | bool " Support expand PS#" | ||
| 148 | default n | ||
| 149 | depends on CONFIG_ASH | ||
| 150 | help | ||
| 151 | "PS#" may be have commands. It option enable expand string | ||
| 152 | from prompt before each show. | ||
| 153 | |||
| 154 | |||
| 146 | config CONFIG_HUSH | 155 | config CONFIG_HUSH |
| 147 | bool "hush" | 156 | bool "hush" |
| 148 | default n | 157 | default n |
diff --git a/shell/ash.c b/shell/ash.c index 5f859a1fb..5f6f7c6d3 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -276,16 +276,6 @@ static void forceinton(void) | |||
| 276 | }) | 276 | }) |
| 277 | #endif /* CONFIG_ASH_OPTIMIZE_FOR_SIZE */ | 277 | #endif /* CONFIG_ASH_OPTIMIZE_FOR_SIZE */ |
| 278 | 278 | ||
| 279 | /* | ||
| 280 | * BSD setjmp saves the signal mask, which violates ANSI C and takes time, | ||
| 281 | * so we use _setjmp instead. | ||
| 282 | */ | ||
| 283 | |||
| 284 | #if defined(BSD) && !defined(__SVR4) && !defined(__GLIBC__) | ||
| 285 | #define setjmp(jmploc) _setjmp(jmploc) | ||
| 286 | #define longjmp(jmploc, val) _longjmp(jmploc, val) | ||
| 287 | #endif | ||
| 288 | |||
| 289 | /* $NetBSD: expand.h,v 1.13 2002/11/24 22:35:40 christos Exp $ */ | 279 | /* $NetBSD: expand.h,v 1.13 2002/11/24 22:35:40 christos Exp $ */ |
| 290 | 280 | ||
| 291 | struct strlist { | 281 | struct strlist { |
| @@ -1700,9 +1690,11 @@ init(void) | |||
| 1700 | { | 1690 | { |
| 1701 | char **envp; | 1691 | char **envp; |
| 1702 | char ppid[32]; | 1692 | char ppid[32]; |
| 1693 | const char *p; | ||
| 1694 | struct stat st1, st2; | ||
| 1703 | 1695 | ||
| 1704 | initvar(); | 1696 | initvar(); |
| 1705 | for (envp = environ ; *envp ; envp++) { | 1697 | for (envp = environ ; envp && *envp ; envp++) { |
| 1706 | if (strchr(*envp, '=')) { | 1698 | if (strchr(*envp, '=')) { |
| 1707 | setvareq(*envp, VEXPORT|VTEXTFIXED); | 1699 | setvareq(*envp, VEXPORT|VTEXTFIXED); |
| 1708 | } | 1700 | } |
| @@ -1710,7 +1702,13 @@ init(void) | |||
| 1710 | 1702 | ||
| 1711 | snprintf(ppid, sizeof(ppid), "%d", (int) getppid()); | 1703 | snprintf(ppid, sizeof(ppid), "%d", (int) getppid()); |
| 1712 | setvar("PPID", ppid, 0); | 1704 | setvar("PPID", ppid, 0); |
| 1713 | setpwd(0, 0); | 1705 | |
| 1706 | p = lookupvar("PWD"); | ||
| 1707 | if (p) | ||
| 1708 | if (*p != '/' || stat(p, &st1) || stat(".", &st2) || | ||
| 1709 | st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) | ||
| 1710 | p = 0; | ||
| 1711 | setpwd(p, 0); | ||
| 1714 | } | 1712 | } |
| 1715 | } | 1713 | } |
| 1716 | 1714 | ||
| @@ -2300,9 +2298,7 @@ cdcmd(int argc, char **argv) | |||
| 2300 | dest = bltinlookup(homestr); | 2298 | dest = bltinlookup(homestr); |
| 2301 | else if (dest[0] == '-' && dest[1] == '\0') { | 2299 | else if (dest[0] == '-' && dest[1] == '\0') { |
| 2302 | dest = bltinlookup("OLDPWD"); | 2300 | dest = bltinlookup("OLDPWD"); |
| 2303 | if ( !dest ) goto out; | ||
| 2304 | flags |= CD_PRINT; | 2301 | flags |= CD_PRINT; |
| 2305 | goto step7; | ||
| 2306 | } | 2302 | } |
| 2307 | if (!dest) | 2303 | if (!dest) |
| 2308 | dest = nullstr; | 2304 | dest = nullstr; |
| @@ -2563,20 +2559,17 @@ onint(void) { | |||
| 2563 | static void | 2559 | static void |
| 2564 | exvwarning(const char *msg, va_list ap) | 2560 | exvwarning(const char *msg, va_list ap) |
| 2565 | { | 2561 | { |
| 2566 | FILE *errs; | 2562 | FILE *errs; |
| 2567 | const char *name; | ||
| 2568 | const char *fmt; | ||
| 2569 | 2563 | ||
| 2570 | errs = stderr; | 2564 | errs = stderr; |
| 2571 | name = arg0; | 2565 | fprintf(errs, "%s: ", arg0); |
| 2572 | fmt = "%s: "; | 2566 | if (commandname) { |
| 2573 | if (commandname) { | 2567 | const char *fmt = (!iflag || parsefile->fd) ? |
| 2574 | name = commandname; | 2568 | "%s: %d: " : "%s: "; |
| 2575 | fmt = "%s: %d: "; | 2569 | fprintf(errs, fmt, commandname, startlinno); |
| 2576 | } | 2570 | } |
| 2577 | fprintf(errs, fmt, name, startlinno); | 2571 | vfprintf(errs, msg, ap); |
| 2578 | vfprintf(errs, msg, ap); | 2572 | outcslow('\n', errs); |
| 2579 | outcslow('\n', errs); | ||
| 2580 | } | 2573 | } |
| 2581 | 2574 | ||
| 2582 | /* | 2575 | /* |
| @@ -3201,6 +3194,12 @@ isassignment(const char *p) | |||
| 3201 | return *q == '='; | 3194 | return *q == '='; |
| 3202 | } | 3195 | } |
| 3203 | 3196 | ||
| 3197 | #ifdef CONFIG_ASH_EXPAND_PRMT | ||
| 3198 | static const char *expandstr(const char *ps); | ||
| 3199 | #else | ||
| 3200 | #define expandstr(s) s | ||
| 3201 | #endif | ||
| 3202 | |||
| 3204 | /* | 3203 | /* |
| 3205 | * Execute a simple command. | 3204 | * Execute a simple command. |
| 3206 | */ | 3205 | */ |
| @@ -3249,7 +3248,7 @@ evalcommand(union node *cmd, int flags) | |||
| 3249 | struct strlist **spp; | 3248 | struct strlist **spp; |
| 3250 | 3249 | ||
| 3251 | spp = arglist.lastp; | 3250 | spp = arglist.lastp; |
| 3252 | if (pseudovarflag && isassignment(argp->narg.text)) | 3251 | if (pseudovarflag && isassignment(argp->narg.text)) |
| 3253 | expandarg(argp, &arglist, EXP_VARTILDE); | 3252 | expandarg(argp, &arglist, EXP_VARTILDE); |
| 3254 | else | 3253 | else |
| 3255 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); | 3254 | expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); |
| @@ -3296,7 +3295,7 @@ evalcommand(union node *cmd, int flags) | |||
| 3296 | const char *p = " %s"; | 3295 | const char *p = " %s"; |
| 3297 | 3296 | ||
| 3298 | p++; | 3297 | p++; |
| 3299 | dprintf(preverrout_fd, p, ps4val()); | 3298 | dprintf(preverrout_fd, p, expandstr(ps4val())); |
| 3300 | 3299 | ||
| 3301 | sp = varlist.list; | 3300 | sp = varlist.list; |
| 3302 | for(n = 0; n < 2; n++) { | 3301 | for(n = 0; n < 2; n++) { |
| @@ -4595,11 +4594,12 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |||
| 4595 | ifsfirst.next = NULL; | 4594 | ifsfirst.next = NULL; |
| 4596 | ifslastp = NULL; | 4595 | ifslastp = NULL; |
| 4597 | argstr(arg->narg.text, flag); | 4596 | argstr(arg->narg.text, flag); |
| 4597 | p = _STPUTC('\0', expdest); | ||
| 4598 | expdest = p - 1; | ||
| 4598 | if (arglist == NULL) { | 4599 | if (arglist == NULL) { |
| 4599 | return; /* here document expanded */ | 4600 | return; /* here document expanded */ |
| 4600 | } | 4601 | } |
| 4601 | STPUTC('\0', expdest); | 4602 | p = grabstackstr(p); |
| 4602 | p = grabstackstr(expdest); | ||
| 4603 | exparg.lastp = &exparg.list; | 4603 | exparg.lastp = &exparg.list; |
| 4604 | /* | 4604 | /* |
| 4605 | * TODO - EXP_REDIR | 4605 | * TODO - EXP_REDIR |
| @@ -5355,9 +5355,12 @@ param: | |||
| 5355 | size_t partlen; | 5355 | size_t partlen; |
| 5356 | 5356 | ||
| 5357 | partlen = strlen(p); | 5357 | partlen = strlen(p); |
| 5358 | |||
| 5359 | len += partlen; | 5358 | len += partlen; |
| 5360 | if (len > partlen && sep) { | 5359 | |
| 5360 | if (!(subtype == VSPLUS || subtype == VSLENGTH)) | ||
| 5361 | memtodest(p, partlen, syntax, quotes); | ||
| 5362 | |||
| 5363 | if (*ap && sep) { | ||
| 5361 | char *q; | 5364 | char *q; |
| 5362 | 5365 | ||
| 5363 | len++; | 5366 | len++; |
| @@ -5370,9 +5373,6 @@ param: | |||
| 5370 | STPUTC(sep, q); | 5373 | STPUTC(sep, q); |
| 5371 | expdest = q; | 5374 | expdest = q; |
| 5372 | } | 5375 | } |
| 5373 | |||
| 5374 | if (!(subtype == VSPLUS || subtype == VSLENGTH)) | ||
| 5375 | memtodest(p, partlen, syntax, quotes); | ||
| 5376 | } | 5376 | } |
| 5377 | return len; | 5377 | return len; |
| 5378 | case '0': | 5378 | case '0': |
| @@ -6603,10 +6603,12 @@ usage: | |||
| 6603 | if (**argv == '%') { | 6603 | if (**argv == '%') { |
| 6604 | jp = getjob(*argv, 0); | 6604 | jp = getjob(*argv, 0); |
| 6605 | pid = -jp->ps[0].pid; | 6605 | pid = -jp->ps[0].pid; |
| 6606 | } else | 6606 | } else { |
| 6607 | pid = number(*argv); | 6607 | pid = **argv == '-' ? |
| 6608 | -number(*argv + 1) : number(*argv); | ||
| 6609 | } | ||
| 6608 | if (kill(pid, signo) != 0) { | 6610 | if (kill(pid, signo) != 0) { |
| 6609 | sh_warnx("kill %d: %s", pid, errmsg(errno, NULL)); | 6611 | sh_warnx("(%d) - %m", pid); |
| 6610 | i = 1; | 6612 | i = 1; |
| 6611 | } | 6613 | } |
| 6612 | } while (*++argv); | 6614 | } while (*++argv); |
| @@ -7621,11 +7623,10 @@ cmdputs(const char *s) | |||
| 7621 | char *nextc; | 7623 | char *nextc; |
| 7622 | int subtype = 0; | 7624 | int subtype = 0; |
| 7623 | int quoted = 0; | 7625 | int quoted = 0; |
| 7624 | static const char *const vstype[16] = { | 7626 | static const char vstype[VSTYPE + 1][4] = { |
| 7625 | nullstr, "}", "-", "+", "?", "=", | 7627 | "", "}", "-", "+", "?", "=", |
| 7626 | "%", "%%", "#", "##", nullstr | 7628 | "%", "%%", "#", "##" |
| 7627 | }; | 7629 | }; |
| 7628 | |||
| 7629 | nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc); | 7630 | nextc = makestrspace((strlen(s) + 1) * 8, cmdnextc); |
| 7630 | p = s; | 7631 | p = s; |
| 7631 | while ((c = *p++) != 0) { | 7632 | while ((c = *p++) != 0) { |
| @@ -7647,14 +7648,10 @@ cmdputs(const char *s) | |||
| 7647 | goto dostr; | 7648 | goto dostr; |
| 7648 | break; | 7649 | break; |
| 7649 | case CTLENDVAR: | 7650 | case CTLENDVAR: |
| 7651 | str = "\"}" + !(quoted & 1); | ||
| 7650 | quoted >>= 1; | 7652 | quoted >>= 1; |
| 7651 | subtype = 0; | 7653 | subtype = 0; |
| 7652 | if (quoted & 1) { | 7654 | goto dostr; |
| 7653 | str = "\"}"; | ||
| 7654 | goto dostr; | ||
| 7655 | } | ||
| 7656 | c = '}'; | ||
| 7657 | break; | ||
| 7658 | case CTLBACKQ: | 7655 | case CTLBACKQ: |
| 7659 | str = "$(...)"; | 7656 | str = "$(...)"; |
| 7660 | goto dostr; | 7657 | goto dostr; |
| @@ -7676,13 +7673,13 @@ cmdputs(const char *s) | |||
| 7676 | case '=': | 7673 | case '=': |
| 7677 | if (subtype == 0) | 7674 | if (subtype == 0) |
| 7678 | break; | 7675 | break; |
| 7676 | if ((subtype & VSTYPE) != VSNORMAL) | ||
| 7677 | quoted <<= 1; | ||
| 7679 | str = vstype[subtype & VSTYPE]; | 7678 | str = vstype[subtype & VSTYPE]; |
| 7680 | if (subtype & VSNUL) | 7679 | if (subtype & VSNUL) |
| 7681 | c = ':'; | 7680 | c = ':'; |
| 7682 | else | 7681 | else |
| 7683 | c = *str++; | 7682 | goto checkstr; |
| 7684 | if (c != '}') | ||
| 7685 | quoted <<= 1; | ||
| 7686 | break; | 7683 | break; |
| 7687 | case '\'': | 7684 | case '\'': |
| 7688 | case '\\': | 7685 | case '\\': |
| @@ -7697,6 +7694,7 @@ cmdputs(const char *s) | |||
| 7697 | break; | 7694 | break; |
| 7698 | } | 7695 | } |
| 7699 | USTPUTC(c, nextc); | 7696 | USTPUTC(c, nextc); |
| 7697 | checkstr: | ||
| 7700 | if (!str) | 7698 | if (!str) |
| 7701 | continue; | 7699 | continue; |
| 7702 | dostr: | 7700 | dostr: |
| @@ -8138,7 +8136,7 @@ static int dotcmd(int argc, char **argv) | |||
| 8138 | for (sp = cmdenviron; sp; sp = sp->next) | 8136 | for (sp = cmdenviron; sp; sp = sp->next) |
| 8139 | setvareq(bb_xstrdup(sp->text), VSTRFIXED | VTEXTFIXED); | 8137 | setvareq(bb_xstrdup(sp->text), VSTRFIXED | VTEXTFIXED); |
| 8140 | 8138 | ||
| 8141 | if (argc >= 2) { /* That's what SVR2 does */ | 8139 | if (argc >= 2) { /* That's what SVR2 does */ |
| 8142 | char *fullname; | 8140 | char *fullname; |
| 8143 | struct stackmark smark; | 8141 | struct stackmark smark; |
| 8144 | 8142 | ||
| @@ -9892,7 +9890,6 @@ parseheredoc(void) | |||
| 9892 | while (here) { | 9890 | while (here) { |
| 9893 | if (needprompt) { | 9891 | if (needprompt) { |
| 9894 | setprompt(2); | 9892 | setprompt(2); |
| 9895 | needprompt = 0; | ||
| 9896 | } | 9893 | } |
| 9897 | readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, | 9894 | readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, |
| 9898 | here->eofmark, here->striptabs); | 9895 | here->eofmark, here->striptabs); |
| @@ -10025,7 +10022,6 @@ static int xxreadtoken() | |||
| 10025 | } | 10022 | } |
| 10026 | if (needprompt) { | 10023 | if (needprompt) { |
| 10027 | setprompt(2); | 10024 | setprompt(2); |
| 10028 | needprompt = 0; | ||
| 10029 | } | 10025 | } |
| 10030 | startlinno = plinno; | 10026 | startlinno = plinno; |
| 10031 | for (;;) { /* until token or start of word found */ | 10027 | for (;;) { /* until token or start of word found */ |
| @@ -10093,7 +10089,6 @@ xxreadtoken(void) | |||
| 10093 | } | 10089 | } |
| 10094 | if (needprompt) { | 10090 | if (needprompt) { |
| 10095 | setprompt(2); | 10091 | setprompt(2); |
| 10096 | needprompt = 0; | ||
| 10097 | } | 10092 | } |
| 10098 | startlinno = plinno; | 10093 | startlinno = plinno; |
| 10099 | for (;;) { /* until token or start of word found */ | 10094 | for (;;) { /* until token or start of word found */ |
| @@ -10649,7 +10644,6 @@ parsebackq: { | |||
| 10649 | for (;;) { | 10644 | for (;;) { |
| 10650 | if (needprompt) { | 10645 | if (needprompt) { |
| 10651 | setprompt(2); | 10646 | setprompt(2); |
| 10652 | needprompt = 0; | ||
| 10653 | } | 10647 | } |
| 10654 | switch (pc = pgetc()) { | 10648 | switch (pc = pgetc()) { |
| 10655 | case '`': | 10649 | case '`': |
| @@ -10859,9 +10853,35 @@ synerror(const char *msg) | |||
| 10859 | * should be added here. | 10853 | * should be added here. |
| 10860 | */ | 10854 | */ |
| 10861 | 10855 | ||
| 10856 | #ifdef CONFIG_ASH_EXPAND_PRMT | ||
| 10857 | static const char * | ||
| 10858 | expandstr(const char *ps) | ||
| 10859 | { | ||
| 10860 | union node n; | ||
| 10861 | |||
| 10862 | /* XXX Fix (char *) cast. */ | ||
| 10863 | setinputstring((char *)ps); | ||
| 10864 | readtoken1(pgetc(), DQSYNTAX, nullstr, 0); | ||
| 10865 | popfile(); | ||
| 10866 | |||
| 10867 | n.narg.type = NARG; | ||
| 10868 | n.narg.next = NULL; | ||
| 10869 | n.narg.text = wordtext; | ||
| 10870 | n.narg.backquote = backquotelist; | ||
| 10871 | |||
| 10872 | expandarg(&n, NULL, 0); | ||
| 10873 | return stackblock(); | ||
| 10874 | } | ||
| 10875 | #endif | ||
| 10876 | |||
| 10862 | static void setprompt(int whichprompt) | 10877 | static void setprompt(int whichprompt) |
| 10863 | { | 10878 | { |
| 10864 | const char *prompt; | 10879 | const char *prompt; |
| 10880 | #ifdef CONFIG_ASH_EXPAND_PRMT | ||
| 10881 | struct stackmark smark; | ||
| 10882 | #endif | ||
| 10883 | |||
| 10884 | needprompt = 0; | ||
| 10865 | 10885 | ||
| 10866 | switch (whichprompt) { | 10886 | switch (whichprompt) { |
| 10867 | case 1: | 10887 | case 1: |
| @@ -10873,7 +10893,14 @@ static void setprompt(int whichprompt) | |||
| 10873 | default: /* 0 */ | 10893 | default: /* 0 */ |
| 10874 | prompt = nullstr; | 10894 | prompt = nullstr; |
| 10875 | } | 10895 | } |
| 10876 | putprompt(prompt); | 10896 | #ifdef CONFIG_ASH_EXPAND_PRMT |
| 10897 | setstackmark(&smark); | ||
| 10898 | stalloc(stackblocksize()); | ||
| 10899 | #endif | ||
| 10900 | putprompt(expandstr(prompt)); | ||
| 10901 | #ifdef CONFIG_ASH_EXPAND_PRMT | ||
| 10902 | popstackmark(&smark); | ||
| 10903 | #endif | ||
| 10877 | } | 10904 | } |
| 10878 | 10905 | ||
| 10879 | 10906 | ||
| @@ -13341,7 +13368,11 @@ arith_apply(operator op, v_n_t *numstack, v_n_t **numstackptr) | |||
| 13341 | goto err; | 13368 | goto err; |
| 13342 | } | 13369 | } |
| 13343 | /* save to shell variable */ | 13370 | /* save to shell variable */ |
| 13344 | snprintf(buf, sizeof(buf), "%lld", (long long) rez); | 13371 | #ifdef CONFIG_ASH_MATH_SUPPORT_64 |
| 13372 | snprintf(buf, sizeof(buf), "%lld", rez); | ||
| 13373 | #else | ||
| 13374 | snprintf(buf, sizeof(buf), "%ld", rez); | ||
| 13375 | #endif | ||
| 13345 | setvar(numptr_m1->var, buf, 0); | 13376 | setvar(numptr_m1->var, buf, 0); |
| 13346 | /* after saving, make previous value for v++ or v-- */ | 13377 | /* after saving, make previous value for v++ or v-- */ |
| 13347 | if(op == TOK_POST_INC) | 13378 | if(op == TOK_POST_INC) |
| @@ -13479,7 +13510,11 @@ static arith_t arith (const char *expr, int *perrcode) | |||
| 13479 | continue; | 13510 | continue; |
| 13480 | } else if (is_digit(arithval)) { | 13511 | } else if (is_digit(arithval)) { |
| 13481 | numstackptr->var = NULL; | 13512 | numstackptr->var = NULL; |
| 13513 | #ifdef CONFIG_ASH_MATH_SUPPORT_64 | ||
| 13482 | numstackptr->val = strtoll(expr, (char **) &expr, 0); | 13514 | numstackptr->val = strtoll(expr, (char **) &expr, 0); |
| 13515 | #else | ||
| 13516 | numstackptr->val = strtol(expr, (char **) &expr, 0); | ||
| 13517 | #endif | ||
| 13483 | goto num; | 13518 | goto num; |
| 13484 | } | 13519 | } |
| 13485 | for(p = op_tokens; ; p++) { | 13520 | for(p = op_tokens; ; p++) { |
