xserver: Clean up lockfile creation a bit

dev
Kristian Høgsberg 14 years ago
parent 534222b4d9
commit f6ee695805
  1. 89
      compositor/xserver-launcher.c

@ -648,74 +648,96 @@ bind_to_unix_socket(int display)
return fd; return fd;
} }
int static int
wlsc_xserver_init(struct wlsc_compositor *compositor) create_lockfile(int display, char *lockfile, size_t lsize)
{ {
struct wl_display *display = compositor->wl_display; char pid[16], *end;
struct wlsc_xserver *mxs;
char lockfile[256], pid[16], *end;
pid_t other;
int fd, size; int fd, size;
pid_t other;
mxs = malloc(sizeof *mxs); snprintf(lockfile, lsize, "/tmp/.X%d-lock", display);
memset(mxs, 0, sizeof *mxs); fd = open(lockfile, O_WRONLY | O_CLOEXEC | O_CREAT | O_EXCL, 0444);
mxs->process.cleanup = wlsc_xserver_cleanup;
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) { if (fd < 0 && errno == EEXIST) {
fd = open(lockfile, O_CLOEXEC, O_RDONLY); fd = open(lockfile, O_CLOEXEC, O_RDONLY);
if (fd < 0 || read(fd, pid, 11) != 11) { if (fd < 0 || read(fd, pid, 11) != 11) {
fprintf(stderr, fprintf(stderr, "can't read lock file %s: %s\n",
"can't read lock file %s: %s\n",
lockfile, strerror(errno)); lockfile, strerror(errno));
mxs->display++; errno = EEXIST;
continue; return -1;
} }
other = strtol(pid, &end, 0); other = strtol(pid, &end, 0);
if (end != pid + 10) { if (end != pid + 10) {
fprintf(stderr, "can't parse lock file %s\n", fprintf(stderr, "can't parse lock file %s\n",
lockfile); lockfile);
mxs->display++; errno = EEXIST;
continue; return -1;
} }
if (kill(other, 0) < 0 && errno == ESRCH) { if (kill(other, 0) < 0 && errno == ESRCH) {
/* stale lock file; unlink and try again */ /* stale lock file; unlink and try again */
fprintf(stderr, fprintf(stderr,
"unlinking stale lock file %s\n", "unlinking stale lock file %s\n", lockfile);
lockfile);
unlink(lockfile); unlink(lockfile);
continue; errno = EAGAIN;
return -1;
} }
mxs->display++; errno = EEXIST;
continue; return -1;
} else if (fd < 0) { } else if (fd < 0) {
fprintf(stderr, "failed to create lock file %s: %s\n", fprintf(stderr, "failed to create lock file %s: %s\n",
lockfile, strerror(errno)); lockfile, strerror(errno));
free(mxs);
return -1; return -1;
} }
/* Subtle detail: we use the pid of the wayland /* Subtle detail: we use the pid of the wayland
* compositor, not the xserver in the lock file. */ * compositor, not the xserver in the lock file. */
size = snprintf(pid, sizeof pid, "%10d\n", getpid()); size = snprintf(pid, sizeof pid, "%10d\n", getpid());
write(fd, pid, size); if (write(fd, pid, size) != size) {
unlink(lockfile);
close(fd); 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];
mxs = malloc(sizeof *mxs);
memset(mxs, 0, sizeof *mxs);
mxs->process.cleanup = wlsc_xserver_cleanup;
mxs->wl_display = display;
mxs->display = 0;
retry:
if (create_lockfile(mxs->display, lockfile, sizeof lockfile) < 0) {
if (errno == EAGAIN) {
goto retry;
} else if (errno == EEXIST) {
mxs->display++;
goto retry;
} else {
free(mxs);
return -1;
}
}
mxs->abstract_fd = bind_to_abstract_socket(mxs->display); mxs->abstract_fd = bind_to_abstract_socket(mxs->display);
if (mxs->abstract_fd < 0 && errno == EADDRINUSE) { if (mxs->abstract_fd < 0 && errno == EADDRINUSE) {
mxs->display++; mxs->display++;
unlink(lockfile); unlink(lockfile);
continue; goto retry;
} }
mxs->unix_fd = bind_to_unix_socket(mxs->display); mxs->unix_fd = bind_to_unix_socket(mxs->display);
@ -726,9 +748,6 @@ wlsc_xserver_init(struct wlsc_compositor *compositor)
return -1; return -1;
} }
break;
} while (errno != 0);
fprintf(stderr, "xserver listening on display :%d\n", mxs->display); fprintf(stderr, "xserver listening on display :%d\n", mxs->display);
mxs->loop = wl_display_get_event_loop(display); mxs->loop = wl_display_get_event_loop(display);

Loading…
Cancel
Save