From f6ee69580545c214fb729d5169b98493be0405ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 11 Aug 2011 17:48:38 -0400 Subject: [PATCH] xserver: Clean up lockfile creation a bit --- compositor/xserver-launcher.c | 139 +++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 60 deletions(-) diff --git a/compositor/xserver-launcher.c b/compositor/xserver-launcher.c index a5e66299..02f022a3 100644 --- a/compositor/xserver-launcher.c +++ b/compositor/xserver-launcher.c @@ -648,14 +648,69 @@ bind_to_unix_socket(int display) return fd; } +static int +create_lockfile(int display, char *lockfile, size_t lsize) +{ + char pid[16], *end; + int fd, size; + pid_t other; + + snprintf(lockfile, lsize, "/tmp/.X%d-lock", display); + fd = open(lockfile, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444); + if (fd < 0 && errno == EEXIST) { + fd = open(lockfile, O_CLOEXEC, O_RDONLY); + if (fd < 0 || read(fd, pid, 11) != 11) { + fprintf(stderr, "can't read lock file %s: %s\n", + lockfile, strerror(errno)); + errno = EEXIST; + return -1; + } + + other = strtol(pid, &end, 0); + if (end != pid + 10) { + fprintf(stderr, "can't parse lock file %s\n", + lockfile); + errno = EEXIST; + return -1; + } + + if (kill(other, 0) < 0 && errno == ESRCH) { + /* stale lock file; unlink and try again */ + fprintf(stderr, + "unlinking stale lock file %s\n", lockfile); + unlink(lockfile); + errno = EAGAIN; + return -1; + } + + errno = EEXIST; + return -1; + } else if (fd < 0) { + fprintf(stderr, "failed to create lock file %s: %s\n", + lockfile, strerror(errno)); + return -1; + } + + /* Subtle detail: we use the pid of the wayland + * compositor, not the xserver in the lock file. */ + size = snprintf(pid, sizeof pid, "%10d\n", getpid()); + if (write(fd, pid, size) != size) { + unlink(lockfile); + close(fd); + return -1; + } + + close(fd); + + return 0; +} + int wlsc_xserver_init(struct wlsc_compositor *compositor) { struct wl_display *display = compositor->wl_display; struct wlsc_xserver *mxs; - char lockfile[256], pid[16], *end; - pid_t other; - int fd, size; + char lockfile[256]; mxs = malloc(sizeof *mxs); memset(mxs, 0, sizeof *mxs); @@ -664,70 +719,34 @@ wlsc_xserver_init(struct wlsc_compositor *compositor) mxs->wl_display = display; mxs->display = 0; - do { - snprintf(lockfile, sizeof lockfile, - "/tmp/.X%d-lock", mxs->display); - fd = open(lockfile, - O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444); - if (fd < 0 && errno == EEXIST) { - fd = open(lockfile, O_CLOEXEC, O_RDONLY); - if (fd < 0 || read(fd, pid, 11) != 11) { - fprintf(stderr, - "can't read lock file %s: %s\n", - lockfile, strerror(errno)); - mxs->display++; - continue; - } - - other = strtol(pid, &end, 0); - if (end != pid + 10) { - fprintf(stderr, "can't parse lock file %s\n", - lockfile); - mxs->display++; - continue; - } - - if (kill(other, 0) < 0 && errno == ESRCH) { - /* stale lock file; unlink and try again */ - fprintf(stderr, - "unlinking stale lock file %s\n", - lockfile); - unlink(lockfile); - continue; - } + retry: + if (create_lockfile(mxs->display, lockfile, sizeof lockfile) < 0) { + if (errno == EAGAIN) { + goto retry; + } else if (errno == EEXIST) { mxs->display++; - continue; - } else if (fd < 0) { - fprintf(stderr, "failed to create lock file %s: %s\n", - lockfile, strerror(errno)); + goto retry; + } else { free(mxs); return -1; } + } - /* Subtle detail: we use the pid of the wayland - * compositor, not the xserver in the lock file. */ - size = snprintf(pid, sizeof pid, "%10d\n", getpid()); - write(fd, pid, size); - close(fd); - - mxs->abstract_fd = bind_to_abstract_socket(mxs->display); - if (mxs->abstract_fd < 0 && errno == EADDRINUSE) { - mxs->display++; - unlink(lockfile); - continue; - } - - mxs->unix_fd = bind_to_unix_socket(mxs->display); - if (mxs->unix_fd < 0) { - unlink(lockfile); - close(mxs->abstract_fd); - free(mxs); - return -1; - } + mxs->abstract_fd = bind_to_abstract_socket(mxs->display); + if (mxs->abstract_fd < 0 && errno == EADDRINUSE) { + mxs->display++; + unlink(lockfile); + goto retry; + } - break; - } while (errno != 0); + mxs->unix_fd = bind_to_unix_socket(mxs->display); + if (mxs->unix_fd < 0) { + unlink(lockfile); + close(mxs->abstract_fd); + free(mxs); + return -1; + } fprintf(stderr, "xserver listening on display :%d\n", mxs->display);