1 /* SPDX-License-Identifier: MIT OR X11
3 * Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
7 Copyright 1987, 1998 The Open Group
9 Permission to use, copy, modify, distribute, and sell this software and its
10 documentation for any purpose is hereby granted without fee, provided that
11 the above copyright notice appear in all copies and that both that
12 copyright notice and this permission notice appear in supporting
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
26 Except as contained in this notice, the name of The Open Group shall
27 not be used in advertising or otherwise to promote the sale, use or
28 other dealings in this Software without prior written authorization
31 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
32 Copyright 1994 Quarterdeck Office Systems.
36 Permission to use, copy, modify, and distribute this software and its
37 documentation for any purpose and without fee is hereby granted,
38 provided that the above copyright notice appear in all copies and that
39 both that copyright notice and this permission notice appear in
40 supporting documentation, and that the names of Digital and
41 Quarterdeck not be used in advertising or publicity pertaining to
42 distribution of the software without specific, written prior
45 DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
46 SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
47 FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
48 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
49 OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
50 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
51 OR PERFORMANCE OF THIS SOFTWARE.
54 #include <dix-config.h>
63 #include "dix/dix_priv.h"
64 #include "os/serverlock.h"
71 * Explicit support for a server lock file like the ones used for UUCP.
72 * For architectures with virtual terminals that can run more than one
73 * server at a time. This keeps the servers from stomping on each other
74 * if the user forgets to give them different display numbers.
76 #define LOCK_DIR "/tmp"
77 #define LOCK_TMP_PREFIX "/.tX"
78 #define LOCK_PREFIX "/.X"
79 #define LOCK_SUFFIX "-lock"
83 static Bool StillLocking
= FALSE
;
84 static char LockFile
[PATH_MAX
];
85 static Bool nolock
= FALSE
;
89 * Check if the server lock file exists. If so, check if the PID
90 * contained inside is valid. If so, then die. Otherwise, create
91 * the lock file containing the PID.
96 char tmp
[PATH_MAX
], pid_str
[12];
97 int lfd
, i
, haslock
, l_pid
, t
;
98 const char *tmppath
= LOCK_DIR
;
102 if (nolock
|| NoListenAll
)
107 snprintf(port
, sizeof(port
), "%d", atoi(display
));
108 len
= strlen(LOCK_PREFIX
) > strlen(LOCK_TMP_PREFIX
) ? strlen(LOCK_PREFIX
) :
109 strlen(LOCK_TMP_PREFIX
);
110 len
+= strlen(tmppath
) + strlen(port
) + strlen(LOCK_SUFFIX
) + 1;
111 if (len
> sizeof(LockFile
))
112 FatalError("Display name `%s' is too long\n", port
);
113 (void) sprintf(tmp
, "%s" LOCK_TMP_PREFIX
"%s" LOCK_SUFFIX
, tmppath
, port
);
114 (void) sprintf(LockFile
, "%s" LOCK_PREFIX
"%s" LOCK_SUFFIX
, tmppath
, port
);
117 * Create a temporary file containing our PID. Attempt three times
118 * to create the file.
124 lfd
= open(tmp
, O_CREAT
| O_EXCL
| O_WRONLY
, 0644);
135 lfd
= open(tmp
, O_CREAT
| O_EXCL
| O_WRONLY
, 0644);
143 FatalError("Could not create lock file in %s\n", tmp
);
144 snprintf(pid_str
, sizeof(pid_str
), "%10lu\n", (unsigned long) getpid());
145 if (write(lfd
, pid_str
, 11) != 11)
146 FatalError("Could not write pid to lock file in %s\n", tmp
);
147 (void) fchmod(lfd
, 0444);
151 * OK. Now the tmp file exists. Try three times to move it in place
156 while ((!haslock
) && (i
++ < 3)) {
157 haslock
= (link(tmp
, LockFile
) == 0);
164 else if (errno
== EEXIST
) {
166 * Read the pid from the existing file
168 lfd
= open(LockFile
, O_RDONLY
| O_NOFOLLOW
);
171 FatalError("Can't read lock file %s\n", LockFile
);
174 if (read(lfd
, pid_str
, 11) != 11) {
183 sscanf(pid_str
, "%d", &l_pid
);
187 * Now try to kill the PID to see if it exists.
191 if ((t
< 0) && (errno
== ESRCH
)) {
198 else if (((t
< 0) && (errno
== EPERM
)) || (t
== 0)) {
200 * Process is still active.
204 ("Server is already active for display %s\n%s %s\n%s\n",
205 port
, "\tIf this server is no longer running, remove",
206 LockFile
, "\tand start again.");
212 ("Linking lock file (%s) in place failed: %s\n",
213 LockFile
, strerror(errno
));
218 FatalError("Could not create server lock file: %s\n", LockFile
);
219 StillLocking
= FALSE
;
224 * Remove the server lock file.
229 if (nolock
|| NoListenAll
)
234 (void) unlink(LockFile
);
238 void DisableServerLock(void) {
242 void LockServerUseMsg(void) {
243 ErrorF("-nolock disable the locking mechanism\n");
246 #else /* LOCK_SERVER */
248 void LockServer(void) {}
249 void UnlockServer(void) {}
250 void DisableServerLock(void) {}
251 void LockServerUseMsg(void) {}
253 #endif /* LOCK_SERVER */