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