aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c90
-rw-r--r--shell/ash_test/ash-heredoc/herestring1.right33
-rwxr-xr-xshell/ash_test/ash-heredoc/herestring1.tests35
-rw-r--r--shell/hush.c16
4 files changed, 139 insertions, 35 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 773de79f5..61f10d74e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -431,7 +431,7 @@ struct forkshell {
431 int fd[3]; 431 int fd[3];
432 union node *n; 432 union node *n;
433 char **argv; 433 char **argv;
434 char *path; 434 const char *path;
435} ALIGN64; 435} ALIGN64;
436 436
437enum { 437enum {
@@ -1181,14 +1181,15 @@ static const char dolatstr[] ALIGN1 = {
1181#endif 1181#endif
1182#define NCLOBBER 18 1182#define NCLOBBER 18
1183#define NFROM 19 1183#define NFROM 19
1184#define NFROMTO 20 1184#define NFROMSTR 20
1185#define NAPPEND 21 1185#define NFROMTO 21
1186#define NTOFD 22 1186#define NAPPEND 22
1187#define NFROMFD 23 1187#define NTOFD 23
1188#define NHERE 24 1188#define NFROMFD 24
1189#define NXHERE 25 1189#define NHERE 25
1190#define NNOT 26 1190#define NXHERE 26
1191#define N_NUMBER 27 1191#define NNOT 27
1192#define N_NUMBER 28
1192 1193
1193union node; 1194union node;
1194 1195
@@ -1619,6 +1620,7 @@ shcmd(union node *cmd, FILE *fp)
1619#endif 1620#endif
1620 case NTOFD: s = ">&"; dftfd = 1; break; 1621 case NTOFD: s = ">&"; dftfd = 1; break;
1621 case NFROM: s = "<"; break; 1622 case NFROM: s = "<"; break;
1623 case NFROMSTR: s = "<<<"; break;
1622 case NFROMFD: s = "<&"; break; 1624 case NFROMFD: s = "<&"; break;
1623 case NFROMTO: s = "<>"; break; 1625 case NFROMTO: s = "<>"; break;
1624 default: s = "*error*"; break; 1626 default: s = "*error*"; break;
@@ -5881,6 +5883,9 @@ cmdtxt(union node *n)
5881 case NXHERE: 5883 case NXHERE:
5882 p = "<<..."; 5884 p = "<<...";
5883 goto dotail2; 5885 goto dotail2;
5886 case NFROMSTR:
5887 p = "<<<";
5888 goto dotail2;
5884 case NCASE: 5889 case NCASE:
5885 cmdputs("case "); 5890 cmdputs("case ");
5886 cmdputs(n->ncase.expr->narg.text); 5891 cmdputs(n->ncase.expr->narg.text);
@@ -6371,26 +6376,11 @@ stoppedjobs(void)
6371 * data to a pipe. If the document is short, we can stuff the data in 6376 * data to a pipe. If the document is short, we can stuff the data in
6372 * the pipe without forking. 6377 * the pipe without forking.
6373 */ 6378 */
6374/* openhere needs this forward reference */
6375static void expandhere(union node *arg);
6376static int 6379static int
6377openhere(union node *redir) 6380write2pipe(int pip[2], const char *p, size_t len)
6378{ 6381{
6379 char *p;
6380 int pip[2];
6381 size_t len = 0;
6382 IF_PLATFORM_MINGW32(struct forkshell fs); 6382 IF_PLATFORM_MINGW32(struct forkshell fs);
6383 6383
6384 if (pipe(pip) < 0)
6385 ash_msg_and_raise_perror("can't create pipe");
6386
6387 p = redir->nhere.doc->narg.text;
6388 if (redir->type == NXHERE) {
6389 expandhere(redir->nhere.doc);
6390 p = stackblock();
6391 }
6392
6393 len = strlen(p);
6394 if (len <= PIPE_BUF) { 6384 if (len <= PIPE_BUF) {
6395 xwrite(pip[1], p, len); 6385 xwrite(pip[1], p, len);
6396 goto out; 6386 goto out;
@@ -6421,6 +6411,42 @@ openhere(union node *redir)
6421 return pip[0]; 6411 return pip[0];
6422} 6412}
6423 6413
6414/* openhere needs this forward reference */
6415static void expandhere(union node *arg);
6416static int
6417openhere(union node *redir)
6418{
6419 char *p;
6420 int pip[2];
6421
6422 if (pipe(pip) < 0)
6423 ash_msg_and_raise_perror("can't create pipe");
6424
6425 p = redir->nhere.doc->narg.text;
6426 if (redir->type == NXHERE) {
6427 expandhere(redir->nhere.doc);
6428 p = stackblock();
6429 }
6430
6431 return write2pipe(pip, p, strlen(p));
6432}
6433
6434static int
6435openherestr(char *str)
6436{
6437 int pip[2];
6438 size_t len;
6439
6440 if (pipe(pip) < 0)
6441 ash_msg_and_raise_perror("can't create pipe");
6442
6443 len = strlen(str);
6444 str[len] = '\n';
6445 write2pipe(pip, str, len + 1);
6446 str[len] = '\0';
6447 return pip[0];
6448}
6449
6424static int 6450static int
6425openredirect(union node *redir) 6451openredirect(union node *redir)
6426{ 6452{
@@ -6439,6 +6465,9 @@ openredirect(union node *redir)
6439 lseek(f, 0, SEEK_END); 6465 lseek(f, 0, SEEK_END);
6440#endif 6466#endif
6441 break; 6467 break;
6468 case NFROMSTR:
6469 f = openherestr(redir->nfile.expfname);
6470 break;
6442 case NFROMTO: 6471 case NFROMTO:
6443 flags = O_RDWR|O_CREAT; 6472 flags = O_RDWR|O_CREAT;
6444 goto do_open; 6473 goto do_open;
@@ -10176,6 +10205,7 @@ calcsize(int funcblocksize, union node *n)
10176#endif 10205#endif
10177 case NCLOBBER: 10206 case NCLOBBER:
10178 case NFROM: 10207 case NFROM:
10208 case NFROMSTR:
10179 case NFROMTO: 10209 case NFROMTO:
10180 case NAPPEND: 10210 case NAPPEND:
10181 funcblocksize = calcsize(funcblocksize, n->nfile.fname); 10211 funcblocksize = calcsize(funcblocksize, n->nfile.fname);
@@ -10392,6 +10422,7 @@ copynode(union node *n)
10392#endif 10422#endif
10393 case NCLOBBER: 10423 case NCLOBBER:
10394 case NFROM: 10424 case NFROM:
10425 case NFROMSTR:
10395 case NFROMTO: 10426 case NFROMTO:
10396 case NAPPEND: 10427 case NAPPEND:
10397 new->nfile.fname = copynode(n->nfile.fname); 10428 new->nfile.fname = copynode(n->nfile.fname);
@@ -10929,6 +10960,7 @@ expredir(union node *n)
10929 switch (redir->type) { 10960 switch (redir->type) {
10930 case NFROMTO: 10961 case NFROMTO:
10931 case NFROM: 10962 case NFROM:
10963 case NFROMSTR:
10932 case NTO: 10964 case NTO:
10933#if BASH_REDIR_OUTPUT 10965#if BASH_REDIR_OUTPUT
10934 case NTO2: 10966 case NTO2:
@@ -14306,6 +14338,11 @@ parseredir: {
14306 c = pgetc_eatbnl(); 14338 c = pgetc_eatbnl();
14307 switch (c) { 14339 switch (c) {
14308 case '<': 14340 case '<':
14341 c = pgetc_eatbnl();
14342 if (c == '<') {
14343 np->type = NFROMSTR;
14344 break;
14345 }
14309 if (sizeof(struct nfile) != sizeof(struct nhere)) { 14346 if (sizeof(struct nfile) != sizeof(struct nhere)) {
14310 np = stzalloc(sizeof(struct nhere)); 14347 np = stzalloc(sizeof(struct nhere));
14311 /*np->nfile.fd = 0; - stzalloc did it */ 14348 /*np->nfile.fd = 0; - stzalloc did it */
@@ -14313,7 +14350,6 @@ parseredir: {
14313 np->type = NHERE; 14350 np->type = NHERE;
14314 heredoc = stzalloc(sizeof(struct heredoc)); 14351 heredoc = stzalloc(sizeof(struct heredoc));
14315 heredoc->here = np; 14352 heredoc->here = np;
14316 c = pgetc_eatbnl();
14317 if (c == '-') { 14353 if (c == '-') {
14318 heredoc->striptabs = 1; 14354 heredoc->striptabs = 1;
14319 } else { 14355 } else {
@@ -16768,7 +16804,7 @@ forkshell_shellexec(struct forkshell *fs)
16768{ 16804{
16769 int idx = fs->fd[0]; 16805 int idx = fs->fd[0];
16770 char **argv = fs->argv; 16806 char **argv = fs->argv;
16771 char *path = fs->path; 16807 const char *path = fs->path;
16772 16808
16773 FORCEINTON; 16809 FORCEINTON;
16774 shellexec(argv[0], argv, path, idx, TRUE); 16810 shellexec(argv[0], argv, path, idx, TRUE);
diff --git a/shell/ash_test/ash-heredoc/herestring1.right b/shell/ash_test/ash-heredoc/herestring1.right
new file mode 100644
index 000000000..555937daa
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/herestring1.right
@@ -0,0 +1,33 @@
1one
2_two
3\_three
4\_four
5\_two
6\_three
7\\_four
8two_newlines
9
10/bin/c*
11star_*
12star_*
13star_*
14star_\*
15star_*
16star_\*
17line1
18line2
19 line3
20line1
21line2
22 line3
23512
24256
25128
2664
2732
2816
298
304
312
32v-$a-\t-\-\"-\x-`-\--\z-\*-\?-
33v-$a-\t-\-"-\x-`-\--\z-\*-\?-
diff --git a/shell/ash_test/ash-heredoc/herestring1.tests b/shell/ash_test/ash-heredoc/herestring1.tests
new file mode 100755
index 000000000..fb7bd0dda
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/herestring1.tests
@@ -0,0 +1,35 @@
1cat <<<one
2cat <<<\_two
3cat <<<"\_three"
4cat <<<'\_four'
5cat <<<\\_two
6cat <<<"\\_three"
7cat <<<'\\_four'
8
9cat <<<$'two_newlines\n'
10
11cat <<</bin/c*
12
13cat <<<star_*
14cat <<<star_\*
15cat <<<"star_*"
16cat <<<"star_\*"
17cat <<<'star_*'
18cat <<<'star_\*'
19
20var=$'line1
21line2
22 line3'
23
24cat <<<$var
25
26cat <<<"$var"
27
28i=10
29until test $((--i)) = 0; do
30 cat <<<$((2**i))
31done
32
33a=qwerty
34cat <<<`echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`
35cat <<<"`echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`"
diff --git a/shell/hush.c b/shell/hush.c
index 226a6d68f..da0db7948 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -683,6 +683,7 @@ struct command {
683# endif 683# endif
684# define CMD_FUNCDEF 5 684# define CMD_FUNCDEF 5
685#endif 685#endif
686/* ^^^ if you change this, update CMDTYPE[] array too */
686 687
687 smalluint cmd_exitcode; 688 smalluint cmd_exitcode;
688 /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */ 689 /* if non-NULL, this "command" is { list }, ( list ), or a compound statement */
@@ -3947,7 +3948,7 @@ static void debug_print_tree(struct pipe *pi, int lvl)
3947# endif 3948# endif
3948# if ENABLE_HUSH_CASE 3949# if ENABLE_HUSH_CASE
3949 [RES_CASE ] = "CASE" , 3950 [RES_CASE ] = "CASE" ,
3950 [RES_CASE_IN] = "CASE_IN" , 3951 [RES_CASE_IN] = "CASE_IN",
3951 [RES_MATCH] = "MATCH", 3952 [RES_MATCH] = "MATCH",
3952 [RES_CASE_BODY] = "CASE_BODY", 3953 [RES_CASE_BODY] = "CASE_BODY",
3953 [RES_ESAC ] = "ESAC" , 3954 [RES_ESAC ] = "ESAC" ,
@@ -3956,11 +3957,13 @@ static void debug_print_tree(struct pipe *pi, int lvl)
3956 [RES_SNTX ] = "SNTX" , 3957 [RES_SNTX ] = "SNTX" ,
3957 }; 3958 };
3958 static const char *const CMDTYPE[] ALIGN_PTR = { 3959 static const char *const CMDTYPE[] ALIGN_PTR = {
3959 "{}", 3960 "{}", //CMD_NORMAL
3960 "()", 3961 "()", //CMD_SUBSHELL
3961 "[noglob]", 3962 "[test2]", //CMD_TEST2_SINGLEWORD_NOGLOB
3963 "[noglob]", //CMD_SINGLEWORD_NOGLOB
3962# if ENABLE_HUSH_FUNCTIONS 3964# if ENABLE_HUSH_FUNCTIONS
3963 "func()", 3965 "func()", //CMD_FUNCTION_KWORD
3966 "funcdef", //CMD_FUNCDEF
3964# endif 3967# endif
3965 }; 3968 };
3966 3969
@@ -12988,9 +12991,6 @@ static int FAST_FUNC builtin_alias(char **argv)
12988 } 12991 }
12989 12992
12990 while (*++argv) { 12993 while (*++argv) {
12991 /* The characters /, $, `, = and any of the shell
12992 * metacharacters or quoting characters
12993 * may not appear in an alias name */
12994 char *eq = end_of_alias_name(*argv); 12994 char *eq = end_of_alias_name(*argv);
12995 if (*eq == '=' && eq != *argv) { 12995 if (*eq == '=' && eq != *argv) {
12996 /* alias NAME=VALUE */ 12996 /* alias NAME=VALUE */