st-externalpipe-0.8.4.diff (2008B)
1 diff --git a/st.c b/st.c 2 index 76b7e0d..0e9a614 100644 3 --- a/st.c 4 +++ b/st.c 5 @@ -723,8 +723,14 @@ sigchld(int a) 6 if ((p = waitpid(pid, &stat, WNOHANG)) < 0) 7 die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); 8 9 - if (pid != p) 10 + if (pid != p) { 11 + if (p == 0 && wait(&stat) < 0) 12 + die("wait: %s\n", strerror(errno)); 13 + 14 + /* reinstall sigchld handler */ 15 + signal(SIGCHLD, sigchld); 16 return; 17 + } 18 19 if (WIFEXITED(stat) && WEXITSTATUS(stat)) 20 die("child exited with status %d\n", WEXITSTATUS(stat)); 21 @@ -1926,6 +1932,59 @@ strparse(void) 22 } 23 } 24 25 +void 26 +externalpipe(const Arg *arg) 27 +{ 28 + int to[2]; 29 + char buf[UTF_SIZ]; 30 + void (*oldsigpipe)(int); 31 + Glyph *bp, *end; 32 + int lastpos, n, newline; 33 + 34 + if (pipe(to) == -1) 35 + return; 36 + 37 + switch (fork()) { 38 + case -1: 39 + close(to[0]); 40 + close(to[1]); 41 + return; 42 + case 0: 43 + dup2(to[0], STDIN_FILENO); 44 + close(to[0]); 45 + close(to[1]); 46 + execvp(((char **)arg->v)[0], (char **)arg->v); 47 + fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]); 48 + perror("failed"); 49 + exit(0); 50 + } 51 + 52 + close(to[0]); 53 + /* ignore sigpipe for now, in case child exists early */ 54 + oldsigpipe = signal(SIGPIPE, SIG_IGN); 55 + newline = 0; 56 + for (n = 0; n < term.row; n++) { 57 + bp = term.line[n]; 58 + lastpos = MIN(tlinelen(n) + 1, term.col) - 1; 59 + if (lastpos < 0) 60 + break; 61 + end = &bp[lastpos + 1]; 62 + for (; bp < end; ++bp) 63 + if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) 64 + break; 65 + if ((newline = term.line[n][lastpos].mode & ATTR_WRAP)) 66 + continue; 67 + if (xwrite(to[1], "\n", 1) < 0) 68 + break; 69 + newline = 0; 70 + } 71 + if (newline) 72 + (void)xwrite(to[1], "\n", 1); 73 + close(to[1]); 74 + /* restore */ 75 + signal(SIGPIPE, oldsigpipe); 76 +} 77 + 78 void 79 strdump(void) 80 { 81 diff --git a/st.h b/st.h 82 index 3d351b6..392b64e 100644 83 --- a/st.h 84 +++ b/st.h 85 @@ -81,6 +81,7 @@ void die(const char *, ...); 86 void redraw(void); 87 void draw(void); 88 89 +void externalpipe(const Arg *); 90 void printscreen(const Arg *); 91 void printsel(const Arg *); 92 void sendbreak(const Arg *);