From a41a62dad70436d869d34cbac6087c02b3fa0557 Mon Sep 17 00:00:00 2001 From: tg Date: Sun, 26 Jun 2016 00:44:59 +0000 Subject: [PATCH] =?UTF-8?q?efficient=20$(<<" + y=$(<<-EOF + hi! + + $foo) is not a problem + + + EOF) + echo "7<$y>" +expected-stdout: + 3 + 7 +--- name: heredoc-subshell-1 description: Tests for here documents in subshells, taken from Austin ML diff --git a/eval.c b/eval.c index 3899bfa..b93e808 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.188 2016/06/25 23:54:59 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.189 2016/06/26 00:44:57 tg Exp $"); /* * string expansion @@ -1326,14 +1326,31 @@ comsub(Expand *xp, const char *cp, int fn MKSH_A_UNUSED) struct ioword *io = *t->ioact; char *name; - if ((io->ioflag & IOTYPE) != IOREAD) + switch (io->ioflag & IOTYPE) { + case IOREAD: + shf = shf_open(name = evalstr(io->ioname, DOTILDE), + O_RDONLY, 0, SHF_MAPHI | SHF_CLEXEC); + if (shf == NULL) + warningf(!Flag(FTALKING), "%s: %s %s: %s", + name, "can't open", "$(<...) input", + cstrerror(errno)); + break; + case IOHERE: + if (!herein(io, &name)) { + xp->str = name; + /* as $(…) requires, trim trailing newlines */ + name += strlen(name); + while (name > xp->str && name[-1] == '\n') + --name; + *name = '\0'; + return (XSUB); + } + shf = NULL; + break; + default: errorf("%s: %s", T_funny_command, snptreef(NULL, 32, "%R", io)); - shf = shf_open(name = evalstr(io->ioname, DOTILDE), O_RDONLY, - 0, SHF_MAPHI | SHF_CLEXEC); - if (shf == NULL) - warningf(!Flag(FTALKING), "%s: %s %s: %s", name, - "can't open", "$(<...) input", cstrerror(errno)); + } } else if (fn == FUNSUB) { int ofd1; struct temp *tf = NULL; diff --git a/exec.c b/exec.c index a75f489..a3ab278 100644 --- a/exec.c +++ b/exec.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.174 2016/06/26 00:09:35 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.175 2016/06/26 00:44:58 tg Exp $"); #ifndef MKSH_DEFAULT_EXECSHELL #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" @@ -34,7 +34,6 @@ static int comexec(struct op *, struct tbl * volatile, const char **, static void scriptexec(struct op *, const char **) MKSH_A_NORETURN; static int call_builtin(struct tbl *, const char **, const char *, bool); static int iosetup(struct ioword *, struct tbl *); -static int herein(struct ioword *, char **); static const char *do_selectargs(const char **, bool); static Test_op dbteste_isa(Test_env *, Test_meta); static const char *dbteste_getopnd(Test_env *, Test_op, bool); @@ -1557,7 +1556,7 @@ hereinval(struct ioword *iop, int sub, char **resbuf, struct shf *shf) return (0); } -static int +int herein(struct ioword *iop, char **resbuf) { int fd = -1; diff --git a/sh.h b/sh.h index d5234e4..370961a 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.773 2016/06/25 23:49:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.774 2016/06/26 00:44:59 tg Exp $"); #endif -#define MKSH_VERSION "R52 2016/05/17" +#define MKSH_VERSION "R52 2016/06/25" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -1752,6 +1752,7 @@ int search_access(const char *, int); const char *search_path(const char *, const char *, int, int *); void pr_menu(const char * const *); void pr_list(char * const *); +int herein(struct ioword *, char **); /* expr.c */ int evaluate(const char *, mksh_ari_t *, int, bool); int v_evaluate(struct tbl *, const char *, volatile int, bool);