xwayland: Avoid late errno checks

We do some things when binding to a socket fails (closing the fd,
logging, unlinking files, ...) those might affect errno in some
or other way, so it might no longer be EADDRINUSE even if we later
try to make those non fatal.

It seems better to check errno soon after the failure, and don't
rely on it in any way at a later point. All error paths in
bind_to_abstract_socket() also have early logging, which also might
help figure out better the point of failure when the socket fails
to be created.

https://bugzilla.gnome.org/show_bug.cgi?id=769578
This commit is contained in:
Carlos Garnacho 2016-08-06 16:17:33 +02:00
parent dd549604e2
commit 5c9a2c54c4

View File

@ -299,7 +299,8 @@ create_lock_file (int display, int *display_out)
}
static int
bind_to_abstract_socket (int display)
bind_to_abstract_socket (int display,
gboolean *fatal)
{
struct sockaddr_un addr;
socklen_t size, name_size;
@ -307,7 +308,11 @@ bind_to_abstract_socket (int display)
fd = socket (PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd < 0)
{
*fatal = TRUE;
g_warning ("Failed to create socket: %m");
return -1;
}
addr.sun_family = AF_LOCAL;
name_size = snprintf (addr.sun_path, sizeof addr.sun_path,
@ -315,6 +320,7 @@ bind_to_abstract_socket (int display)
size = offsetof (struct sockaddr_un, sun_path) + name_size;
if (bind (fd, (struct sockaddr *) &addr, size) < 0)
{
*fatal = errno != EADDRINUSE;
g_warning ("failed to bind to @%s: %m", addr.sun_path + 1);
close (fd);
return -1;
@ -322,6 +328,9 @@ bind_to_abstract_socket (int display)
if (listen (fd, 1) < 0)
{
*fatal = errno != EADDRINUSE;
g_warning ("Failed to listen on abstract socket @%s: %m",
addr.sun_path + 1);
close (fd);
return -1;
}
@ -394,6 +403,7 @@ choose_xdisplay (MetaXWaylandManager *manager)
{
int display = 0;
char *lock_file = NULL;
gboolean fatal = FALSE;
/* Hack to keep the unused Xwayland instance on
* the login screen from taking the prime :0 display
@ -411,19 +421,22 @@ choose_xdisplay (MetaXWaylandManager *manager)
return FALSE;
}
manager->abstract_fd = bind_to_abstract_socket (display);
manager->abstract_fd = bind_to_abstract_socket (display, &fatal);
if (manager->abstract_fd < 0)
{
unlink (lock_file);
if (errno == EADDRINUSE)
if (!fatal)
{
display++;
continue;
}
else
{
g_warning ("Failed to bind abstract socket");
return FALSE;
}
}
manager->unix_fd = bind_to_unix_socket (display);
if (manager->unix_fd < 0)