commit c5087aac7bbdbffd5a26a578fb1f401b48b91bf1
parent c63a87cd936c1eeef14c4c21572e5b782d3df4bc
Author: Christoph Lohmann <20h@r-36.net>
Date:   Sun, 19 Feb 2017 16:45:51 +0100
Apply externalpipe patch to default.
Diffstat:
| st.c | | | 57 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
1 file changed, 57 insertions(+), 0 deletions(-)
diff --git a/st.c b/st.c
@@ -344,6 +344,7 @@ static void printscreen(const Arg *) ;
 static void iso14755(const Arg *);
 static void toggleprinter(const Arg *);
 static void sendbreak(const Arg *);
+static void externalpipe(const Arg *);
 
 /* Config.h for applying patches and the configuration. */
 #include "config.h"
@@ -2996,6 +2997,62 @@ eschandle(uchar ascii)
 }
 
 void
+externalpipe(const Arg *arg)
+{
+	int to[2]; /* 0 = read, 1 = write */
+	pid_t child;
+	int n;
+	void (*oldsigpipe)(int);
+	char buf[UTF_SIZ];
+	Glyph *bp, *end;
+
+	if(pipe(to) == -1)
+		return;
+
+	/* sigchld() handles this */
+	switch(child = fork()){
+		case -1:
+			close(to[0]), close(to[1]);
+			return;
+		case 0:
+			/* child */
+			close(to[1]);
+			dup2(to[0], STDIN_FILENO); /* 0<&to */
+			close(to[0]);
+			execvp(
+					"sh",
+					(char *const []){
+						"/bin/sh",
+						"-c",
+						(char *)arg->v,
+						0
+					});
+			exit(127);
+	}
+
+	/* parent */
+	close(to[0]);
+	/* ignore sigpipe for now, in case child exits early */
+	oldsigpipe = signal(SIGPIPE, SIG_IGN);
+
+	for(n = 0; n < term.row; n++){
+		bp = &term.line[n][0];
+		end = &bp[MIN(tlinelen(n), term.col) - 1];
+		if(bp != end || bp->u != ' ')
+			for(; bp <= end; ++bp)
+				if(xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
+					break;
+		if(xwrite(to[1], "\n", 1) < 0)
+			break;
+	}
+
+	close(to[1]);
+
+	/* restore */
+	signal(SIGPIPE, oldsigpipe);
+}
+
+void
 tputc(Rune u)
 {
 	char c[UTF_SIZ];