st/patches/st-externalpipe-0.8.2.diff (view raw)
1diff --git a/st.c b/st.c
2index ede7ae6..f55d30f 100644
3--- a/st.c
4+++ b/st.c
5@@ -1914,6 +1914,59 @@ strparse(void)
6 }
7 }
8
9+void
10+externalpipe(const Arg *arg)
11+{
12+ int to[2];
13+ char buf[UTF_SIZ];
14+ void (*oldsigpipe)(int);
15+ Glyph *bp, *end;
16+ int lastpos, n, newline;
17+
18+ if (pipe(to) == -1)
19+ return;
20+
21+ switch (fork()) {
22+ case -1:
23+ close(to[0]);
24+ close(to[1]);
25+ return;
26+ case 0:
27+ dup2(to[0], STDIN_FILENO);
28+ close(to[0]);
29+ close(to[1]);
30+ execvp(((char **)arg->v)[0], (char **)arg->v);
31+ fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
32+ perror("failed");
33+ exit(0);
34+ }
35+
36+ close(to[0]);
37+ /* ignore sigpipe for now, in case child exists early */
38+ oldsigpipe = signal(SIGPIPE, SIG_IGN);
39+ newline = 0;
40+ for (n = 0; n < term.row; n++) {
41+ bp = term.line[n];
42+ lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
43+ if (lastpos < 0)
44+ break;
45+ end = &bp[lastpos + 1];
46+ for (; bp < end; ++bp)
47+ if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
48+ break;
49+ if ((newline = term.line[n][lastpos].mode & ATTR_WRAP))
50+ continue;
51+ if (xwrite(to[1], "\n", 1) < 0)
52+ break;
53+ newline = 0;
54+ }
55+ if (newline)
56+ (void)xwrite(to[1], "\n", 1);
57+ close(to[1]);
58+ /* restore */
59+ signal(SIGPIPE, oldsigpipe);
60+}
61+
62 void
63 strdump(void)
64 {
65diff --git a/st.h b/st.h
66index 4da3051..cb7101f 100644
67--- a/st.h
68+++ b/st.h
69@@ -80,6 +80,7 @@ void die(const char *, ...);
70 void redraw(void);
71 void draw(void);
72
73+void externalpipe(const Arg *);
74 void printscreen(const Arg *);
75 void printsel(const Arg *);
76 void sendbreak(const Arg *);