From: VMware, Inc <> Date: Thu, 15 Oct 2009 22:09:00 +0000 (-0700) Subject: Don't abort if log files can't be opened. X-Git-Tag: 2009.10.15-201664~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9962034643c34aecbaf7ae25071efcf9725cc13a;p=thirdparty%2Fopen-vm-tools.git Don't abort if log files can't be opened. glib's documentation lies about custom log handlers being able to handle G_LOG_FLAG_RECURSION. It always uses its internal handler. So what happens is that when our logging function calls g_warning() to log that a log file could not be opened, it causes log recursion, which calls glib's internal handler, which then aborts the process. Avoid that by calling the default log handler directly instead of going through the glib log system in that case. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/libvmtools/vmtoolsLog.c b/open-vm-tools/libvmtools/vmtoolsLog.c index cf6ff0544..5e828ec16 100644 --- a/open-vm-tools/libvmtools/vmtoolsLog.c +++ b/open-vm-tools/libvmtools/vmtoolsLog.c @@ -104,6 +104,7 @@ typedef struct LogHandlerData { gboolean append; guint handlerId; gboolean inherited; + gboolean error; } LogHandlerData; static gchar *gLogDomain = NULL; @@ -314,22 +315,39 @@ VMToolsLogFile(const gchar *domain, { LogHandlerData *data = _data; if (SHOULD_LOG(level, data)) { - char *msg = VMToolsLogFormat(message, domain, level, TRUE); - if (msg != NULL) { - FILE *dest; - data = data->inherited ? gDefaultData : data; - if (data->file == NULL && data->path != NULL) { - data->file = VMToolsLogOpenFile(data->path, data->append); - if (data->file == NULL) { - g_warning("Unable to open log file %s for domain %s.\n", - data->domain, data->path); - } + FILE *dest; + data = data->inherited ? gDefaultData : data; + if (!data->error && data->file == NULL && data->path != NULL) { + data->file = VMToolsLogOpenFile(data->path, data->append); + if (data->file == NULL) { + /* + * glib's documentation says that we can set up log handlers that + * handle G_LOG_FLAG_RECURSION, but looking at the source code of + * the g_logv() function that's not really true (at least up to + * current top of tree - glib 2.20?). So we have to avoid recursion + * here and bypass the log system. + */ + gchar warn[1024]; + g_snprintf(warn, sizeof warn, + "Unable to open log file %s for domain %s.\n", + data->path, data->domain); + + data->error = TRUE; + DEFAULT_HANDLER(domain, G_LOG_LEVEL_WARNING | G_LOG_FLAG_RECURSION, + warn, gDefaultData); + } + } + if (!(level & G_LOG_FLAG_RECURSION) && data->error) { + DEFAULT_HANDLER(domain, level | G_LOG_FLAG_RECURSION, message, gDefaultData); + } else { + char *msg = VMToolsLogFormat(message, domain, level, TRUE); + if (msg != NULL) { + dest = (data->file != NULL) ? data->file + : ((level < G_LOG_LEVEL_MESSAGE) ? stderr : stdout); + fputs(msg, dest); + fflush(dest); + vm_free(msg); } - dest = (data->file != NULL) ? data->file - : ((level < G_LOG_LEVEL_MESSAGE) ? stderr : stdout); - fputs(msg, dest); - fflush(dest); - free(msg); } } if (IS_FATAL(level)) {