os: move out LockServer logic from util.c to serverlock.c
Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1320>
This commit is contained in:
parent
4773182c72
commit
749046e5e9
|
@ -12,6 +12,7 @@ srcs_os = [
|
||||||
'mitauth.c',
|
'mitauth.c',
|
||||||
'osinit.c',
|
'osinit.c',
|
||||||
'ospoll.c',
|
'ospoll.c',
|
||||||
|
'serverlock.c',
|
||||||
'string.c',
|
'string.c',
|
||||||
'utils.c',
|
'utils.c',
|
||||||
'xdmauth.c',
|
'xdmauth.c',
|
||||||
|
|
|
@ -0,0 +1,248 @@
|
||||||
|
/* SPDX-License-Identifier: MIT OR X11
|
||||||
|
*
|
||||||
|
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 1987, 1998 The Open Group
|
||||||
|
|
||||||
|
Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
the above copyright notice appear in all copies and that both that
|
||||||
|
copyright notice and this permission notice appear in supporting
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of The Open Group shall
|
||||||
|
not be used in advertising or otherwise to promote the sale, use or
|
||||||
|
other dealings in this Software without prior written authorization
|
||||||
|
from The Open Group.
|
||||||
|
|
||||||
|
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
|
||||||
|
Copyright 1994 Quarterdeck Office Systems.
|
||||||
|
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and its
|
||||||
|
documentation for any purpose and without fee is hereby granted,
|
||||||
|
provided that the above copyright notice appear in all copies and that
|
||||||
|
both that copyright notice and this permission notice appear in
|
||||||
|
supporting documentation, and that the names of Digital and
|
||||||
|
Quarterdeck not be used in advertising or publicity pertaining to
|
||||||
|
distribution of the software without specific, written prior
|
||||||
|
permission.
|
||||||
|
|
||||||
|
DIGITAL AND QUARTERDECK DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
|
||||||
|
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||||
|
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|
||||||
|
OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#include <dix-config.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "dix/dix_priv.h"
|
||||||
|
#include "os/serverlock.h"
|
||||||
|
#include "os/osdep.h"
|
||||||
|
|
||||||
|
#include "os.h"
|
||||||
|
#include "opaque.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Explicit support for a server lock file like the ones used for UUCP.
|
||||||
|
* For architectures with virtual terminals that can run more than one
|
||||||
|
* server at a time. This keeps the servers from stomping on each other
|
||||||
|
* if the user forgets to give them different display numbers.
|
||||||
|
*/
|
||||||
|
#define LOCK_DIR "/tmp"
|
||||||
|
#define LOCK_TMP_PREFIX "/.tX"
|
||||||
|
#define LOCK_PREFIX "/.X"
|
||||||
|
#define LOCK_SUFFIX "-lock"
|
||||||
|
|
||||||
|
#ifdef LOCK_SERVER
|
||||||
|
|
||||||
|
static Bool StillLocking = FALSE;
|
||||||
|
static char LockFile[PATH_MAX];
|
||||||
|
static Bool nolock = FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LockServer --
|
||||||
|
* Check if the server lock file exists. If so, check if the PID
|
||||||
|
* contained inside is valid. If so, then die. Otherwise, create
|
||||||
|
* the lock file containing the PID.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LockServer(void)
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX], pid_str[12];
|
||||||
|
int lfd, i, haslock, l_pid, t;
|
||||||
|
const char *tmppath = LOCK_DIR;
|
||||||
|
int len;
|
||||||
|
char port[20];
|
||||||
|
|
||||||
|
if (nolock || NoListenAll)
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
* Path names
|
||||||
|
*/
|
||||||
|
snprintf(port, sizeof(port), "%d", atoi(display));
|
||||||
|
len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) :
|
||||||
|
strlen(LOCK_TMP_PREFIX);
|
||||||
|
len += strlen(tmppath) + strlen(port) + strlen(LOCK_SUFFIX) + 1;
|
||||||
|
if (len > sizeof(LockFile))
|
||||||
|
FatalError("Display name `%s' is too long\n", port);
|
||||||
|
(void) sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
|
||||||
|
(void) sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a temporary file containing our PID. Attempt three times
|
||||||
|
* to create the file.
|
||||||
|
*/
|
||||||
|
StillLocking = TRUE;
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
i++;
|
||||||
|
lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
|
||||||
|
if (lfd < 0)
|
||||||
|
sleep(2);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
} while (i < 3);
|
||||||
|
if (lfd < 0) {
|
||||||
|
unlink(tmp);
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
i++;
|
||||||
|
lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
|
||||||
|
if (lfd < 0)
|
||||||
|
sleep(2);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
} while (i < 3);
|
||||||
|
}
|
||||||
|
if (lfd < 0)
|
||||||
|
FatalError("Could not create lock file in %s\n", tmp);
|
||||||
|
snprintf(pid_str, sizeof(pid_str), "%10lu\n", (unsigned long) getpid());
|
||||||
|
if (write(lfd, pid_str, 11) != 11)
|
||||||
|
FatalError("Could not write pid to lock file in %s\n", tmp);
|
||||||
|
(void) fchmod(lfd, 0444);
|
||||||
|
(void) close(lfd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OK. Now the tmp file exists. Try three times to move it in place
|
||||||
|
* for the lock.
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
haslock = 0;
|
||||||
|
while ((!haslock) && (i++ < 3)) {
|
||||||
|
haslock = (link(tmp, LockFile) == 0);
|
||||||
|
if (haslock) {
|
||||||
|
/*
|
||||||
|
* We're done.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (errno == EEXIST) {
|
||||||
|
/*
|
||||||
|
* Read the pid from the existing file
|
||||||
|
*/
|
||||||
|
lfd = open(LockFile, O_RDONLY | O_NOFOLLOW);
|
||||||
|
if (lfd < 0) {
|
||||||
|
unlink(tmp);
|
||||||
|
FatalError("Can't read lock file %s\n", LockFile);
|
||||||
|
}
|
||||||
|
pid_str[0] = '\0';
|
||||||
|
if (read(lfd, pid_str, 11) != 11) {
|
||||||
|
/*
|
||||||
|
* Bogus lock file.
|
||||||
|
*/
|
||||||
|
unlink(LockFile);
|
||||||
|
close(lfd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pid_str[11] = '\0';
|
||||||
|
sscanf(pid_str, "%d", &l_pid);
|
||||||
|
close(lfd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now try to kill the PID to see if it exists.
|
||||||
|
*/
|
||||||
|
errno = 0;
|
||||||
|
t = kill(l_pid, 0);
|
||||||
|
if ((t < 0) && (errno == ESRCH)) {
|
||||||
|
/*
|
||||||
|
* Stale lock file.
|
||||||
|
*/
|
||||||
|
unlink(LockFile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (((t < 0) && (errno == EPERM)) || (t == 0)) {
|
||||||
|
/*
|
||||||
|
* Process is still active.
|
||||||
|
*/
|
||||||
|
unlink(tmp);
|
||||||
|
FatalError
|
||||||
|
("Server is already active for display %s\n%s %s\n%s\n",
|
||||||
|
port, "\tIf this server is no longer running, remove",
|
||||||
|
LockFile, "\tand start again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
unlink(tmp);
|
||||||
|
FatalError
|
||||||
|
("Linking lock file (%s) in place failed: %s\n",
|
||||||
|
LockFile, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlink(tmp);
|
||||||
|
if (!haslock)
|
||||||
|
FatalError("Could not create server lock file: %s\n", LockFile);
|
||||||
|
StillLocking = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UnlockServer --
|
||||||
|
* Remove the server lock file.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
UnlockServer(void)
|
||||||
|
{
|
||||||
|
if (nolock || NoListenAll)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!StillLocking) {
|
||||||
|
|
||||||
|
(void) unlink(LockFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisableServerLock(void) {
|
||||||
|
nolock = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* LOCK_SERVER */
|
||||||
|
|
||||||
|
void LockServer(void) {}
|
||||||
|
void UnlockServer(void) {}
|
||||||
|
void DisableServerLock(void) {}
|
||||||
|
|
||||||
|
#endif /* LOCK_SERVER */
|
|
@ -7,5 +7,6 @@
|
||||||
|
|
||||||
void LockServer(void);
|
void LockServer(void);
|
||||||
void UnlockServer(void);
|
void UnlockServer(void);
|
||||||
|
void DisableServerLock(void);
|
||||||
|
|
||||||
#endif /* _XSERVER_SERVERLOCK_H */
|
#endif /* _XSERVER_SERVERLOCK_H */
|
||||||
|
|
182
os/utils.c
182
os/utils.c
|
@ -224,182 +224,6 @@ OsSignal(int sig, OsSigHandlerPtr handler)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Explicit support for a server lock file like the ones used for UUCP.
|
|
||||||
* For architectures with virtual terminals that can run more than one
|
|
||||||
* server at a time. This keeps the servers from stomping on each other
|
|
||||||
* if the user forgets to give them different display numbers.
|
|
||||||
*/
|
|
||||||
#define LOCK_DIR "/tmp"
|
|
||||||
#define LOCK_TMP_PREFIX "/.tX"
|
|
||||||
#define LOCK_PREFIX "/.X"
|
|
||||||
#define LOCK_SUFFIX "-lock"
|
|
||||||
|
|
||||||
#ifndef LOCK_SERVER
|
|
||||||
void
|
|
||||||
LockServer(void)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void
|
|
||||||
UnlockServer(void)
|
|
||||||
{}
|
|
||||||
#else /* LOCK_SERVER */
|
|
||||||
static Bool StillLocking = FALSE;
|
|
||||||
static char LockFile[PATH_MAX];
|
|
||||||
static Bool nolock = FALSE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LockServer --
|
|
||||||
* Check if the server lock file exists. If so, check if the PID
|
|
||||||
* contained inside is valid. If so, then die. Otherwise, create
|
|
||||||
* the lock file containing the PID.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
LockServer(void)
|
|
||||||
{
|
|
||||||
char tmp[PATH_MAX], pid_str[12];
|
|
||||||
int lfd, i, haslock, l_pid, t;
|
|
||||||
const char *tmppath = LOCK_DIR;
|
|
||||||
int len;
|
|
||||||
char port[20];
|
|
||||||
|
|
||||||
if (nolock || NoListenAll)
|
|
||||||
return;
|
|
||||||
/*
|
|
||||||
* Path names
|
|
||||||
*/
|
|
||||||
snprintf(port, sizeof(port), "%d", atoi(display));
|
|
||||||
len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) :
|
|
||||||
strlen(LOCK_TMP_PREFIX);
|
|
||||||
len += strlen(tmppath) + strlen(port) + strlen(LOCK_SUFFIX) + 1;
|
|
||||||
if (len > sizeof(LockFile))
|
|
||||||
FatalError("Display name `%s' is too long\n", port);
|
|
||||||
(void) sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
|
|
||||||
(void) sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a temporary file containing our PID. Attempt three times
|
|
||||||
* to create the file.
|
|
||||||
*/
|
|
||||||
StillLocking = TRUE;
|
|
||||||
i = 0;
|
|
||||||
do {
|
|
||||||
i++;
|
|
||||||
lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
|
|
||||||
if (lfd < 0)
|
|
||||||
sleep(2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
} while (i < 3);
|
|
||||||
if (lfd < 0) {
|
|
||||||
unlink(tmp);
|
|
||||||
i = 0;
|
|
||||||
do {
|
|
||||||
i++;
|
|
||||||
lfd = open(tmp, O_CREAT | O_EXCL | O_WRONLY, 0644);
|
|
||||||
if (lfd < 0)
|
|
||||||
sleep(2);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
} while (i < 3);
|
|
||||||
}
|
|
||||||
if (lfd < 0)
|
|
||||||
FatalError("Could not create lock file in %s\n", tmp);
|
|
||||||
snprintf(pid_str, sizeof(pid_str), "%10lu\n", (unsigned long) getpid());
|
|
||||||
if (write(lfd, pid_str, 11) != 11)
|
|
||||||
FatalError("Could not write pid to lock file in %s\n", tmp);
|
|
||||||
(void) fchmod(lfd, 0444);
|
|
||||||
(void) close(lfd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* OK. Now the tmp file exists. Try three times to move it in place
|
|
||||||
* for the lock.
|
|
||||||
*/
|
|
||||||
i = 0;
|
|
||||||
haslock = 0;
|
|
||||||
while ((!haslock) && (i++ < 3)) {
|
|
||||||
haslock = (link(tmp, LockFile) == 0);
|
|
||||||
if (haslock) {
|
|
||||||
/*
|
|
||||||
* We're done.
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (errno == EEXIST) {
|
|
||||||
/*
|
|
||||||
* Read the pid from the existing file
|
|
||||||
*/
|
|
||||||
lfd = open(LockFile, O_RDONLY | O_NOFOLLOW);
|
|
||||||
if (lfd < 0) {
|
|
||||||
unlink(tmp);
|
|
||||||
FatalError("Can't read lock file %s\n", LockFile);
|
|
||||||
}
|
|
||||||
pid_str[0] = '\0';
|
|
||||||
if (read(lfd, pid_str, 11) != 11) {
|
|
||||||
/*
|
|
||||||
* Bogus lock file.
|
|
||||||
*/
|
|
||||||
unlink(LockFile);
|
|
||||||
close(lfd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pid_str[11] = '\0';
|
|
||||||
sscanf(pid_str, "%d", &l_pid);
|
|
||||||
close(lfd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now try to kill the PID to see if it exists.
|
|
||||||
*/
|
|
||||||
errno = 0;
|
|
||||||
t = kill(l_pid, 0);
|
|
||||||
if ((t < 0) && (errno == ESRCH)) {
|
|
||||||
/*
|
|
||||||
* Stale lock file.
|
|
||||||
*/
|
|
||||||
unlink(LockFile);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (((t < 0) && (errno == EPERM)) || (t == 0)) {
|
|
||||||
/*
|
|
||||||
* Process is still active.
|
|
||||||
*/
|
|
||||||
unlink(tmp);
|
|
||||||
FatalError
|
|
||||||
("Server is already active for display %s\n%s %s\n%s\n",
|
|
||||||
port, "\tIf this server is no longer running, remove",
|
|
||||||
LockFile, "\tand start again.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
unlink(tmp);
|
|
||||||
FatalError
|
|
||||||
("Linking lock file (%s) in place failed: %s\n",
|
|
||||||
LockFile, strerror(errno));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unlink(tmp);
|
|
||||||
if (!haslock)
|
|
||||||
FatalError("Could not create server lock file: %s\n", LockFile);
|
|
||||||
StillLocking = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* UnlockServer --
|
|
||||||
* Remove the server lock file.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
UnlockServer(void)
|
|
||||||
{
|
|
||||||
if (nolock || NoListenAll)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!StillLocking) {
|
|
||||||
|
|
||||||
(void) unlink(LockFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* LOCK_SERVER */
|
|
||||||
|
|
||||||
/* Force connections to close on SIGHUP from init */
|
/* Force connections to close on SIGHUP from init */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -763,9 +587,7 @@ ProcessCommandLine(int argc, char *argv[])
|
||||||
else if (strcmp(argv[i], "-displayfd") == 0) {
|
else if (strcmp(argv[i], "-displayfd") == 0) {
|
||||||
if (++i < argc) {
|
if (++i < argc) {
|
||||||
displayfd = atoi(argv[i]);
|
displayfd = atoi(argv[i]);
|
||||||
#ifdef LOCK_SERVER
|
DisableServerLock();
|
||||||
nolock = TRUE;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
UseMsg();
|
UseMsg();
|
||||||
|
@ -854,7 +676,7 @@ ProcessCommandLine(int argc, char *argv[])
|
||||||
("Warning: the -nolock option can only be used by root\n");
|
("Warning: the -nolock option can only be used by root\n");
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
nolock = TRUE;
|
DisableServerLock();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if ( strcmp( argv[i], "-maxclients") == 0)
|
else if ( strcmp( argv[i], "-maxclients") == 0)
|
||||||
|
|
Loading…
Reference in New Issue