ListNames and ListQueuedOwners updated to work with new kdbus
[platform/upstream/dbus.git] / dbus / dbus-internals.c
index 96302d7..e248259 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
+
+#include <config.h>
 #include "dbus-internals.h"
 #include "dbus-protocol.h"
 #include "dbus-marshal-basic.h"
 #include "dbus-test.h"
+#include "dbus-valgrind-internal.h"
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
 #include <stdlib.h>
 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
 #include <windows.h>
+#include <mbstring.h>
 #endif
 
 /**
  */
 
 /**
- * @def _DBUS_DEFINE_GLOBAL_LOCK
- *
- * Defines a global lock variable with the given name.
- * The lock must be added to the list to initialize
- * in dbus_threads_init().
- */
-
-/**
- * @def _DBUS_DECLARE_GLOBAL_LOCK
- *
- * Expands to declaration of a global lock defined
- * with _DBUS_DEFINE_GLOBAL_LOCK.
- * The lock must be added to the list to initialize
- * in dbus_threads_init().
- */
-
-/**
  * @def _DBUS_LOCK
  *
- * Locks a global lock
+ * Locks a global lock, initializing it first if necessary.
+ *
+ * @returns #FALSE if not enough memory
  */
 
 /**
@@ -298,9 +287,6 @@ static dbus_bool_t verbose = TRUE;
 #include <pthread.h>
 #endif
 
-#ifdef DBUS_WIN
-#define inline
-#endif
 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
 static char module_name[1024];
 #endif
@@ -310,22 +296,61 @@ _dbus_verbose_init (void)
 {
   if (!verbose_initted)
     {
-      char *p = _dbus_getenv ("DBUS_VERBOSE"); 
+      const char *p = _dbus_getenv ("DBUS_VERBOSE");
       verbose = p != NULL && *p == '1';
       verbose_initted = TRUE;
 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
-      GetModuleFileName(0,module_name,sizeof(module_name)-1);
-      p = strrchr(module_name,'.');
-      if (p)
-        *p ='\0';
-      p = strrchr(module_name,'\\');
-      if (p)
-        strcpy(module_name,p+1);
-      strcat(module_name,": ");
+      {
+        char *last_period, *last_slash;
+        GetModuleFileName(0,module_name,sizeof(module_name)-1);
+        last_period = _mbsrchr(module_name,'.');
+        if (last_period)
+          *last_period ='\0';
+        last_slash = _mbsrchr(module_name,'\\');
+        if (last_slash)
+          strcpy(module_name,last_slash+1);
+        strcat(module_name,": ");
+      }
 #endif
     }
 }
 
+/** @def DBUS_IS_DIR_SEPARATOR(c)
+ * macro for checking if character c is a patch separator
+ * 
+ * @todo move to a header file so that others can use this too
+ */
+#ifdef DBUS_WIN 
+#define DBUS_IS_DIR_SEPARATOR(c) (c == '\\' || c == '/')
+#else
+#define DBUS_IS_DIR_SEPARATOR(c) (c == '/')
+#endif
+
+/** 
+ remove source root from file path 
+ the source root is determined by 
+*/ 
+static char *_dbus_file_path_extract_elements_from_tail(const char *file,int level)
+{
+  int prefix = 0;
+  char *p = (char *)file + strlen(file);
+  int i = 0;
+
+  for (;p >= file;p--)
+    {
+      if (DBUS_IS_DIR_SEPARATOR(*p))
+        {
+          if (++i >= level)
+            {
+              prefix = p-file+1;
+              break;
+            }
+       }
+    }
+
+  return (char *)file+prefix;
+}
+
 /**
  * Implementation of dbus_is_verbose() macro if built with verbose logging
  * enabled.
@@ -347,7 +372,13 @@ _dbus_is_verbose_real (void)
  * @param format printf-style format string.
  */
 void
