aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c115
-rw-r--r--shell/ash_test/ash-heredoc/heredoc2.right2
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc2.tests7
-rw-r--r--shell/ash_test/ash-heredoc/heredoc3.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc3.tests9
-rw-r--r--shell/ash_test/ash-misc/command.right1
-rwxr-xr-xshell/ash_test/ash-misc/command.tests1
-rw-r--r--shell/ash_test/ash-misc/command2.right2
-rwxr-xr-xshell/ash_test/ash-misc/command2.tests6
-rw-r--r--shell/ash_test/ash-misc/exec.right2
-rwxr-xr-xshell/ash_test/ash-misc/exec.tests3
-rw-r--r--shell/ash_test/ash-misc/for.right1
-rwxr-xr-xshell/ash_test/ash-misc/for.tests5
-rw-r--r--shell/ash_test/ash-misc/local2.right1
-rwxr-xr-xshell/ash_test/ash-misc/local2.tests1
-rwxr-xr-xshell/ash_test/run-all6
-rw-r--r--shell/hush_test/hush-misc/for.right1
-rwxr-xr-xshell/hush_test/hush-misc/for.tests5
18 files changed, 107 insertions, 62 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 21fc05f01..08b6aa430 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -2747,7 +2747,7 @@ updatepwd(const char *dir)
2747 new = stack_putstr(p, new); 2747 new = stack_putstr(p, new);
2748 USTPUTC('/', new); 2748 USTPUTC('/', new);
2749 } 2749 }
2750 p = strtok(0, "/"); 2750 p = strtok(NULL, "/");
2751 } 2751 }
2752 if (new > lim) 2752 if (new > lim)
2753 STUNPUTC(new); 2753 STUNPUTC(new);
@@ -5731,7 +5731,7 @@ popredir(int drop, int restore)
5731 struct redirtab *rp; 5731 struct redirtab *rp;
5732 int i; 5732 int i;
5733 5733
5734 if (--g_nullredirs >= 0) 5734 if (--g_nullredirs >= 0 || redirlist == NULL)
5735 return; 5735 return;
5736 INT_OFF; 5736 INT_OFF;
5737 rp = redirlist; 5737 rp = redirlist;
@@ -8159,14 +8159,15 @@ findkwd(const char *s)
8159 * Locate and print what a word is... 8159 * Locate and print what a word is...
8160 */ 8160 */
8161static int 8161static int
8162describe_command(char *command, int describe_command_verbose) 8162describe_command(char *command, const char *path, int describe_command_verbose)
8163{ 8163{
8164 struct cmdentry entry; 8164 struct cmdentry entry;
8165 struct tblentry *cmdp; 8165 struct tblentry *cmdp;
8166#if ENABLE_ASH_ALIAS 8166#if ENABLE_ASH_ALIAS
8167 const struct alias *ap; 8167 const struct alias *ap;
8168#endif 8168#endif
8169 const char *path = pathval(); 8169
8170 path = path ? path : pathval();
8170 8171
8171 if (describe_command_verbose) { 8172 if (describe_command_verbose) {
8172 out1str(command); 8173 out1str(command);
@@ -8266,7 +8267,7 @@ typecmd(int argc UNUSED_PARAM, char **argv)
8266 verbose = 0; 8267 verbose = 0;
8267 } 8268 }
8268 while (argv[i]) { 8269 while (argv[i]) {
8269 err |= describe_command(argv[i++], verbose); 8270 err |= describe_command(argv[i++], NULL, verbose);
8270 } 8271 }
8271 return err; 8272 return err;
8272} 8273}
@@ -8280,6 +8281,7 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8280 VERIFY_BRIEF = 1, 8281 VERIFY_BRIEF = 1,
8281 VERIFY_VERBOSE = 2, 8282 VERIFY_VERBOSE = 2,
8282 } verify = 0; 8283 } verify = 0;
8284 const char *path = NULL;
8283 8285
8284 while ((c = nextopt("pvV")) != '\0') 8286 while ((c = nextopt("pvV")) != '\0')
8285 if (c == 'V') 8287 if (c == 'V')
@@ -8290,9 +8292,11 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
8290 else if (c != 'p') 8292 else if (c != 'p')
8291 abort(); 8293 abort();
8292#endif 8294#endif
8295 else
8296 path = bb_default_path;
8293 /* Mimic bash: just "command -v" doesn't complain, it's a nop */ 8297 /* Mimic bash: just "command -v" doesn't complain, it's a nop */
8294 if (verify && (*argptr != NULL)) { 8298 if (verify && (*argptr != NULL)) {
8295 return describe_command(*argptr, verify - VERIFY_BRIEF); 8299 return describe_command(*argptr, path, verify - VERIFY_BRIEF);
8296 } 8300 }
8297 8301
8298 return 0; 8302 return 0;
@@ -9296,14 +9300,15 @@ parse_command_args(char **argv, const char **path)
9296 for (;;) { 9300 for (;;) {
9297 cp = *++argv; 9301 cp = *++argv;
9298 if (!cp) 9302 if (!cp)
9299 return 0; 9303 return NULL;
9300 if (*cp++ != '-') 9304 if (*cp++ != '-')
9301 break; 9305 break;
9302 c = *cp++; 9306 c = *cp++;
9303 if (!c) 9307 if (!c)
9304 break; 9308 break;
9305 if (c == '-' && !*cp) { 9309 if (c == '-' && !*cp) {
9306 argv++; 9310 if (!*++argv)
9311 return NULL;
9307 break; 9312 break;
9308 } 9313 }
9309 do { 9314 do {
@@ -9313,7 +9318,7 @@ parse_command_args(char **argv, const char **path)
9313 break; 9318 break;
9314 default: 9319 default:
9315 /* run 'typecmd' for other options */ 9320 /* run 'typecmd' for other options */
9316 return 0; 9321 return NULL;
9317 } 9322 }
9318 c = *cp++; 9323 c = *cp++;
9319 } while (c); 9324 } while (c);
@@ -9400,6 +9405,9 @@ localcmd(int argc UNUSED_PARAM, char **argv)
9400{ 9405{
9401 char *name; 9406 char *name;
9402 9407
9408 if (!funcnest)
9409 ash_msg_and_raise_error("not in a function");
9410
9403 argv = argptr; 9411 argv = argptr;
9404 while ((name = *argv++) != NULL) { 9412 while ((name = *argv++) != NULL) {
9405 mklocal(name); 9413 mklocal(name);
@@ -9865,7 +9873,7 @@ evalcommand(union node *cmd, int flags)
9865 if (evalbltin(cmdentry.u.cmd, argc, argv)) { 9873 if (evalbltin(cmdentry.u.cmd, argc, argv)) {
9866 int exit_status; 9874 int exit_status;
9867 int i = exception_type; 9875 int i = exception_type;
9868 if (i == EXEXIT) 9876 if (i == EXEXIT || i == EXEXEC)
9869 goto raise; 9877 goto raise;
9870 exit_status = 2; 9878 exit_status = 2;
9871 if (i == EXINT) 9879 if (i == EXINT)
@@ -10959,7 +10967,7 @@ static union node *andor(void);
10959static union node *pipeline(void); 10967static union node *pipeline(void);
10960static union node *parse_command(void); 10968static union node *parse_command(void);
10961static void parseheredoc(void); 10969static void parseheredoc(void);
10962static char nexttoken_ends_list(void); 10970static int peektoken(void);
10963static int readtoken(void); 10971static int readtoken(void);
10964 10972
10965static union node * 10973static union node *
@@ -10968,11 +10976,27 @@ list(int nlflag)
10968 union node *n1, *n2, *n3; 10976 union node *n1, *n2, *n3;
10969 int tok; 10977 int tok;
10970 10978
10971 checkkwd = CHKNL | CHKKWD | CHKALIAS;
10972 if (nlflag == 2 && nexttoken_ends_list())
10973 return NULL;
10974 n1 = NULL; 10979 n1 = NULL;
10975 for (;;) { 10980 for (;;) {
10981 switch (peektoken()) {
10982 case TNL:
10983 if (!(nlflag & 1))
10984 break;
10985 parseheredoc();
10986 return n1;
10987
10988 case TEOF:
10989 if (!n1 && (nlflag & 1))
10990 n1 = NODE_EOF;
10991 parseheredoc();
10992 return n1;
10993 }
10994
10995 checkkwd = CHKNL | CHKKWD | CHKALIAS;
10996 if (nlflag == 2 && tokname_array[peektoken()][0])
10997 return n1;
10998 nlflag |= 2;
10999
10976 n2 = andor(); 11000 n2 = andor();
10977 tok = readtoken(); 11001 tok = readtoken();
10978 if (tok == TBACKGND) { 11002 if (tok == TBACKGND) {
@@ -10998,37 +11022,15 @@ list(int nlflag)
10998 n1 = n3; 11022 n1 = n3;
10999 } 11023 }
11000 switch (tok) { 11024 switch (tok) {
11025 case TNL:
11026 case TEOF:
11027 tokpushback = 1;
11028 /* fall through */
11001 case TBACKGND: 11029 case TBACKGND:
11002 case TSEMI: 11030 case TSEMI:
11003 tok = readtoken();
11004 /* fall through */
11005 case TNL:
11006 if (tok == TNL) {
11007 parseheredoc();
11008 if (nlflag == 1)
11009 return n1;
11010 } else {
11011 tokpushback = 1;
11012 }
11013 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11014 if (nexttoken_ends_list()) {
11015 /* Testcase: "<<EOF; then <W".
11016 * It used to segfault w/o this check:
11017 */
11018 if (heredoclist) {
11019 raise_error_unexpected_syntax(-1);
11020 }
11021 return n1;
11022 }
11023 break; 11031 break;
11024 case TEOF:
11025 if (heredoclist)
11026 parseheredoc();
11027 else
11028 pungetc(); /* push back EOF on input */
11029 return n1;
11030 default: 11032 default:
11031 if (nlflag == 1) 11033 if ((nlflag & 1))
11032 raise_error_unexpected_syntax(-1); 11034 raise_error_unexpected_syntax(-1);
11033 tokpushback = 1; 11035 tokpushback = 1;
11034 return n1; 11036 return n1;
@@ -11356,7 +11358,7 @@ parse_command(void)
11356 n1 = stzalloc(sizeof(struct nfor)); 11358 n1 = stzalloc(sizeof(struct nfor));
11357 n1->type = NFOR; 11359 n1->type = NFOR;
11358 n1->nfor.var = wordtext; 11360 n1->nfor.var = wordtext;
11359 checkkwd = CHKKWD | CHKALIAS; 11361 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11360 if (readtoken() == TIN) { 11362 if (readtoken() == TIN) {
11361 app = &ap; 11363 app = &ap;
11362 while (readtoken() == TWORD) { 11364 while (readtoken() == TWORD) {
@@ -11383,7 +11385,7 @@ parse_command(void)
11383 * Newline or semicolon here is optional (but note 11385 * Newline or semicolon here is optional (but note
11384 * that the original Bourne shell only allowed NL). 11386 * that the original Bourne shell only allowed NL).
11385 */ 11387 */
11386 if (lasttoken != TNL && lasttoken != TSEMI) 11388 if (lasttoken != TSEMI)
11387 tokpushback = 1; 11389 tokpushback = 1;
11388 } 11390 }
11389 checkkwd = CHKNL | CHKKWD | CHKALIAS; 11391 checkkwd = CHKNL | CHKKWD | CHKALIAS;
@@ -11402,10 +11404,8 @@ parse_command(void)
11402 /*n2->narg.next = NULL; - stzalloc did it */ 11404 /*n2->narg.next = NULL; - stzalloc did it */
11403 n2->narg.text = wordtext; 11405 n2->narg.text = wordtext;
11404 n2->narg.backquote = backquotelist; 11406 n2->narg.backquote = backquotelist;
11405 do { 11407 checkkwd = CHKNL | CHKKWD | CHKALIAS;
11406 checkkwd = CHKKWD | CHKALIAS; 11408 if (readtoken() != TIN)
11407 } while (readtoken() == TNL);
11408 if (lasttoken != TIN)
11409 raise_error_unexpected_syntax(TIN); 11409 raise_error_unexpected_syntax(TIN);
11410 cpp = &n1->ncase.cases; 11410 cpp = &n1->ncase.cases;
11411 next_case: 11411 next_case:
@@ -12336,6 +12336,7 @@ static int
12336readtoken(void) 12336readtoken(void)
12337{ 12337{
12338 int t; 12338 int t;
12339 int kwd = checkkwd;
12339#if DEBUG 12340#if DEBUG
12340 smallint alreadyseen = tokpushback; 12341 smallint alreadyseen = tokpushback;
12341#endif 12342#endif
@@ -12349,7 +12350,7 @@ readtoken(void)
12349 /* 12350 /*
12350 * eat newlines 12351 * eat newlines
12351 */ 12352 */
12352 if (checkkwd & CHKNL) { 12353 if (kwd & CHKNL) {
12353 while (t == TNL) { 12354 while (t == TNL) {
12354 parseheredoc(); 12355 parseheredoc();
12355 t = xxreadtoken(); 12356 t = xxreadtoken();
@@ -12363,7 +12364,7 @@ readtoken(void)
12363 /* 12364 /*
12364 * check for keywords 12365 * check for keywords
12365 */ 12366 */
12366 if (checkkwd & CHKKWD) { 12367 if (kwd & CHKKWD) {
12367 const char *const *pp; 12368 const char *const *pp;
12368 12369
12369 pp = findkwd(wordtext); 12370 pp = findkwd(wordtext);
@@ -12397,14 +12398,14 @@ readtoken(void)
12397 return t; 12398 return t;
12398} 12399}
12399 12400
12400static char 12401static int
12401nexttoken_ends_list(void) 12402peektoken(void)
12402{ 12403{
12403 int t; 12404 int t;
12404 12405
12405 t = readtoken(); 12406 t = readtoken();
12406 tokpushback = 1; 12407 tokpushback = 1;
12407 return tokname_array[t][0]; 12408 return t;
12408} 12409}
12409 12410
12410/* 12411/*
@@ -12414,18 +12415,12 @@ nexttoken_ends_list(void)
12414static union node * 12415static union node *
12415parsecmd(int interact) 12416parsecmd(int interact)
12416{ 12417{
12417 int t;
12418
12419 tokpushback = 0; 12418 tokpushback = 0;
12419 checkkwd = 0;
12420 heredoclist = 0;
12420 doprompt = interact; 12421 doprompt = interact;
12421 setprompt_if(doprompt, doprompt); 12422 setprompt_if(doprompt, doprompt);
12422 needprompt = 0; 12423 needprompt = 0;
12423 t = readtoken();
12424 if (t == TEOF)
12425 return NODE_EOF;
12426 if (t == TNL)
12427 return NULL;
12428 tokpushback = 1;
12429 return list(1); 12424 return list(1);
12430} 12425}
12431 12426
diff --git a/shell/ash_test/ash-heredoc/heredoc2.right b/shell/ash_test/ash-heredoc/heredoc2.right
new file mode 100644
index 000000000..a486f1ac4
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc2.right
@@ -0,0 +1,2 @@
1bar
2bar
diff --git a/shell/ash_test/ash-heredoc/heredoc2.tests b/shell/ash_test/ash-heredoc/heredoc2.tests
new file mode 100755
index 000000000..6d9ccb6cc
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc2.tests
@@ -0,0 +1,7 @@
1foo () {
2cat <<EOF && { echo "$1" ; }
3$1
4EOF
5}
6
7foo "bar"
diff --git a/shell/ash_test/ash-heredoc/heredoc3.right b/shell/ash_test/ash-heredoc/heredoc3.right
new file mode 100644
index 000000000..ce0136250
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc3.right
@@ -0,0 +1 @@
hello
diff --git a/shell/ash_test/ash-heredoc/heredoc3.tests b/shell/ash_test/ash-heredoc/heredoc3.tests
new file mode 100755
index 000000000..96c227cc1
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc3.tests
@@ -0,0 +1,9 @@
1echo hello >greeting
2cat <<EOF &&
3$(cat greeting)
4EOF
5{
6 echo $?
7 cat greeting
8} >/dev/null
9rm greeting
diff --git a/shell/ash_test/ash-misc/command.right b/shell/ash_test/ash-misc/command.right
new file mode 100644
index 000000000..7f746d9c4
--- /dev/null
+++ b/shell/ash_test/ash-misc/command.right
@@ -0,0 +1 @@
recho: not found
diff --git a/shell/ash_test/ash-misc/command.tests b/shell/ash_test/ash-misc/command.tests
new file mode 100755
index 000000000..5d445af51
--- /dev/null
+++ b/shell/ash_test/ash-misc/command.tests
@@ -0,0 +1 @@
command -p -V recho
diff --git a/shell/ash_test/ash-misc/command2.right b/shell/ash_test/ash-misc/command2.right
new file mode 100644
index 000000000..8d2165f69
--- /dev/null
+++ b/shell/ash_test/ash-misc/command2.right
@@ -0,0 +1,2 @@
1test1
2./command2.tests: ./test1.sh: line 1: ./test2.sh: Permission denied
diff --git a/shell/ash_test/ash-misc/command2.tests b/shell/ash_test/ash-misc/command2.tests
new file mode 100755
index 000000000..9d9de9a89
--- /dev/null
+++ b/shell/ash_test/ash-misc/command2.tests
@@ -0,0 +1,6 @@
1echo "echo test1; ./test2.sh" >test1.sh
2echo "echo test2" >test2.sh
3
4command . ./test1.sh
5
6rm -f test1.sh test2.sh
diff --git a/shell/ash_test/ash-misc/exec.right b/shell/ash_test/ash-misc/exec.right
new file mode 100644
index 000000000..1741a38dd
--- /dev/null
+++ b/shell/ash_test/ash-misc/exec.right
@@ -0,0 +1,2 @@
1./exec.tests: exec: line 2: ./test1.sh: not found
2127
diff --git a/shell/ash_test/ash-misc/exec.tests b/shell/ash_test/ash-misc/exec.tests
new file mode 100755
index 000000000..624915de1
--- /dev/null
+++ b/shell/ash_test/ash-misc/exec.tests
@@ -0,0 +1,3 @@
1rm -f test1.sh
2(exec ./test1.sh)
3echo $?
diff --git a/shell/ash_test/ash-misc/for.right b/shell/ash_test/ash-misc/for.right
new file mode 100644
index 000000000..d86bac9de
--- /dev/null
+++ b/shell/ash_test/ash-misc/for.right
@@ -0,0 +1 @@
OK
diff --git a/shell/ash_test/ash-misc/for.tests b/shell/ash_test/ash-misc/for.tests
new file mode 100755
index 000000000..4889a9f2d
--- /dev/null
+++ b/shell/ash_test/ash-misc/for.tests
@@ -0,0 +1,5 @@
1for i
2in OK
3do
4 echo $i
5done
diff --git a/shell/ash_test/ash-misc/local2.right b/shell/ash_test/ash-misc/local2.right
new file mode 100644
index 000000000..630ef7979
--- /dev/null
+++ b/shell/ash_test/ash-misc/local2.right
@@ -0,0 +1 @@
./local2.tests: local: line 1: not in a function
diff --git a/shell/ash_test/ash-misc/local2.tests b/shell/ash_test/ash-misc/local2.tests
new file mode 100755
index 000000000..8e14037c5
--- /dev/null
+++ b/shell/ash_test/ash-misc/local2.tests
@@ -0,0 +1 @@
local x=1
diff --git a/shell/ash_test/run-all b/shell/ash_test/run-all
index ad93e251d..354cc1fcf 100755
--- a/shell/ash_test/run-all
+++ b/shell/ash_test/run-all
@@ -31,8 +31,9 @@ do_test()
31 *.orig|*~) ;; 31 *.orig|*~) ;;
32 #*) echo $x ; sh $x ;; 32 #*) echo $x ; sh $x ;;
33 *) 33 *)
34 echo -n "$1/$x: "
34 sh "$x" >"$TOPDIR/$noslash-$x.fail" 2>&1 && \ 35 sh "$x" >"$TOPDIR/$noslash-$x.fail" 2>&1 && \
35 { echo "$1/$x: ok"; rm "$TOPDIR/$noslash-$x.fail"; } || echo "$1/$x: fail"; 36 { echo "ok"; rm "$TOPDIR/$noslash-$x.fail"; } || echo "fail";
36 ;; 37 ;;
37 esac 38 esac
38 done 39 done
@@ -42,11 +43,12 @@ do_test()
42 test -x "$x" || continue 43 test -x "$x" || continue
43 name="${x%%.tests}" 44 name="${x%%.tests}"
44 test -f "$name.right" || continue 45 test -f "$name.right" || continue
46 echo -n "$1/$x: "
45 { 47 {
46 "$THIS_SH" "./$x" >"$name.xx" 2>&1 48 "$THIS_SH" "./$x" >"$name.xx" 2>&1
47 diff -u "$name.xx" "$name.right" >"$TOPDIR/$noslash-$x.fail" \ 49 diff -u "$name.xx" "$name.right" >"$TOPDIR/$noslash-$x.fail" \
48 && rm -f "$name.xx" "$TOPDIR/$noslash-$x.fail" 50 && rm -f "$name.xx" "$TOPDIR/$noslash-$x.fail"
49 } && echo "$1/$x: ok" || echo "$1/$x: fail" 51 } && echo "ok" || echo "fail"
50 done 52 done
51 ) 53 )
52} 54}
diff --git a/shell/hush_test/hush-misc/for.right b/shell/hush_test/hush-misc/for.right
new file mode 100644
index 000000000..d86bac9de
--- /dev/null
+++ b/shell/hush_test/hush-misc/for.right
@@ -0,0 +1 @@
OK
diff --git a/shell/hush_test/hush-misc/for.tests b/shell/hush_test/hush-misc/for.tests
new file mode 100755
index 000000000..4889a9f2d
--- /dev/null
+++ b/shell/hush_test/hush-misc/for.tests
@@ -0,0 +1,5 @@
1for i
2in OK
3do
4 echo $i
5done