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 |
} |