-_dbus_verbose_real (const char *format,
+_dbus_verbose_real (
+#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
+                    const char *file,
+                    const int line, 
+                    const char *function, 
+#endif
+                    const char *format,
                     ...)
 {
   va_list args;
@@ -379,17 +410,24 @@ _dbus_verbose_real (const char *format,
     need_pid = TRUE;
   else
     need_pid = FALSE;
-  
+
   va_start (args, format);
 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
   {
   char buf[1024];
   strcpy(buf,module_name);
+#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
+  sprintf (buf+strlen(buf), "[%s(%d):%s] ",_dbus_file_path_extract_elements_from_tail(file,2),line,function);
+#endif
   vsprintf (buf+strlen(buf),format, args);
   va_end (args);
-  OutputDebugString(buf);
+  OutputDebugStringA(buf);
   }
 #else
+#ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
+  fprintf (stderr, "[%s(%d):%s] ",_dbus_file_path_extract_elements_from_tail(file,2),line,function);
+#endif
+
   vfprintf (stderr, format, args);
   va_end (args);
 
@@ -409,6 +447,72 @@ _dbus_verbose_reset_real (void)
   verbose_initted = FALSE;
 }
 
+void
+_dbus_trace_ref (const char *obj_name,
+                 void       *obj,
+                 int         old_refcount,
+                 int         new_refcount,
+                 const char *why,
+                 const char *env_var,
+                 int        *enabled)
+{
+  _dbus_assert (obj_name != NULL);
+  _dbus_assert (obj != NULL);
+  _dbus_assert (old_refcount >= -1);
+  _dbus_assert (new_refcount >= -1);
+
+  if (old_refcount == -1)
+    {
+      _dbus_assert (new_refcount == -1);
+    }
+  else
+    {
+      _dbus_assert (new_refcount >= 0);
+      _dbus_assert (old_refcount >= 0);
+      _dbus_assert (old_refcount > 0 || new_refcount > 0);
+    }
+
+  _dbus_assert (why != NULL);
+  _dbus_assert (env_var != NULL);
+  _dbus_assert (enabled != NULL);
+
+  if (*enabled < 0)
+    {
+      const char *s = _dbus_getenv (env_var);
+
+      *enabled = FALSE;
+
+      if (s && *s)
+        {
+          if (*s == '0')
+            *enabled = FALSE;
+          else if (*s == '1')
+            *enabled = TRUE;
+          else
+            _dbus_warn ("%s should be 0 or 1 if set, not '%s'", env_var, s);
+        }
+    }
+
+  if (*enabled)
+    {
+      if (old_refcount == -1)
+        {
+          VALGRIND_PRINTF_BACKTRACE ("%s %p ref stolen (%s)",
+                                     obj_name, obj, why);
+          _dbus_verbose ("%s %p ref stolen (%s)",
+                         obj_name, obj, why);
+        }
+      else
+        {
+          VALGRIND_PRINTF_BACKTRACE ("%s %p %d -> %d refs (%s)",
+                                     obj_name, obj,
+                                     old_refcount, new_refcount, why);
+          _dbus_verbose ("%s %p %d -> %d refs (%s)",
+                         obj_name, obj, old_refcount, new_refcount, why);
+        }
+    }
+}
+
 #endif /* DBUS_ENABLE_VERBOSE_MODE */
 
 /**
@@ -538,7 +642,10 @@ _dbus_generate_uuid (DBusGUID *uuid)
 {
   long now;
 
-  _dbus_get_current_time (&now, NULL);
+  /* don't use monotonic time because the UUID may be saved to disk, e.g.
+   * it may persist across reboots
+   */
+  _dbus_get_real_time (&now, NULL);
 
   uuid->as_uint32s[DBUS_UUID_LENGTH_WORDS - 1] = DBUS_UINT32_TO_BE (now);
   
@@ -659,27 +766,13 @@ _dbus_create_uuid_file_exclusively (const DBusString *filename,
       goto error;
     }
   
-  /* FIXME this is racy; we need a save_file_exclusively
-   * function. But in practice this should be fine for now.
-   *
-   * - first be sure we can create the file and it
-   *   doesn't exist by creating it empty with O_EXCL
-   * - then create it by creating a temporary file and
-   *   overwriting atomically with rename()
-   */
-  if (!_dbus_create_file_exclusively (filename, error))
-    goto error;
-
   if (!_dbus_string_append_byte (&encoded, '\n'))
     {
       _DBUS_SET_OOM (error);
       goto error;
     }
   
-  if (!_dbus_string_save_to_file (&encoded, filename, error))
-    goto error;
-
-  if (!_dbus_make_file_world_readable (filename, error))
+  if (!_dbus_string_save_to_file (&encoded, filename, TRUE, error))
     goto error;
 
   _dbus_string_free (&encoded);
@@ -736,7 +829,7 @@ _dbus_read_uuid_file (const DBusString *filename,
     }
 }
 
-_DBUS_DEFINE_GLOBAL_LOCK (machine_uuid);
+/* Protected by _DBUS_LOCK (machine_uuid) */
 static int machine_uuid_initialized_generation = 0;
 static DBusGUID machine_uuid;
 
@@ -755,7 +848,9 @@ _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str)
 {
   dbus_bool_t ok;
   
-  _DBUS_LOCK (machine_uuid);
+  if (!_DBUS_LOCK (machine_uuid))
+    return FALSE;
+
   if (machine_uuid_initialized_generation != _dbus_current_generation)
     {
       DBusError error = DBUS_ERROR_INIT;
@@ -763,7 +858,7 @@ _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str)
       if (!_dbus_read_local_machine_uuid (&machine_uuid, FALSE,
                                           &error))
         {          
-#ifndef DBUS_BUILD_TESTS
+#ifndef DBUS_ENABLE_EMBEDDED_TESTS
           /* For the test suite, we may not be installed so just continue silently
            * here. But in a production build, we want to be nice and loud about
            * this.
@@ -786,42 +881,6 @@ _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str)
   return ok;
 }
 
-#ifdef DBUS_BUILD_TESTS
-/**
- * Returns a string describing the given name.
- *
- * @param header_field the field to describe
- * @returns a constant string describing the field
- */
-const char *
-_dbus_header_field_to_string (int header_field)
-{
-  switch (header_field)
-    {
-    case DBUS_HEADER_FIELD_INVALID:
-      return "invalid";
-    case DBUS_HEADER_FIELD_PATH:
-      return "path";
-    case DBUS_HEADER_FIELD_INTERFACE:
-      return "interface";
-    case DBUS_HEADER_FIELD_MEMBER:
-      return "member";
-    case DBUS_HEADER_FIELD_ERROR_NAME:
-      return "error-name";
-    case DBUS_HEADER_FIELD_REPLY_SERIAL:
-      return "reply-serial";
-    case DBUS_HEADER_FIELD_DESTINATION:
-      return "destination";
-    case DBUS_HEADER_FIELD_SENDER:
-      return "sender";
-    case DBUS_HEADER_FIELD_SIGNATURE:
-      return "signature";
-    default:
-      return "unknown";
-    }
-}
-#endif /* DBUS_BUILD_TESTS */
-
 #ifndef DBUS_DISABLE_CHECKS
 /** String used in _dbus_return_if_fail macro */
 const char *_dbus_return_if_fail_warning_format =
@@ -878,7 +937,7 @@ _dbus_real_assert_not_reached (const char *explanation,
 }
 #endif /* DBUS_DISABLE_ASSERT */
   
-#ifdef DBUS_BUILD_TESTS
+#ifdef DBUS_ENABLE_EMBEDDED_TESTS
 static dbus_bool_t
 run_failing_each_malloc (int                    n_mallocs,
                          const char            *description,
@@ -973,6 +1032,6 @@ _dbus_test_oom_handling (const char             *description,
 
   return TRUE;
 }
-#endif /* DBUS_BUILD_TESTS */
+#endif /* DBUS_ENABLE_EMBEDDED_TESTS */
 
 /** @} */