Wait for the child process to surface the exit status.
Patch status: needinfo
Patch by Wael M. Nasreddine
To apply this patch, use:
curl http://cr.i3wm.org/patch/625/raw.patch | git am
b/i3lock.c
13 |
@@ -6,6 +6,7 @@ |
14 |
* See LICENSE for licensing information |
15 |
* |
16 |
*/ |
17 |
+#include <sys/wait.h> |
18 |
#include <stdio.h> |
19 |
#include <stdlib.h> |
20 |
#include <string.h> |
21 |
@@ -514,7 +515,7 @@ static int conv_callback(int num_msg, const struct pam_message **msg, |
22 |
* See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop |
23 |
* |
24 |
*/ |
25 |
-static void xcb_got_event(EV_P_ struct ev_io *w, int revents) { |
26 |
+static void xcb_got_event(EV_P_ struct ev_io *xcb, int revents) { |
27 |
/* empty, because xcb_prepare_cb and xcb_check_cb are used */ |
28 |
} |
29 |
|
30 |
@@ -522,7 +523,7 @@ static void xcb_got_event(EV_P_ struct ev_io *w, int revents) { |
31 |
* Flush before blocking (and waiting for new events) |
32 |
* |
33 |
*/ |
34 |
-static void xcb_prepare_cb(EV_P_ ev_prepare *w, int revents) { |
35 |
+static void xcb_prepare_cb(EV_P_ ev_prepare *xcb, int revents) { |
36 |
xcb_flush(conn); |
37 |
} |
38 |
|
39 |
@@ -531,7 +532,10 @@ static void xcb_prepare_cb(EV_P_ ev_prepare *w, int revents) { |
40 |
* xcb_poll_for_event() which knows better than we can ever know. |
41 |
* |
42 |
*/ |
43 |
-static void xcb_check_cb(EV_P_ ev_check *w, int revents) { |
44 |
+static void xcb_check_cb(EV_P_ ev_check *xcb, int revents) { |
45 |
+ pid_t cpid, w; |
46 |
+ int status; |
47 |
+ |
48 |
xcb_generic_event_t *event; |
49 |
|
50 |
while ((event = xcb_poll_for_event(conn)) != NULL) { |
51 |
@@ -571,11 +575,22 @@ static void xcb_check_cb(EV_P_ ev_check *w, int revents) { |
52 |
* expect to get another MapNotify, but better be sureā¦ */ |
53 |
dont_fork = true; |
54 |
|
55 |
- /* In the parent process, we exit */ |
56 |
- if (fork() != 0) |
57 |
- exit(0); |
58 |
+ cpid = fork(); |
59 |
+ if (cpid == -1) |
60 |
+ errx(EXIT_FAILURE, "Couldn't fork."); |
61 |
+ |
62 |
+ if (cpid == 0) { // Code execured by the child |
63 |
+ ev_loop_fork(EV_DEFAULT); |
64 |
+ } else { // Code execured by the parent |
65 |
+ do { |
66 |
+ w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); |
67 |
+ |
68 |
+ if (w == -1) |
69 |
+ errx(EXIT_FAILURE, "Couldn't wait for the child."); |
70 |
+ } while (!WIFEXITED(status) && !WIFSIGNALED(status)); |
71 |
|
72 |
- ev_loop_fork(EV_DEFAULT); |
73 |
+ exit(EXIT_SUCCESS); |
74 |
+ } |
75 |
} |
76 |
break; |
77 |
|