i3bar: Don't start child unless status_command
Patch status: merged
Patch by Tony Crisci
Long description:
If a command is passed to `start_child` which is NULL, such as in the case when there is no `status_command` specified in the bar config, do not start a child process to listen on stdin. fixes #1140
To apply this patch, use:
curl http://cr.i3wm.org/patch/355/raw.patch | git am
b/i3bar/src/child.c
20 |
@@ -452,10 +452,16 @@ void child_write_output(void) { |
21 |
/* |
22 |
* Start a child-process with the specified command and reroute stdin. |
23 |
* We actually start a $SHELL to execute the command so we don't have to care |
24 |
- * about arguments and such |
25 |
+ * about arguments and such. |
26 |
+ * |
27 |
+ * If `command' is NULL, such as in the case when no `status_command' is given |
28 |
+ * in the bar config, no child will be started. |
29 |
* |
30 |
*/ |
31 |
void start_child(char *command) { |
32 |
+ if (command == NULL) |
33 |
+ return; |
34 |
+ |
35 |
/* Allocate a yajl parser which will be used to parse stdin. */ |
36 |
memset(&callbacks, '\0', sizeof(yajl_callbacks)); |
37 |
callbacks.yajl_map_key = stdin_map_key; |
38 |
@@ -478,43 +484,41 @@ void start_child(char *command) { |
39 |
gen = yajl_gen_alloc(NULL); |
40 |
#endif |
41 |
|
42 |
- if (command != NULL) { |
43 |
- int pipe_in[2]; /* pipe we read from */ |
44 |
- int pipe_out[2]; /* pipe we write to */ |
45 |
+ int pipe_in[2]; /* pipe we read from */ |
46 |
+ int pipe_out[2]; /* pipe we write to */ |
47 |
|
48 |
- if (pipe(pipe_in) == -1) |
49 |
- err(EXIT_FAILURE, "pipe(pipe_in)"); |
50 |
- if (pipe(pipe_out) == -1) |
51 |
- err(EXIT_FAILURE, "pipe(pipe_out)"); |
52 |
+ if (pipe(pipe_in) == -1) |
53 |
+ err(EXIT_FAILURE, "pipe(pipe_in)"); |
54 |
+ if (pipe(pipe_out) == -1) |
55 |
+ err(EXIT_FAILURE, "pipe(pipe_out)"); |
56 |
|
57 |
- child.pid = fork(); |
58 |
- switch (child.pid) { |
59 |
- case -1: |
60 |
- ELOG("Couldn't fork(): %s\n", strerror(errno)); |
61 |
- exit(EXIT_FAILURE); |
62 |
- case 0: |
63 |
- /* Child-process. Reroute streams and start shell */ |
64 |
+ child.pid = fork(); |
65 |
+ switch (child.pid) { |
66 |
+ case -1: |
67 |
+ ELOG("Couldn't fork(): %s\n", strerror(errno)); |
68 |
+ exit(EXIT_FAILURE); |
69 |
+ case 0: |
70 |
+ /* Child-process. Reroute streams and start shell */ |
71 |
|
72 |
- close(pipe_in[0]); |
73 |
- close(pipe_out[1]); |
74 |
+ close(pipe_in[0]); |
75 |
+ close(pipe_out[1]); |
76 |
|
77 |
- dup2(pipe_in[1], STDOUT_FILENO); |
78 |
- dup2(pipe_out[0], STDIN_FILENO); |
79 |
+ dup2(pipe_in[1], STDOUT_FILENO); |
80 |
+ dup2(pipe_out[0], STDIN_FILENO); |
81 |
|
82 |
- setpgid(child.pid, 0); |
83 |
- execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (char*) NULL); |
84 |
- return; |
85 |
- default: |
86 |
- /* Parent-process. Reroute streams */ |
87 |
+ setpgid(child.pid, 0); |
88 |
+ execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (char*) NULL); |
89 |
+ return; |
90 |
+ default: |
91 |
+ /* Parent-process. Reroute streams */ |
92 |
|
93 |
- close(pipe_in[1]); |
94 |
- close(pipe_out[0]); |
95 |
+ close(pipe_in[1]); |
96 |
+ close(pipe_out[0]); |
97 |
|
98 |
- dup2(pipe_in[0], STDIN_FILENO); |
99 |
- child_stdin = pipe_out[1]; |
100 |
+ dup2(pipe_in[0], STDIN_FILENO); |
101 |
+ child_stdin = pipe_out[1]; |
102 |
|
103 |
- break; |
104 |
- } |
105 |
+ break; |
106 |
} |
107 |
|
108 |
/* We set O_NONBLOCK because blocking is evil in event-driven software */ |
b/i3bar/src/config.c
113 |
@@ -127,10 +127,6 @@ static int config_string_cb(void *params_, const unsigned char *val, unsigned in |
114 |
} |
115 |
|
116 |
if (!strcmp(cur_key, "status_command")) { |
117 |
- /* We cannot directly start the child here, because start_child() also |
118 |
- * needs to be run when no command was specified (to setup stdin). |
119 |
- * Therefore we save the command in 'config' and access it later in |
120 |
- * got_bar_config() */ |
121 |
DLOG("command = %.*s\n", len, val); |
122 |
sasprintf(&config.command, "%.*s", len, val); |
123 |
return 1; |
b/i3bar/src/ipc.c
128 |
@@ -100,9 +100,6 @@ void got_bar_config(char *reply) { |
129 |
/* Resolve color strings to colorpixels and save them, then free the strings. */ |
130 |
init_colors(&(config.colors)); |
131 |
|
132 |
- /* The name of this function is actually misleading. Even if no command is |
133 |
- * specified, this function initiates the watchers to listen on stdin and |
134 |
- * react accordingly */ |
135 |
start_child(config.command); |
136 |
FREE(config.command); |
137 |
} |