xwayland: Clean up display finding code

Split out and make it more manageable.
This commit is contained in:
Jasper St. Pierre 2014-04-17 15:03:45 -04:00
parent e5ab4f13f1
commit 72b1a2837d

View File

@ -121,72 +121,100 @@ meta_xwayland_handle_wl_surface_id (MetaWindow *window,
} }
} }
static char * static gboolean
create_lockfile (int display, int *display_out) try_display (int display,
char **filename_out,
int *fd_out)
{ {
gboolean ret = FALSE;
char *filename; char *filename;
int size;
char pid[11];
int fd; int fd;
do
{
char *end;
pid_t other;
filename = g_strdup_printf ("/tmp/.X%d-lock", display); filename = g_strdup_printf ("/tmp/.X%d-lock", display);
again:
fd = open (filename, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444); fd = open (filename, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444);
if (fd < 0 && errno == EEXIST) if (fd < 0 && errno == EEXIST)
{ {
char pid[11];
char *end;
pid_t other;
fd = open (filename, O_CLOEXEC, O_RDONLY); fd = open (filename, O_CLOEXEC, O_RDONLY);
if (fd < 0 || read (fd, pid, 11) != 11) if (fd < 0 || read (fd, pid, 11) != 11)
{ {
g_warning ("can't read lock file %s: %m", filename); g_warning ("can't read lock file %s: %m", filename);
g_free (filename); goto out;
/* ignore error and try the next display number */
display++;
continue;
} }
close (fd); close (fd);
fd = -1;
other = strtol (pid, &end, 0); other = strtol (pid, &end, 0);
if (end != pid + 10) if (end != pid + 10)
{ {
g_warning ("can't parse lock file %s", filename); g_warning ("can't parse lock file %s", filename);
g_free (filename); goto out;
/* ignore error and try the next display number */
display++;
continue;
} }
if (kill (other, 0) < 0 && errno == ESRCH) if (kill (other, 0) < 0 && errno == ESRCH)
{ {
/* Process is dead. Try unlinking the lockfile and trying again. */
if (unlink (filename) < 0) if (unlink (filename) < 0)
{ {
g_warning ("failed to unlink stale lock file %s: %m", filename); g_warning ("failed to unlink stale lock file %s: %m", filename);
display++; goto out;
}
g_free (filename);
continue;
} }
g_free (filename); goto again;
display++; }
continue;
goto out;
} }
else if (fd < 0) else if (fd < 0)
{ {
g_warning ("failed to create lock file %s: %m", filename); g_warning ("failed to create lock file %s: %m", filename);
g_free (filename); goto out;
return NULL;
} }
break; ret = TRUE;
out:
if (!ret)
{
g_free (filename);
filename = NULL;
if (fd >= 0)
{
close (fd);
fd = -1;
}
}
*filename_out = filename;
*fd_out = fd;
return ret;
}
static char *
create_lockfile (int display, int *display_out)
{
char *filename;
int fd;
char pid[11];
int size;
while (!try_display (display, &filename, &fd))
{
display++;
/* If display is above 50, then something's wrong. Just
* abort in this case. */
if (display > 50)
return NULL;
} }
while (1);
/* Subtle detail: we use the pid of the wayland compositor, not the xserver /* Subtle detail: we use the pid of the wayland compositor, not the xserver
* in the lock file. */ * in the lock file. */