diff --git a/st.c b/st.c index 2594c65..ecd9bdc 100644 --- a/st.c +++ b/st.c @@ -329,6 +329,7 @@ static void clipcopy(const Arg *); static void clippaste(const Arg *); static void numlock(const Arg *); static void selpaste(const Arg *); +static void externalpipe(const Arg *); static void xzoom(const Arg *); static void xzoomabs(const Arg *); static void xzoomreset(const Arg *); @@ -337,6 +338,9 @@ static void printscreen(const Arg *) ; static void toggleprinter(const Arg *); static void sendbreak(const Arg *); +/* variables used in config.h */ +static char winid[64]; + /* Config.h for applying patches and the configuration. */ #include "config.h" @@ -2922,6 +2926,59 @@ eschandle(uchar ascii) } void +externalpipe(const Arg *arg) +{ + int to[2]; + char buf[UTF_SIZ]; + void (*oldsigpipe)(int); + Glyph *bp, *end; + int lastpos, n, newline; + + if (pipe(to) == -1) + return; + + switch (fork()) { + case -1: + close(to[0]); + close(to[1]); + return; + case 0: + dup2(to[0], STDIN_FILENO); + close(to[0]); + close(to[1]); + execvp(((char **)arg->v)[0], (char **)arg->v); + fprintf(stderr, "st: execvp %s ", ((char **)arg->v)[0]); + perror("failed"); + exit(0); + } + + close(to[0]); + /* ignore sigpipe for now, in case child exits early */ + oldsigpipe = signal(SIGPIPE, SIG_IGN); + newline = 0; + for (n = 0; n < term.row; n++) { + bp = term.line[n]; + lastpos = MIN(tlinelen(n) + 1, term.col) - 1; + if (lastpos < 0) + break; + end = &bp[lastpos + 1]; + for (; bp < end; ++bp) + if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) + break; + if ((newline = term.line[n][lastpos].mode & ATTR_WRAP)) + continue; + if (xwrite(to[1], "\n", 1) < 0) + break; + newline = 0; + } + if (newline) + (void)xwrite(to[1], "\n", 1); + close(to[1]); + /* restore */ + signal(SIGPIPE, oldsigpipe); +} + +void tputc(Rune u) { char c[UTF_SIZ]; @@ -3479,6 +3536,7 @@ xinit(void) xw.w, xw.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity | CWEventMask | CWColormap, &xw.attrs); + snprintf(winid, LEN(winid), "%lu", (unsigned long)xw.win); memset(&gcvalues, 0, sizeof(gcvalues)); gcvalues.graphics_exposures = False;