summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2011-07-15 20:14:57 -0400
committerKristian Høgsberg <krh@bitplanet.net>2011-07-15 20:14:57 -0400
commitfcf6577108b1047e1360958004a32e9ab994c758 (patch)
treebdfe5524dc36bd7bf270877ad380ada81123b152
parentd6520e144a344493ee0819beb675540f625abb96 (diff)
downloadweston-fcf6577108b1047e1360958004a32e9ab994c758.tar.gz
xserver: Detect an clean up stale lock file
-rw-r--r--compositor/xserver-launcher.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/compositor/xserver-launcher.c b/compositor/xserver-launcher.c
index 61ffc09a..c11f4106 100644
--- a/compositor/xserver-launcher.c
+++ b/compositor/xserver-launcher.c
@@ -30,6 +30,7 @@
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
+#include <signal.h>
#include <xcb/xcb.h>
@@ -551,8 +552,9 @@ int
wlsc_xserver_init(struct wl_display *display)
{
struct wlsc_xserver *mxs;
- char lockfile[256], pid[16];
+ char lockfile[256], pid[16], *end;
socklen_t size, name_size;
+ pid_t other;
int fd;
mxs = malloc(sizeof *mxs);
@@ -574,15 +576,44 @@ wlsc_xserver_init(struct wl_display *display)
fd = open(lockfile,
O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444);
if (fd < 0 && errno == EEXIST) {
- fprintf(stderr, "server %d exists\n", mxs->display);
+ 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;
+ }
+
mxs->display++;
continue;
} else if (fd < 0) {
+ fprintf(stderr, "failed to create lock file %s: %s\n",
+ lockfile, strerror(errno));
close(mxs->fd);
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);
@@ -591,9 +622,10 @@ wlsc_xserver_init(struct wl_display *display)
sizeof mxs->addr.sun_path,
"/tmp/.X11-unix/X%d", mxs->display) + 1;
size = offsetof(struct sockaddr_un, sun_path) + name_size;
+ unlink(mxs->addr.sun_path);
if (bind(mxs->fd, (struct sockaddr *) &mxs->addr, size) < 0) {
- fprintf(stderr, "failed to bind to %s (%m)\n",
- mxs->addr.sun_path);
+ fprintf(stderr, "failed to bind to %s (%s)\n",
+ mxs->addr.sun_path, strerror(errno));
unlink(lockfile);
close(mxs->fd);
free(mxs);
@@ -602,7 +634,7 @@ wlsc_xserver_init(struct wl_display *display)
break;
} while (errno != 0);
- fprintf(stderr, "listening on display %d\n", mxs->display);
+ fprintf(stderr, "xserver listening on display :%d\n", mxs->display);
if (listen(mxs->fd, 1) < 0) {
unlink(mxs->addr.sun_path);