summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2011-08-11 17:48:38 -0400
committerKristian Høgsberg <krh@bitplanet.net>2011-08-11 17:48:38 -0400
commitf6ee69580545c214fb729d5169b98493be0405ce (patch)
tree74e9b03cdb05531ce85d3488b9aa7d29c03b8411
parent534222b4d92012261aec6ae32c3aba3894c6d00b (diff)
xserver: Clean up lockfile creation a bit
-rw-r--r--compositor/xserver-launcher.c139
1 files 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);