i3 - improved tiling WM


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
 }