Commit e96e810c authored by Alan Coopersmith's avatar Alan Coopersmith Committed by Mike Gabriel

Use unique logfile names when starting server with -displayfd

commit edcb6426f20c3be5dd5f50b76a686754aef2f64e Author: Alan Coopersmith <alan.coopersmith@oracle.com> Date: Fri Jan 1 18:11:14 2016 -0800 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: 's avatarAdam Jackson <ajax@redhat.com> Signed-off-by: 's avatarAlan Coopersmith <alan.coopersmith@oracle.com> Backported-to-NX-by: 's avatarMike Gabriel <mike.gabriel@das-netzwerkteam.de>
parent faaba266
......@@ -520,6 +520,7 @@ typedef enum {
#endif
extern const char *LogInit(const char *fname, const char *backup);
extern void LogSetDisplay(void);
extern void LogClose(void);
extern Bool LogSetParameter(LogParameter param, int value);
extern void LogVWrite(int verb, const char *f, va_list args);
......
......@@ -434,6 +434,7 @@ CreateWellKnownSockets(void)
FatalError("Failed to find a socket to listen on");
snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
display = dynamic_display;
LogSetDisplay();
}
ListenTransFds = malloc(ListenTransCount * sizeof (int));
......
......@@ -179,25 +179,20 @@ static Bool needBuffer = TRUE;
#endif
/*
* 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.
* LogFilePrep is called to setup files for logging, including getting
* an old file out of the way, but it doesn't actually open the file,
* since it may be used for renaming a file we're already logging to.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
const char *
LogInit(const char *fname, const char *backup)
static char *
LogFilePrep(const char *fname, const char *backup, const char *idstring)
{
char *logFileName = NULL;
if (fname && *fname) {
/* malloc() can't be used yet. */
logFileName = malloc(strlen(fname) + strlen(display) + 1);
if (!logFileName)
if (asprintf(&logFileName, fname, idstring) == -1)
FatalError("Cannot allocate space for the log file name\n");
sprintf(logFileName, fname, display);
if (backup && *backup) {
struct stat buf;
......@@ -206,21 +201,65 @@ LogInit(const char *fname, const char *backup)
char *suffix;
char *oldLog;
oldLog = malloc(strlen(logFileName) + strlen(backup) +
strlen(display) + 1);
suffix = malloc(strlen(backup) + strlen(display) + 1);
if (!oldLog || !suffix)
if ((asprintf(&suffix, backup, idstring) == -1) ||
(asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) {
FatalError("Cannot allocate space for the log file name\n");
sprintf(suffix, backup, display);
sprintf(oldLog, "%s%s", logFileName, suffix);
}
free(suffix);
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);
}
free(oldLog);
}
}
else {
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)
FatalError("Cannot open log file \"%s\"\n", logFileName);
setvbuf(logFile, NULL, _IONBF, 0);
......@@ -250,6 +289,36 @@ LogInit(const char *fname, const char *backup)
}
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
LogClose()
{
if (logFile) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment