st-externalpipe-0.6.diff (1551B)
1 diff --git a/st.c b/st.c 2 index b89d094..124ed16 100644 3 --- a/st.c 4 +++ b/st.c 5 @@ -326,6 +326,7 @@ static void clipcopy(const Arg *); 6 static void clippaste(const Arg *); 7 static void numlock(const Arg *); 8 static void selpaste(const Arg *); 9 +static void externalpipe(const Arg *); 10 static void xzoom(const Arg *); 11 static void xzoomabs(const Arg *); 12 static void xzoomreset(const Arg *); 13 @@ -2684,6 +2685,62 @@ eschandle(uchar ascii) { 14 } 15 16 void 17 +externalpipe(const Arg *arg) 18 +{ 19 + int to[2]; /* 0 = read, 1 = write */ 20 + pid_t child; 21 + int n; 22 + void (*oldsigpipe)(int); 23 + char buf[UTF_SIZ]; 24 + Glyph *bp, *end; 25 + 26 + if(pipe(to) == -1) 27 + return; 28 + 29 + /* sigchld() handles this */ 30 + switch(child = fork()){ 31 + case -1: 32 + close(to[0]), close(to[1]); 33 + return; 34 + case 0: 35 + /* child */ 36 + close(to[1]); 37 + dup2(to[0], STDIN_FILENO); /* 0<&to */ 38 + close(to[0]); 39 + execvp( 40 + "sh", 41 + (char *const []){ 42 + "/bin/sh", 43 + "-c", 44 + (char *)arg->v, 45 + 0 46 + }); 47 + exit(127); 48 + } 49 + 50 + /* parent */ 51 + close(to[0]); 52 + /* ignore sigpipe for now, in case child exits early */ 53 + oldsigpipe = signal(SIGPIPE, SIG_IGN); 54 + 55 + for(n = 0; n < term.row; n++){ 56 + bp = &term.line[n][0]; 57 + end = &bp[MIN(tlinelen(n), term.col) - 1]; 58 + if(bp != end || bp->u != ' ') 59 + for(; bp <= end; ++bp) 60 + if(xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) 61 + break; 62 + if(xwrite(to[1], "\n", 1) < 0) 63 + break; 64 + } 65 + 66 + close(to[1]); 67 + 68 + /* restore */ 69 + signal(SIGPIPE, oldsigpipe); 70 +} 71 + 72 +void 73 tputc(Rune u) { 74 char c[UTF_SIZ]; 75 bool control;