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>
This commit is contained in:
parent
f706972309
commit
29aed56ec7
|
@ -60,6 +60,15 @@ usage(int argc, char **argv)
|
||||||
exit(1);
|
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. */
|
/* Starts the X server, returning its pid. */
|
||||||
static int
|
static int
|
||||||
start_server(char *const *server_args)
|
start_server(char *const *server_args)
|
||||||
|
@ -71,6 +80,17 @@ start_server(char *const *server_args)
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (server_pid != 0) {
|
} else if (server_pid != 0) {
|
||||||
/* Continue along the main process that will exec the client. */
|
/* 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;
|
return server_pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +104,7 @@ start_server(char *const *server_args)
|
||||||
static int
|
static int
|
||||||
get_display(int displayfd)
|
get_display(int displayfd)
|
||||||
{
|
{
|
||||||
char display_string[10];
|
char display_string[20];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
ret = read(displayfd, display_string, sizeof(display_string) - 1);
|
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.
|
* '\n', but not '\0'. Cap it and parse the number.
|
||||||
*/
|
*/
|
||||||
display_string[ret] = '\0';
|
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);
|
return atoi(display_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +248,8 @@ main(int argc, char **argv)
|
||||||
exit(1);
|
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);
|
server_pid = start_server(server_args);
|
||||||
display = get_display(displayfd_pipe[0]);
|
display = get_display(displayfd_pipe[0]);
|
||||||
ret = start_client(client_args, display);
|
ret = start_client(client_args, display);
|
||||||
|
|
Loading…
Reference in New Issue