Use unique logfile names when starting server with -displayfd
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=93212 Previously all X servers started with -displayfd would overwrite Xorg.0.log - now a temporary name of Xorg.pid-<pid>.log is used until after -displayfd finds an open display - then it is renamed to the traditional Xorg.<display>.log name. Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
This commit is contained in:
parent
fe8562f531
commit
edcb6426f2
|
@ -626,6 +626,8 @@ typedef enum {
|
||||||
|
|
||||||
extern _X_EXPORT const char *
|
extern _X_EXPORT const char *
|
||||||
LogInit(const char *fname, const char *backup);
|
LogInit(const char *fname, const char *backup);
|
||||||
|
extern void
|
||||||
|
LogSetDisplay(void);
|
||||||
extern _X_EXPORT void
|
extern _X_EXPORT void
|
||||||
LogClose(enum ExitCode error);
|
LogClose(enum ExitCode error);
|
||||||
extern _X_EXPORT Bool
|
extern _X_EXPORT Bool
|
||||||
|
|
|
@ -431,6 +431,7 @@ CreateWellKnownSockets(void)
|
||||||
FatalError("Failed to find a socket to listen on");
|
FatalError("Failed to find a socket to listen on");
|
||||||
snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
|
snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
|
||||||
display = dynamic_display;
|
display = dynamic_display;
|
||||||
|
LogSetDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenTransFds = xallocarray(ListenTransCount, sizeof (int));
|
ListenTransFds = xallocarray(ListenTransCount, sizeof (int));
|
||||||
|
|
100
os/log.c
100
os/log.c
|
@ -85,6 +85,7 @@ OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h> /* for malloc() */
|
#include <stdlib.h> /* for malloc() */
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "site.h"
|
#include "site.h"
|
||||||
|
@ -181,24 +182,19 @@ strlen_sigsafe(const char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LogInit is called to start logging to a file. It is also called (with
|
* LogFilePrep is called to setup files for logging, including getting
|
||||||
* NULL arguments) when logging to a file is not wanted. It must always be
|
* an old file out of the way, but it doesn't actually open the file,
|
||||||
* called, otherwise log messages will continue to accumulate in a buffer.
|
* since it may be used for renaming a file we're already logging to.
|
||||||
*
|
|
||||||
* %s, if present in the fname or backup strings, is expanded to the display
|
|
||||||
* string.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
|
|
||||||
const char *
|
static char *
|
||||||
LogInit(const char *fname, const char *backup)
|
LogFilePrep(const char *fname, const char *backup, const char *idstring)
|
||||||
{
|
{
|
||||||
char *logFileName = NULL;
|
char *logFileName = NULL;
|
||||||
|
|
||||||
if (fname && *fname) {
|
if (asprintf(&logFileName, fname, idstring) == -1)
|
||||||
if (asprintf(&logFileName, fname, display) == -1)
|
|
||||||
FatalError("Cannot allocate space for the log file name\n");
|
FatalError("Cannot allocate space for the log file name\n");
|
||||||
|
|
||||||
if (backup && *backup) {
|
if (backup && *backup) {
|
||||||
|
@ -208,10 +204,12 @@ LogInit(const char *fname, const char *backup)
|
||||||
char *suffix;
|
char *suffix;
|
||||||
char *oldLog;
|
char *oldLog;
|
||||||
|
|
||||||
if ((asprintf(&suffix, backup, display) == -1) ||
|
if ((asprintf(&suffix, backup, idstring) == -1) ||
|
||||||
(asprintf(&oldLog, "%s%s", logFileName, suffix) == -1))
|
(asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) {
|
||||||
FatalError("Cannot allocate space for the log file name\n");
|
FatalError("Cannot allocate space for the log file name\n");
|
||||||
|
}
|
||||||
free(suffix);
|
free(suffix);
|
||||||
|
|
||||||
if (rename(logFileName, oldLog) == -1) {
|
if (rename(logFileName, oldLog) == -1) {
|
||||||
FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
|
FatalError("Cannot move old log file \"%s\" to \"%s\"\n",
|
||||||
logFileName, oldLog);
|
logFileName, oldLog);
|
||||||
|
@ -220,8 +218,51 @@ LogInit(const char *fname, const char *backup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unlink(logFileName);
|
if (remove(logFileName) != 0) {
|
||||||
|
FatalError("Cannot remove old log file \"%s\": %s\n",
|
||||||
|
logFileName, strerror(errno));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return logFileName;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LogInit is called to start logging to a file. It is also called (with
|
||||||
|
* NULL arguments) when logging to a file is not wanted. It must always be
|
||||||
|
* called, otherwise log messages will continue to accumulate in a buffer.
|
||||||
|
*
|
||||||
|
* %s, if present in the fname or backup strings, is expanded to the display
|
||||||
|
* string (or to a string containing the pid if the display is not yet set).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char *saved_log_fname;
|
||||||
|
static char *saved_log_backup;
|
||||||
|
static char *saved_log_tempname;
|
||||||
|
|
||||||
|
const char *
|
||||||
|
LogInit(const char *fname, const char *backup)
|
||||||
|
{
|
||||||
|
char *logFileName = NULL;
|
||||||
|
|
||||||
|
if (fname && *fname) {
|
||||||
|
if (displayfd != -1) {
|
||||||
|
/* Display isn't set yet, so we can't use it in filenames yet. */
|
||||||
|
char pidstring[32];
|
||||||
|
snprintf(pidstring, sizeof(pidstring), "pid-%ld",
|
||||||
|
(unsigned long) getpid());
|
||||||
|
logFileName = LogFilePrep(fname, backup, pidstring);
|
||||||
|
saved_log_tempname = logFileName;
|
||||||
|
|
||||||
|
/* Save the patterns for use when the display is named. */
|
||||||
|
saved_log_fname = strdup(fname);
|
||||||
|
if (backup == NULL)
|
||||||
|
saved_log_backup = NULL;
|
||||||
|
else
|
||||||
|
saved_log_backup = strdup(backup);
|
||||||
|
} else
|
||||||
|
logFileName = LogFilePrep(fname, backup, display);
|
||||||
if ((logFile = fopen(logFileName, "w")) == NULL)
|
if ((logFile = fopen(logFileName, "w")) == NULL)
|
||||||
FatalError("Cannot open log file \"%s\"\n", logFileName);
|
FatalError("Cannot open log file \"%s\"\n", logFileName);
|
||||||
setvbuf(logFile, NULL, _IONBF, 0);
|
setvbuf(logFile, NULL, _IONBF, 0);
|
||||||
|
@ -251,7 +292,36 @@ LogInit(const char *fname, const char *backup)
|
||||||
|
|
||||||
return logFileName;
|
return logFileName;
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
void
|
||||||
|
LogSetDisplay(void)
|
||||||
|
{
|
||||||
|
if (saved_log_fname) {
|
||||||
|
char *logFileName;
|
||||||
|
|
||||||
|
logFileName = LogFilePrep(saved_log_fname, saved_log_backup, display);
|
||||||
|
|
||||||
|
if (rename(saved_log_tempname, logFileName) == 0) {
|
||||||
|
LogMessageVerb(X_PROBED, 0,
|
||||||
|
"Log file renamed from \"%s\" to \"%s\"\n",
|
||||||
|
saved_log_tempname, logFileName);
|
||||||
|
|
||||||
|
if (strlen(saved_log_tempname) >= strlen(logFileName))
|
||||||
|
strncpy(saved_log_tempname, logFileName,
|
||||||
|
strlen(saved_log_tempname));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ErrorF("Failed to rename log file \"%s\" to \"%s\": %s\n",
|
||||||
|
saved_log_tempname, logFileName, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free newly allocated string - can't free old one since existing
|
||||||
|
pointers to it may exist in DDX callers. */
|
||||||
|
free(logFileName);
|
||||||
|
free(saved_log_fname);
|
||||||
|
free(saved_log_backup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogClose(enum ExitCode error)
|
LogClose(enum ExitCode error)
|
||||||
|
|
Loading…
Reference in New Issue