From e96e810c2287232000767ee55f2d1b84b31e6291 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 15 Mar 2017 15:42:10 +0000 Subject: Use unique logfile names when starting server with -displayfd commit edcb6426f20c3be5dd5f50b76a686754aef2f64e Author: Alan Coopersmith 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-.log is used until after -displayfd finds an open display - then it is renamed to the traditional Xorg..log name. Reviewed-by: Adam Jackson Signed-off-by: Alan Coopersmith Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/os.h | 1 + nx-X11/programs/Xserver/os/connection.c | 1 + nx-X11/programs/Xserver/os/log.c | 127 ++++++++++++++++++++++++-------- 3 files changed, 100 insertions(+), 29 deletions(-) diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index 1af34a04c..0c7ce6a6f 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -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); diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 0d48fda5b..940b0bd75 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -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)); diff --git a/nx-X11/programs/Xserver/os/log.c b/nx-X11/programs/Xserver/os/log.c index d82f545a0..0ead6e9f0 100644 --- a/nx-X11/programs/Xserver/os/log.c +++ b/nx-X11/programs/Xserver/os/log.c @@ -178,49 +178,88 @@ static Bool needBuffer = TRUE; #define X_NOT_IMPLEMENTED_STRING "(NI)" #endif +/* + * 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" + +static char * +LogFilePrep(const char *fname, const char *backup, const char *idstring) +{ + char *logFileName = NULL; + + if (asprintf(&logFileName, fname, idstring) == -1) + FatalError("Cannot allocate space for the log file name\n"); + + if (backup && *backup) { + struct stat buf; + + if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) { + char *suffix; + char *oldLog; + + if ((asprintf(&suffix, backup, idstring) == -1) || + (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) { + FatalError("Cannot allocate space for the log file name\n"); + } + free(suffix); + + if (rename(logFileName, oldLog) == -1) { + 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. + * 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) { - /* malloc() can't be used yet. */ - logFileName = malloc(strlen(fname) + strlen(display) + 1); - if (!logFileName) - FatalError("Cannot allocate space for the log file name\n"); - sprintf(logFileName, fname, display); - - if (backup && *backup) { - struct stat buf; - - if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) { - char *suffix; - char *oldLog; - - oldLog = malloc(strlen(logFileName) + strlen(backup) + - strlen(display) + 1); - suffix = malloc(strlen(backup) + strlen(display) + 1); - if (!oldLog || !suffix) - 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", - logFileName, oldLog); - } - free(oldLog); - } - } + 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); @@ -249,6 +288,36 @@ LogInit(const char *fname, const char *backup) return logFileName; } +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() { -- cgit v1.2.3