]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Don't abort if log files can't be opened.
authorVMware, Inc <>
Thu, 15 Oct 2009 22:09:00 +0000 (15:09 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Thu, 15 Oct 2009 22:09:00 +0000 (15:09 -0700)
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 <mvanzin@vmware.com>
open-vm-tools/libvmtools/vmtoolsLog.c

index cf6ff05447344f97c099038d855b58aaec6e2844..5e828ec16a0b715a2225c2d7fde77c209a8e57d1 100644 (file)
@@ -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)) {