st-externalpipe-0.4.1.diff (2070B)
1 diff --git a/st.c b/st.c 2 index 686ed5d..697cd43 100644 3 --- a/st.c 4 +++ b/st.c 5 @@ -249,6 +249,7 @@ typedef union { 6 unsigned int ui; 7 float f; 8 const void *v; 9 + const char *s; 10 } Arg; 11 12 typedef struct { 13 @@ -263,6 +264,7 @@ static void clippaste(const Arg *); 14 static void numlock(const Arg *); 15 static void selpaste(const Arg *); 16 static void xzoom(const Arg *); 17 +static void externalpipe(const Arg *); 18 19 /* Config.h for applying patches and the configuration. */ 20 #include "config.h" 21 @@ -1024,15 +1026,22 @@ execsh(void) { 22 void 23 sigchld(int a) { 24 int stat = 0; 25 + pid_t r; 26 27 - if(waitpid(pid, &stat, 0) < 0) 28 - die("Waiting for pid %hd failed: %s\n", pid, SERRNO); 29 + r = wait(&stat); 30 + if(r < 0) 31 + die("wait(): %s\n", SERRNO); 32 33 - if(WIFEXITED(stat)) { 34 - exit(WEXITSTATUS(stat)); 35 - } else { 36 - exit(EXIT_FAILURE); 37 + if(r == pid){ 38 + /* _the_ sub process */ 39 + if(WIFEXITED(stat)) { 40 + exit(WEXITSTATUS(stat)); 41 + } else { 42 + exit(EXIT_FAILURE); 43 + } 44 } 45 + 46 + /* something else we've forked out */ 47 } 48 49 void 50 @@ -2593,6 +2602,59 @@ xzoom(const Arg *arg) { 51 } 52 53 void 54 +externalpipe(const Arg *arg) 55 +{ 56 + int to[2]; /* 0 = read, 1 = write */ 57 + pid_t child; 58 + int y, x; 59 + void (*oldsigpipe)(int); 60 + 61 + if(pipe(to) == -1) 62 + return; 63 + 64 + /* sigchld() handles this */ 65 + switch((child = fork())){ 66 + case -1: 67 + close(to[0]), close(to[1]); 68 + return; 69 + case 0: 70 + /* child */ 71 + close(to[1]); 72 + dup2(to[0], STDIN_FILENO); /* 0<&to */ 73 + close(to[0]); 74 + execvp( 75 + "sh", 76 + (char *const []){ 77 + "/bin/sh", 78 + "-c", 79 + (char *)arg->s, 80 + 0 81 + }); 82 + exit(127); 83 + } 84 + 85 + /* parent */ 86 + close(to[0]); 87 + /* ignore sigpipe for now, in case child exits early */ 88 + oldsigpipe = signal(SIGPIPE, SIG_IGN); 89 + 90 + for(y = 0; y < term.row; y++){ 91 + for(x = 0; x < term.col; x++){ 92 + if(write(to[1], term.line[y][x].c, 1) == -1) 93 + goto done; 94 + } 95 + if(write(to[1], "\n", 1) == -1) 96 + break; 97 + } 98 + 99 +done: 100 + close(to[1]); 101 + 102 + /* restore */ 103 + signal(SIGPIPE, oldsigpipe); 104 +} 105 + 106 +void 107 xinit(void) { 108 XSetWindowAttributes attrs; 109 XGCValues gcvalues;