st-externalpipe-0.5.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
st-externalpipe-0.5.diff (2100B) | |
--- | |
1 diff --git a/st.c b/st.c | |
2 index 392f12d..31660c8 100644 | |
3 --- a/st.c | |
4 +++ b/st.c | |
5 @@ -301,6 +301,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 @@ -315,6 +316,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 static void printsel(const Arg *); | |
19 static void printscreen(const Arg *) ; | |
20 static void toggleprinter(const Arg *); | |
21 @@ -1179,15 +1181,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", strerror(errno)); | |
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 @@ -2982,6 +2991,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 XGCValues gcvalues; | |
109 Cursor cursor; |