ref: 2025214dfcc46ac16cb93abc05b344330987b339
parent: d0c9127b10251d85b56eba00bc586b57dd998aaf
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Dec 31 18:26:59 EST 2021
rc: fix here document handling with quoted end-marker (thanks sigrid) when end marker is quoted, we should not substitute. also, pcmd() needs to print the end marker without quotes.
--- a/sys/src/cmd/rc/code.c
+++ b/sys/src/cmd/rc/code.c
@@ -353,14 +353,10 @@
stuffdot(p);
break;
case REDIR:
- emitf(Xmark);
- if(t->rtype==HERE){
- /* replace end marker with mktmep() pattern */
- free(c0->str);
- c0->str=estrdup("/tmp/here.XXXXXXXXXXX");
- c0->glob=0;
+ if(t->rtype!=HERE){
+ emitf(Xmark);
+ outcode(c0, eflag);
}
- outcode(c0, eflag);
switch(t->rtype){
case APPEND:
emitf(Xappend);
@@ -375,7 +371,7 @@
emitf(Xrdwr);
break;
case HERE:
- emitf(Xhere);
+ emitf(c0->quoted?Xhereq:Xhere);
emits(t->str);
t->str=0; /* passed ownership */
break;
@@ -539,7 +535,7 @@
|| p->f==Xsubshell || p->f==Xtrue) p++;
else if(p->f==Xdup || p->f==Xpipefd) p+=2;
else if(p->f==Xpipe) p+=4;
- else if(p->f==Xhere) free(p[1].s), p+=2;
+ else if(p->f==Xhere || p->f==Xhereq) free(p[1].s), p+=2;
else if(p->f==Xword) free((++p)->s);
else if(p->f==Xfn){
free(p[2].s);
--- a/sys/src/cmd/rc/exec.c
+++ b/sys/src/cmd/rc/exec.c
@@ -446,22 +446,11 @@
void
Xhere(void)
{
- char *file;
+ char file[] = "/tmp/here.XXXXXXXXXXX";
int fd;
io *io;
- switch(count(runq->argv->words)){
- default:
- Xerror1("<< requires singleton");
- return;
- case 0:
- Xerror1("<< requires file");
- return;
- case 1:
- break;
- }
- file = mktemp(runq->argv->words->word);
- if((fd = Creat(file))<0){
+ if((fd = Creat(mktemp(file)))<0){
Xerror("can't open");
return;
}
@@ -469,6 +458,7 @@
psubst(io, (uchar*)runq->code[runq->pc++].s);
flushio(io);
closeio(io);
+
/* open for reading and unlink */
if((fd = Open(file, 3))<0){
Xerror("can't open");
@@ -475,7 +465,28 @@
return;
}
pushredir(ROPEN, fd, runq->code[runq->pc++].i);
- poplist();
+}
+
+void
+Xhereq(void)
+{
+ char file[] = "/tmp/here.XXXXXXXXXXX", *body;
+ int fd;
+
+ if((fd = Creat(mktemp(file)))<0){
+ Xerror("can't open");
+ return;
+ }
+ body = runq->code[runq->pc++].s;
+ Write(fd, body, strlen(body));
+ Close(fd);
+
+ /* open for reading and unlink */
+ if((fd = Open(file, 3))<0){
+ Xerror("can't open");
+ return;
+ }
+ pushredir(ROPEN, fd, runq->code[runq->pc++].i);
}
void
--- a/sys/src/cmd/rc/exec.h
+++ b/sys/src/cmd/rc/exec.h
@@ -4,7 +4,7 @@
extern void Xappend(void), Xasync(void), Xbackq(void), Xbang(void), Xclose(void);
extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqw(void), Xdup(void);
extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void);
-extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void), Xhere(void);
+extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void), Xhere(void), Xhereq(void);
extern void Xrdwr(void), Xsrcline(void);
extern void Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void);
extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void);
--- a/sys/src/cmd/rc/pcmd.c
+++ b/sys/src/cmd/rc/pcmd.c
@@ -147,7 +147,7 @@
}
pfmt(f, "%t", c0);
if(t->rtype == HERE)
- pfmt(f, "\n%s%t\n", t->str, c0);
+ pfmt(f, "\n%s%s\n", t->str, c0->str);
else if(c1)
pfmt(f, " %t", c1);
break;