shithub: riscv

Download patch

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;