aboutsummaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
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
commitbef14d7a878049a01f1fb9b412611a2d64c2b154 (patch)
tree064bf486a768a14ca0f9d583e1e6d0608c9c8b32 /shell/ash.c
parent10a1fe6169cc0c1868715f5baf752b818cdfdc1c (diff)
downloadbusybox-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/ash.c')
-rw-r--r--shell/ash.c153
1 files changed, 94 insertions, 59 deletions
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
291struct strlist { 281struct 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) {
2563static void 2559static void
2564exvwarning(const char *msg, va_list ap) 2560exvwarning(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
3198static 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);
7697checkstr:
7700 if (!str) 7698 if (!str)
7701 continue; 7699 continue;
7702dostr: 7700dostr:
@@ -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
10857static const char *
10858expandstr(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
10862static void setprompt(int whichprompt) 10877static 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++) {