st-externalpipe-0.4.1.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
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;