commit dcdbc16

Michael Forney  ·  2014-08-01 01:35:55 +0000 UTC
parent 2e37a44
xserver: Handle stale lockfiles
1 files changed,  +30, -4
+30, -4
 1@@ -63,6 +63,10 @@ static int open_socket(struct sockaddr_un * addr, size_t path_size)
 2     if ((fd = socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
 3         goto error0;
 4 
 5+    /* Unlink the socket location in case it was being used by a process which
 6+     * left around a stale lockfile. */
 7+    unlink(addr->sun_path);
 8+
 9     if (bind(fd, (struct sockaddr *) addr, size) < 0)
10         goto error1;
11 
12@@ -107,12 +111,34 @@ static bool open_display()
13     snprintf(lock_name, sizeof lock_name, LOCK_FMT, xserver.display);
14     lock_fd = open(lock_name, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0444);
15 
16-    /* XXX: Stale lockfile handling? */
17-    if (lock_fd < 0)
18-        goto retry0;
19+    if (lock_fd == -1)
20+    {
21+        char * end;
22+        pid_t owner;
23+
24+        /* Check if the owning process is still alive. */
25+        if ((lock_fd = open(lock_name, O_RDONLY)) == -1)
26+            goto retry0;
27+
28+        if (read(lock_fd, pid, sizeof pid - 1) != sizeof pid - 1)
29+            goto retry0;
30+
31+        owner = strtol(pid, &end, 10);
32+
33+        if (end != pid + 10)
34+            goto retry0;
35+
36+        if (kill(owner, 0) == 0 || errno != ESRCH)
37+            goto retry0;
38+
39+        if (unlink(lock_name) != 0)
40+            goto retry0;
41+
42+        goto begin;
43+    }
44 
45     snprintf(pid, sizeof pid, "%10d\n", getpid());
46-    if (write(lock_fd, pid, sizeof pid) != sizeof pid)
47+    if (write(lock_fd, pid, sizeof pid - 1) != sizeof pid - 1)
48     {
49         ERROR("Failed to write PID file\n");
50         unlink(lock_name);