summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2019-03-26 12:26:34 -0700
committerEric Anholt <eric@anholt.net>2019-03-27 09:50:19 -0700
commit29aed56ec72d2e95dba8975eb44f385a5f6ef1ff (patch)
tree1f277a842c6d945634a31a95a3781fb540e644cf /test
parentf7069723093de585d082cfd98f0191d163569a78 (diff)
downloadxserver-29aed56ec72d2e95dba8975eb44f385a5f6ef1ff.tar.gz
simple-xinit: Avoid hanging if the server fails to set up the display fd.
Early fatal errors may leave us with nothing in the displayfd pipe, and we'd block forever. Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'test')
-rw-r--r--test/simple-xinit.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/test/simple-xinit.c b/test/simple-xinit.c
index 26ff12bf7..a80eb9cf5 100644
--- a/test/simple-xinit.c
+++ b/test/simple-xinit.c
@@ -60,6 +60,15 @@ usage(int argc, char **argv)
exit(1);
}
+static int server_displayfd;
+static const char *server_dead = "server_dead";
+
+static void
+handle_sigchld(int sig)
+{
+ write(server_displayfd, server_dead, strlen(server_dead));
+}
+
/* Starts the X server, returning its pid. */
static int
start_server(char *const *server_args)
@@ -71,6 +80,17 @@ start_server(char *const *server_args)
exit(1);
} else if (server_pid != 0) {
/* Continue along the main process that will exec the client. */
+
+ struct sigaction sa;
+ sa.sa_handler = handle_sigchld;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
+ if (sigaction(SIGCHLD, &sa, 0) == -1) {
+ fprintf(stderr, "Failed to set up signal handler: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
return server_pid;
}
@@ -84,7 +104,7 @@ start_server(char *const *server_args)
static int
get_display(int displayfd)
{
- char display_string[10];
+ char display_string[20];
ssize_t ret;
ret = read(displayfd, display_string, sizeof(display_string) - 1);
@@ -97,6 +117,12 @@ get_display(int displayfd)
* '\n', but not '\0'. Cap it and parse the number.
*/
display_string[ret] = '\0';
+
+ if (strncmp(display_string, server_dead, strlen(server_dead)) == 0) {
+ fprintf(stderr, "Server failed to start before setting up displayfd\n");
+ exit(1);
+ }
+
return atoi(display_string);
}
@@ -222,7 +248,8 @@ main(int argc, char **argv)
exit(1);
}
- parse_args(argc, argv, &client_args, &server_args, displayfd_pipe[1]);
+ server_displayfd = displayfd_pipe[1];
+ parse_args(argc, argv, &client_args, &server_args, server_displayfd);
server_pid = start_server(server_args);
display = get_display(displayfd_pipe[0]);
ret = start_client(client_args, display);