Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      2 /* dbus-internals.c  random utility stuff (internal to D-Bus implementation)
      3  *
      4  * Copyright (C) 2002, 2003  Red Hat, Inc.
      5  *
      6  * Licensed under the Academic Free License version 2.1
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     21  *
     22  */
     23 
     24 #include <config.h>
     25 #include "dbus-internals.h"
     26 #include "dbus-protocol.h"
     27 #include "dbus-marshal-basic.h"
     28 #include "dbus-test.h"
     29 #include "dbus-valgrind-internal.h"
     30 #include <stdio.h>
     31 #include <stdarg.h>
     32 #include <string.h>
     33 #include <stdlib.h>
     34 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
     35 #include <windows.h>
     36 #include <mbstring.h>
     37 #endif
     38 
     39 #ifdef DBUS_ANDROID_LOG
     40 #define LOG_TAG "libdbus"
     41 #include <cutils/log.h>
     42 #endif /* DBUS_ANDROID_LOG */
     43 
     44 /**
     45  * @defgroup DBusInternals D-Bus secret internal implementation details
     46  * @brief Documentation useful when developing or debugging D-Bus itself.
     47  *
     48  */
     49 
     50 /**
     51  * @defgroup DBusInternalsUtils Utilities and portability
     52  * @ingroup DBusInternals
     53  * @brief Utility functions (_dbus_assert(), _dbus_warn(), etc.)
     54  * @{
     55  */
     56 
     57 /**
     58  * @def _dbus_assert
     59  *
     60  * Aborts with an error message if the condition is false.
     61  *
     62  * @param condition condition which must be true.
     63  */
     64 
     65 /**
     66  * @def _dbus_assert_not_reached
     67  *
     68  * Aborts with an error message if called.
     69  * The given explanation will be printed.
     70  *
     71  * @param explanation explanation of what happened if the code was reached.
     72  */
     73 
     74 /**
     75  * @def _DBUS_N_ELEMENTS
     76  *
     77  * Computes the number of elements in a fixed-size array using
     78  * sizeof().
     79  *
     80  * @param array the array to count elements in.
     81  */
     82 
     83 /**
     84  * @def _DBUS_POINTER_TO_INT
     85  *
     86  * Safely casts a void* to an integer; should only be used on void*
     87  * that actually contain integers, for example one created with
     88  * _DBUS_INT_TO_POINTER.  Only guaranteed to preserve 32 bits.
     89  * (i.e. it's used to store 32-bit ints in pointers, but
     90  * can't be used to store 64-bit pointers in ints.)
     91  *
     92  * @param pointer pointer to extract an integer from.
     93  */
     94 /**
     95  * @def _DBUS_INT_TO_POINTER
     96  *
     97  * Safely stuffs an integer into a pointer, to be extracted later with
     98  * _DBUS_POINTER_TO_INT. Only guaranteed to preserve 32 bits.
     99  *
    100  * @param integer the integer to stuff into a pointer.
    101  */
    102 /**
    103  * @def _DBUS_ZERO
    104  *
    105  * Sets all bits in an object to zero.
    106  *
    107  * @param object the object to be zeroed.
    108  */
    109 /**
    110  * @def _DBUS_INT16_MIN
    111  *
    112  * Minimum value of type "int16"
    113  */
    114 /**
    115  * @def _DBUS_INT16_MAX
    116  *
    117  * Maximum value of type "int16"
    118  */
    119 /**
    120  * @def _DBUS_UINT16_MAX
    121  *
    122  * Maximum value of type "uint16"
    123  */
    124 
    125 /**
    126  * @def _DBUS_INT32_MIN
    127  *
    128  * Minimum value of type "int32"
    129  */
    130 /**
    131  * @def _DBUS_INT32_MAX
    132  *
    133  * Maximum value of type "int32"
    134  */
    135 /**
    136  * @def _DBUS_UINT32_MAX
    137  *
    138  * Maximum value of type "uint32"
    139  */
    140 
    141 /**
    142  * @def _DBUS_INT_MIN
    143  *
    144  * Minimum value of type "int"
    145  */
    146 /**
    147  * @def _DBUS_INT_MAX
    148  *
    149  * Maximum value of type "int"
    150  */
    151 /**
    152  * @def _DBUS_UINT_MAX
    153  *
    154  * Maximum value of type "uint"
    155  */
    156 
    157 /**
    158  * @typedef DBusForeachFunction
    159  *
    160  * Used to iterate over each item in a collection, such as
    161  * a DBusList.
    162  */
    163 
    164 /**
    165  * @def _DBUS_LOCK_NAME
    166  *
    167  * Expands to name of a global lock variable.
    168  */
    169 
    170 /**
    171  * @def _DBUS_DEFINE_GLOBAL_LOCK
    172  *
    173  * Defines a global lock variable with the given name.
    174  * The lock must be added to the list to initialize
    175  * in dbus_threads_init().
    176  */
    177 
    178 /**
    179  * @def _DBUS_DECLARE_GLOBAL_LOCK
    180  *
    181  * Expands to declaration of a global lock defined
    182  * with _DBUS_DEFINE_GLOBAL_LOCK.
    183  * The lock must be added to the list to initialize
    184  * in dbus_threads_init().
    185  */
    186 
    187 /**
    188  * @def _DBUS_LOCK
    189  *
    190  * Locks a global lock
    191  */
    192 
    193 /**
    194  * @def _DBUS_UNLOCK
    195  *
    196  * Unlocks a global lock
    197  */
    198 
    199 /**
    200  * Fixed "out of memory" error message, just to avoid
    201  * making up a different string every time and wasting
    202  * space.
    203  */
    204 const char *_dbus_no_memory_message = "Not enough memory";
    205 
    206 static dbus_bool_t warn_initted = FALSE;
    207 static dbus_bool_t fatal_warnings = FALSE;
    208 static dbus_bool_t fatal_warnings_on_check_failed = TRUE;
    209 
    210 static void
    211 init_warnings(void)
    212 {
    213   if (!warn_initted)
    214     {
    215       const char *s;
    216       s = _dbus_getenv ("DBUS_FATAL_WARNINGS");
    217       if (s && *s)
    218         {
    219           if (*s == '0')
    220             {
    221               fatal_warnings = FALSE;
    222               fatal_warnings_on_check_failed = FALSE;
    223             }
    224           else if (*s == '1')
    225             {
    226               fatal_warnings = TRUE;
    227               fatal_warnings_on_check_failed = TRUE;
    228             }
    229           else
    230             {
    231               fprintf(stderr, "DBUS_FATAL_WARNINGS should be set to 0 or 1 if set, not '%s'",
    232                       s);
    233             }
    234         }
    235 
    236       warn_initted = TRUE;
    237     }
    238 }
    239 
    240 /**
    241  * Prints a warning message to stderr. Can optionally be made to exit
    242  * fatally by setting DBUS_FATAL_WARNINGS, but this is rarely
    243  * used. This function should be considered pretty much equivalent to
    244  * fprintf(stderr). _dbus_warn_check_failed() on the other hand is
    245  * suitable for use when a programming mistake has been made.
    246  *
    247  * @param format printf-style format string.
    248  */
    249 void
    250 _dbus_warn (const char *format,
    251             ...)
    252 {
    253   va_list args;
    254 
    255   if (!warn_initted)
    256     init_warnings ();
    257 
    258   va_start (args, format);
    259 #ifdef DBUS_ANDROID_LOG
    260   LOG_PRI_VA(ANDROID_LOG_WARN, LOG_TAG, format, args);
    261 #else
    262   vfprintf (stderr, format, args);
    263 #endif /* DBUS_ANDROID_LOG */
    264   va_end (args);
    265 
    266   if (fatal_warnings)
    267     {
    268       fflush (stderr);
    269       _dbus_abort ();
    270     }
    271 }
    272 
    273 /**
    274  * Prints a "critical" warning to stderr when an assertion fails;
    275  * differs from _dbus_warn primarily in that it prefixes the pid and
    276  * defaults to fatal. This should be used only when a programming
    277  * error has been detected. (NOT for unavoidable errors that an app
    278  * might handle - those should be returned as DBusError.) Calling this
    279  * means "there is a bug"
    280  */
    281 void
    282 _dbus_warn_check_failed(const char *format,
    283                         ...)
    284 {
    285   va_list args;
    286 
    287   if (!warn_initted)
    288     init_warnings ();
    289 
    290   fprintf (stderr, "process %lu: ", _dbus_pid_for_log ());
    291 
    292   va_start (args, format);
    293 #ifdef DBUS_ANDROID_LOG
    294   LOG_PRI_VA(ANDROID_LOG_ERROR, LOG_TAG, format, args);
    295 #else
    296   vfprintf (stderr, format, args);
    297 #endif /* DBUS_ANDROID_LOG */
    298   va_end (args);
    299 
    300   if (fatal_warnings_on_check_failed)
    301     {
    302       fflush (stderr);
    303       _dbus_abort ();
    304     }
    305 }
    306 
    307 #ifdef DBUS_ENABLE_VERBOSE_MODE
    308 
    309 static dbus_bool_t verbose_initted = FALSE;
    310 static dbus_bool_t verbose = TRUE;
    311 
    312 /** Whether to show the current thread in verbose messages */
    313 #define PTHREAD_IN_VERBOSE 0
    314 #if PTHREAD_IN_VERBOSE
    315 #include <pthread.h>
    316 #endif
    317 
    318 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
    319 static char module_name[1024];
    320 #endif
    321 
    322 static inline void
    323 _dbus_verbose_init (void)
    324 {
    325   if (!verbose_initted)
    326     {
    327 #ifdef DBUS_ANDROID_LOG
    328       /* Don't bother checking environment variable - just print the
    329          verbose logs (can still be disabled with DBUS_ENABLE_VERBOSE_MODE) */
    330       verbose = TRUE;
    331 #else
    332       const char *p = _dbus_getenv ("DBUS_VERBOSE");
    333       verbose = p != NULL && *p == '1';
    334 #endif
    335       verbose_initted = TRUE;
    336 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
    337       {
    338         char *last_period, *last_slash;
    339         GetModuleFileName(0,module_name,sizeof(module_name)-1);
    340         last_period = _mbsrchr(module_name,'.');
    341         if (last_period)
    342           *last_period ='\0';
    343         last_slash = _mbsrchr(module_name,'\\');
    344         if (last_slash)
    345           strcpy(module_name,last_slash+1);
    346         strcat(module_name,": ");
    347       }
    348 #endif
    349     }
    350 }
    351 
    352 /** @def DBUS_IS_DIR_SEPARATOR(c)
    353  * macro for checking if character c is a patch separator
    354  *
    355  * @todo move to a header file so that others can use this too
    356  */
    357 #ifdef DBUS_WIN
    358 #define DBUS_IS_DIR_SEPARATOR(c) (c == '\\' || c == '/')
    359 #else
    360 #define DBUS_IS_DIR_SEPARATOR(c) (c == '/')
    361 #endif
    362 
    363 /**
    364  remove source root from file path
    365  the source root is determined by
    366 */
    367 static char *_dbus_file_path_extract_elements_from_tail(const char *file,int level)
    368 {
    369   static int prefix = -1;
    370 
    371   if (prefix == -1)
    372     {
    373       char *p = (char *)file + strlen(file);
    374       int i = 0;
    375       prefix = 0;
    376       for (;p >= file;p--)
    377         {
    378           if (DBUS_IS_DIR_SEPARATOR(*p))
    379             {
    380               if (++i >= level)
    381                 {
    382                   prefix = p-file+1;
    383                   break;
    384                 }
    385            }
    386         }
    387     }
    388   return (char *)file+prefix;
    389 }
    390 
    391 /**
    392  * Implementation of dbus_is_verbose() macro if built with verbose logging
    393  * enabled.
    394  * @returns whether verbose logging is active.
    395  */
    396 dbus_bool_t
    397 _dbus_is_verbose_real (void)
    398 {
    399   _dbus_verbose_init ();
    400   return verbose;
    401 }
    402 
    403 /**
    404  * Prints a warning message to stderr
    405  * if the user has enabled verbose mode.
    406  * This is the real function implementation,
    407  * use _dbus_verbose() macro in code.
    408  *
    409  * @param format printf-style format string.
    410  */
    411 void
    412 _dbus_verbose_real (
    413 #ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
    414                     const char *file,
    415                     const int line,
    416                     const char *function,
    417 #endif
    418                     const char *format,
    419                     ...)
    420 {
    421   va_list args;
    422   static dbus_bool_t need_pid = TRUE;
    423   int len;
    424 
    425   /* things are written a bit oddly here so that
    426    * in the non-verbose case we just have the one
    427    * conditional and return immediately.
    428    */
    429   if (!_dbus_is_verbose_real())
    430     return;
    431 
    432 #ifndef DBUS_USE_OUTPUT_DEBUG_STRING
    433   /* Print out pid before the line */
    434   if (need_pid)
    435     {
    436 #if PTHREAD_IN_VERBOSE
    437       fprintf (stderr, "%lu: 0x%lx: ", _dbus_pid_for_log (), pthread_self ());
    438 #else
    439       fprintf (stderr, "%lu: ", _dbus_pid_for_log ());
    440 #endif
    441     }
    442 #endif
    443 
    444   /* Only print pid again if the next line is a new line */
    445   len = strlen (format);
    446   if (format[len-1] == '\n')
    447     need_pid = TRUE;
    448   else
    449     need_pid = FALSE;
    450 
    451   va_start (args, format);
    452 #ifdef DBUS_USE_OUTPUT_DEBUG_STRING
    453   {
    454   char buf[1024];
    455   strcpy(buf,module_name);
    456 #ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
    457   sprintf (buf+strlen(buf), "[%s(%d):%s] ",_dbus_file_path_extract_elements_from_tail(file,2),line,function);
    458 #endif
    459   vsprintf (buf+strlen(buf),format, args);
    460   va_end (args);
    461   OutputDebugStringA(buf);
    462   }
    463 #else
    464 #ifdef DBUS_CPP_SUPPORTS_VARIABLE_MACRO_ARGUMENTS
    465   fprintf (stderr, "[%s(%d):%s] ",_dbus_file_path_extract_elements_from_tail(file,2),line,function);
    466 #endif
    467 
    468 #ifdef DBUS_ANDROID_LOG
    469   LOG_PRI_VA(ANDROID_LOG_DEBUG, LOG_TAG, format, args);
    470 #else
    471   vfprintf (stderr, format, args);
    472 #endif /* DBUS_ANDROID_LOG */
    473   va_end (args);
    474 
    475   fflush (stderr);
    476 #endif
    477 }
    478 
    479 /**
    480  * Reinitializes the verbose logging code, used
    481  * as a hack in dbus-spawn.c so that a child
    482  * process re-reads its pid
    483  *
    484  */
    485 void
    486 _dbus_verbose_reset_real (void)
    487 {
    488   verbose_initted = FALSE;
    489 }
    490 
    491 void
    492 _dbus_trace_ref (const char *obj_name,
    493                  void       *obj,
    494                  int         old_refcount,
    495                  int         new_refcount,
    496                  const char *why,
    497                  const char *env_var,
    498                  int        *enabled)
    499 {
    500   _dbus_assert (obj_name != NULL);
    501   _dbus_assert (obj != NULL);
    502   _dbus_assert (old_refcount >= -1);
    503   _dbus_assert (new_refcount >= -1);
    504 
    505   if (old_refcount == -1)
    506     {
    507       _dbus_assert (new_refcount == -1);
    508     }
    509   else
    510     {
    511       _dbus_assert (new_refcount >= 0);
    512       _dbus_assert (old_refcount >= 0);
    513       _dbus_assert (old_refcount > 0 || new_refcount > 0);
    514     }
    515 
    516   _dbus_assert (why != NULL);
    517   _dbus_assert (env_var != NULL);
    518   _dbus_assert (enabled != NULL);
    519 
    520   if (*enabled < 0)
    521     {
    522       const char *s = _dbus_getenv (env_var);
    523 
    524       *enabled = FALSE;
    525 
    526       if (s && *s)
    527         {
    528           if (*s == '0')
    529             *enabled = FALSE;
    530           else if (*s == '1')
    531             *enabled = TRUE;
    532           else
    533             _dbus_warn ("%s should be 0 or 1 if set, not '%s'", env_var, s);
    534         }
    535     }
    536 
    537   if (*enabled)
    538     {
    539       if (old_refcount == -1)
    540         {
    541           VALGRIND_PRINTF_BACKTRACE ("%s %p ref stolen (%s)",
    542                                      obj_name, obj, why);
    543           _dbus_verbose ("%s %p ref stolen (%s)",
    544                          obj_name, obj, why);
    545         }
    546       else
    547         {
    548           VALGRIND_PRINTF_BACKTRACE ("%s %p %d -> %d refs (%s)",
    549                                      obj_name, obj,
    550                                      old_refcount, new_refcount, why);
    551           _dbus_verbose ("%s %p %d -> %d refs (%s)",
    552                          obj_name, obj, old_refcount, new_refcount, why);
    553         }
    554     }
    555 }
    556 
    557 #endif /* DBUS_ENABLE_VERBOSE_MODE */
    558 
    559 /**
    560  * Duplicates a string. Result must be freed with
    561  * dbus_free(). Returns #NULL if memory allocation fails.
    562  * If the string to be duplicated is #NULL, returns #NULL.
    563  *
    564  * @param str string to duplicate.
    565  * @returns newly-allocated copy.
    566  */
    567 char*
    568 _dbus_strdup (const char *str)
    569 {
    570   size_t len;
    571   char *copy;
    572 
    573   if (str == NULL)
    574     return NULL;
    575 
    576   len = strlen (str);
    577 
    578   copy = dbus_malloc (len + 1);
    579   if (copy == NULL)
    580     return NULL;
    581 
    582   memcpy (copy, str, len + 1);
    583 
    584   return copy;
    585 }
    586 
    587 /**
    588  * Duplicates a block of memory. Returns
    589  * #NULL on failure.
    590  *
    591  * @param mem memory to copy
    592  * @param n_bytes number of bytes to copy
    593  * @returns the copy
    594  */
    595 void*
    596 _dbus_memdup (const void  *mem,
    597               size_t       n_bytes)
    598 {
    599   void *copy;
    600 
    601   copy = dbus_malloc (n_bytes);
    602   if (copy == NULL)
    603     return NULL;
    604 
    605   memcpy (copy, mem, n_bytes);
    606 
    607   return copy;
    608 }
    609 
    610 /**
    611  * Duplicates a string array. Result may be freed with
    612  * dbus_free_string_array(). Returns #NULL if memory allocation fails.
    613  * If the array to be duplicated is #NULL, returns #NULL.
    614  *
    615  * @param array array to duplicate.
    616  * @returns newly-allocated copy.
    617  */
    618 char**
    619 _dbus_dup_string_array (const char **array)
    620 {
    621   int len;
    622   int i;
    623   char **copy;
    624 
    625   if (array == NULL)
    626     return NULL;
    627 
    628   for (len = 0; array[len] != NULL; ++len)
    629     ;
    630 
    631   copy = dbus_new0 (char*, len + 1);
    632   if (copy == NULL)
    633     return NULL;
    634 
    635   i = 0;
    636   while (i < len)
    637     {
    638       copy[i] = _dbus_strdup (array[i]);
    639       if (copy[i] == NULL)
    640         {
    641           dbus_free_string_array (copy);
    642           return NULL;
    643         }
    644 
    645       ++i;
    646     }
    647 
    648   return copy;
    649 }
    650 
    651 /**
    652  * Checks whether a string array contains the given string.
    653  *
    654  * @param array array to search.
    655  * @param str string to look for
    656  * @returns #TRUE if array contains string
    657  */
    658 dbus_bool_t
    659 _dbus_string_array_contains (const char **array,
    660                              const char  *str)
    661 {
    662   int i;
    663 
    664   i = 0;
    665   while (array[i] != NULL)
    666     {
    667       if (strcmp (array[i], str) == 0)
    668         return TRUE;
    669       ++i;
    670     }
    671 
    672   return FALSE;
    673 }
    674 
    675 /**
    676  * Generates a new UUID. If you change how this is done,
    677  * there's some text about it in the spec that should also change.
    678  *
    679  * @param uuid the uuid to initialize
    680  */
    681 void
    682 _dbus_generate_uuid (DBusGUID *uuid)
    683 {
    684   long now;
    685 
    686   /* don't use monotonic time because the UUID may be saved to disk, e.g.
    687    * it may persist across reboots
    688    */
    689   _dbus_get_real_time (&now, NULL);
    690 
    691   uuid->as_uint32s[DBUS_UUID_LENGTH_WORDS - 1] = DBUS_UINT32_TO_BE (now);
    692 
    693   _dbus_generate_random_bytes_buffer (uuid->as_bytes, DBUS_UUID_LENGTH_BYTES - 4);
    694 }
    695 
    696 /**
    697  * Hex-encode a UUID.
    698  *
    699  * @param uuid the uuid
    700  * @param encoded string to append hex uuid to
    701  * @returns #FALSE if no memory
    702  */
    703 dbus_bool_t
    704 _dbus_uuid_encode (const DBusGUID *uuid,
    705                    DBusString     *encoded)
    706 {
    707   DBusString binary;
    708   _dbus_string_init_const_len (&binary, uuid->as_bytes, DBUS_UUID_LENGTH_BYTES);
    709   return _dbus_string_hex_encode (&binary, 0, encoded, _dbus_string_get_length (encoded));
    710 }
    711 
    712 static dbus_bool_t
    713 _dbus_read_uuid_file_without_creating (const DBusString *filename,
    714                                        DBusGUID         *uuid,
    715                                        DBusError        *error)
    716 {
    717   DBusString contents;
    718   DBusString decoded;
    719   int end;
    720 
    721   if (!_dbus_string_init (&contents))
    722     {
    723       _DBUS_SET_OOM (error);
    724       return FALSE;
    725     }
    726 
    727   if (!_dbus_string_init (&decoded))
    728     {
    729       _dbus_string_free (&contents);
    730       _DBUS_SET_OOM (error);
    731       return FALSE;
    732     }
    733 
    734   if (!_dbus_file_get_contents (&contents, filename, error))
    735     goto error;
    736 
    737   _dbus_string_chop_white (&contents);
    738 
    739   if (_dbus_string_get_length (&contents) != DBUS_UUID_LENGTH_HEX)
    740     {
    741       dbus_set_error (error, DBUS_ERROR_INVALID_FILE_CONTENT,
    742                       "UUID file '%s' should contain a hex string of length %d, not length %d, with no other text",
    743                       _dbus_string_get_const_data (filename),
    744                       DBUS_UUID_LENGTH_HEX,
    745                       _dbus_string_get_length (&contents));
    746       goto error;
    747     }
    748 
    749   if (!_dbus_string_hex_decode (&contents, 0, &end, &decoded, 0))
    750     {
    751       _DBUS_SET_OOM (error);
    752       goto error;
    753     }
    754 
    755   if (end == 0)
    756     {
    757       dbus_set_error (error, DBUS_ERROR_INVALID_FILE_CONTENT,
    758                       "UUID file '%s' contains invalid hex data",
    759                       _dbus_string_get_const_data (filename));
    760       goto error;
    761     }
    762 
    763   if (_dbus_string_get_length (&decoded) != DBUS_UUID_LENGTH_BYTES)
    764     {
    765       dbus_set_error (error, DBUS_ERROR_INVALID_FILE_CONTENT,
    766                       "UUID file '%s' contains %d bytes of hex-encoded data instead of %d",
    767                       _dbus_string_get_const_data (filename),
    768                       _dbus_string_get_length (&decoded),
    769                       DBUS_UUID_LENGTH_BYTES);
    770       goto error;
    771     }
    772 
    773   _dbus_string_copy_to_buffer (&decoded, uuid->as_bytes, DBUS_UUID_LENGTH_BYTES);
    774 
    775   _dbus_string_free (&decoded);
    776   _dbus_string_free (&contents);
    777 
    778   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    779 
    780   return TRUE;
    781 
    782  error:
    783   _DBUS_ASSERT_ERROR_IS_SET (error);
    784   _dbus_string_free (&contents);
    785   _dbus_string_free (&decoded);
    786   return FALSE;
    787 }
    788 
    789 static dbus_bool_t
    790 _dbus_create_uuid_file_exclusively (const DBusString *filename,
    791                                     DBusGUID         *uuid,
    792                                     DBusError        *error)
    793 {
    794   DBusString encoded;
    795 
    796   if (!_dbus_string_init (&encoded))
    797     {
    798       _DBUS_SET_OOM (error);
    799       return FALSE;
    800     }
    801 
    802   _dbus_generate_uuid (uuid);
    803 
    804   if (!_dbus_uuid_encode (uuid, &encoded))
    805     {
    806       _DBUS_SET_OOM (error);
    807       goto error;
    808     }
    809 
    810   if (!_dbus_string_append_byte (&encoded, '\n'))
    811     {
    812       _DBUS_SET_OOM (error);
    813       goto error;
    814     }
    815 
    816   if (!_dbus_string_save_to_file (&encoded, filename, TRUE, error))
    817     goto error;
    818 
    819   _dbus_string_free (&encoded);
    820 
    821   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    822   return TRUE;
    823 
    824  error:
    825   _DBUS_ASSERT_ERROR_IS_SET (error);
    826   _dbus_string_free (&encoded);
    827   return FALSE;
    828 }
    829 
    830 /**
    831  * Reads (and optionally writes) a uuid to a file. Initializes the uuid
    832  * unless an error is returned.
    833  *
    834  * @param filename the name of the file
    835  * @param uuid uuid to be initialized with the loaded uuid
    836  * @param create_if_not_found #TRUE to create a new uuid and save it if the file doesn't exist
    837  * @param error the error return
    838  * @returns #FALSE if the error is set
    839  */
    840 dbus_bool_t
    841 _dbus_read_uuid_file (const DBusString *filename,
    842                       DBusGUID         *uuid,
    843                       dbus_bool_t       create_if_not_found,
    844                       DBusError        *error)
    845 {
    846   DBusError read_error = DBUS_ERROR_INIT;
    847 
    848   if (_dbus_read_uuid_file_without_creating (filename, uuid, &read_error))
    849     return TRUE;
    850 
    851   if (!create_if_not_found)
    852     {
    853       dbus_move_error (&read_error, error);
    854       return FALSE;
    855     }
    856 
    857   /* If the file exists and contains junk, we want to keep that error
    858    * message instead of overwriting it with a "file exists" error
    859    * message when we try to write
    860    */
    861   if (dbus_error_has_name (&read_error, DBUS_ERROR_INVALID_FILE_CONTENT))
    862     {
    863       dbus_move_error (&read_error, error);
    864       return FALSE;
    865     }
    866   else
    867     {
    868       dbus_error_free (&read_error);
    869       return _dbus_create_uuid_file_exclusively (filename, uuid, error);
    870     }
    871 }
    872 
    873 _DBUS_DEFINE_GLOBAL_LOCK (machine_uuid);
    874 static int machine_uuid_initialized_generation = 0;
    875 static DBusGUID machine_uuid;
    876 
    877 /**
    878  * Gets the hex-encoded UUID of the machine this function is
    879  * executed on. This UUID is guaranteed to be the same for a given
    880  * machine at least until it next reboots, though it also
    881  * makes some effort to be the same forever, it may change if the
    882  * machine is reconfigured or its hardware is modified.
    883  *
    884  * @param uuid_str string to append hex-encoded machine uuid to
    885  * @returns #FALSE if no memory
    886  */
    887 dbus_bool_t
    888 _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str)
    889 {
    890   dbus_bool_t ok;
    891 
    892   _DBUS_LOCK (machine_uuid);
    893   if (machine_uuid_initialized_generation != _dbus_current_generation)
    894     {
    895       DBusError error = DBUS_ERROR_INIT;
    896 
    897       if (!_dbus_read_local_machine_uuid (&machine_uuid, FALSE,
    898                                           &error))
    899         {
    900 #ifndef DBUS_BUILD_TESTS
    901           /* For the test suite, we may not be installed so just continue silently
    902            * here. But in a production build, we want to be nice and loud about
    903            * this.
    904            */
    905           _dbus_warn_check_failed ("D-Bus library appears to be incorrectly set up; failed to read machine uuid: %s\n"
    906                                    "See the manual page for dbus-uuidgen to correct this issue.\n",
    907                                    error.message);
    908 #endif
    909 
    910           dbus_error_free (&error);
    911 
    912           _dbus_generate_uuid (&machine_uuid);
    913         }
    914     }
    915 
    916   ok = _dbus_uuid_encode (&machine_uuid, uuid_str);
    917 
    918   _DBUS_UNLOCK (machine_uuid);
    919 
    920   return ok;
    921 }
    922 
    923 #ifndef DBUS_DISABLE_CHECKS
    924 /** String used in _dbus_return_if_fail macro */
    925 const char *_dbus_return_if_fail_warning_format =
    926 "arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\n"
    927 "This is normally a bug in some application using the D-Bus library.\n";
    928 #endif
    929 
    930 #ifndef DBUS_DISABLE_ASSERT
    931 /**
    932  * Internals of _dbus_assert(); it's a function
    933  * rather than a macro with the inline code so
    934  * that the assertion failure blocks don't show up
    935  * in test suite coverage, and to shrink code size.
    936  *
    937  * @param condition TRUE if assertion succeeded
    938  * @param condition_text condition as a string
    939  * @param file file the assertion is in
    940  * @param line line the assertion is in
    941  * @param func function the assertion is in
    942  */
    943 void
    944 _dbus_real_assert (dbus_bool_t  condition,
    945                    const char  *condition_text,
    946                    const char  *file,
    947                    int          line,
    948                    const char  *func)
    949 {
    950   if (_DBUS_UNLIKELY (!condition))
    951     {
    952       _dbus_warn ("%lu: assertion failed \"%s\" file \"%s\" line %d function %s\n",
    953                   _dbus_pid_for_log (), condition_text, file, line, func);
    954       _dbus_abort ();
    955     }
    956 }
    957 
    958 /**
    959  * Internals of _dbus_assert_not_reached(); it's a function
    960  * rather than a macro with the inline code so
    961  * that the assertion failure blocks don't show up
    962  * in test suite coverage, and to shrink code size.
    963  *
    964  * @param explanation what was reached that shouldn't have been
    965  * @param file file the assertion is in
    966  * @param line line the assertion is in
    967  */
    968 void
    969 _dbus_real_assert_not_reached (const char *explanation,
    970                                const char *file,
    971                                int         line)
    972 {
    973   _dbus_warn ("File \"%s\" line %d process %lu should not have been reached: %s\n",
    974               file, line, _dbus_pid_for_log (), explanation);
    975   _dbus_abort ();
    976 }
    977 #endif /* DBUS_DISABLE_ASSERT */
    978 
    979 #ifdef DBUS_BUILD_TESTS
    980 static dbus_bool_t
    981 run_failing_each_malloc (int                    n_mallocs,
    982                          const char            *description,
    983                          DBusTestMemoryFunction func,
    984                          void                  *data)
    985 {
    986   n_mallocs += 10; /* fudge factor to ensure reallocs etc. are covered */
    987 
    988   while (n_mallocs >= 0)
    989     {
    990       _dbus_set_fail_alloc_counter (n_mallocs);
    991 
    992       _dbus_verbose ("\n===\n%s: (will fail malloc %d with %d failures)\n===\n",
    993                      description, n_mallocs,
    994                      _dbus_get_fail_alloc_failures ());
    995 
    996       if (!(* func) (data))
    997         return FALSE;
    998 
    999       n_mallocs -= 1;
   1000     }
   1001 
   1002   _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
   1003 
   1004   return TRUE;
   1005 }
   1006 
   1007 /**
   1008  * Tests how well the given function responds to out-of-memory
   1009  * situations. Calls the function repeatedly, failing a different
   1010  * call to malloc() each time. If the function ever returns #FALSE,
   1011  * the test fails. The function should return #TRUE whenever something
   1012  * valid (such as returning an error, or succeeding) occurs, and #FALSE
   1013  * if it gets confused in some way.
   1014  *
   1015  * @param description description of the test used in verbose output
   1016  * @param func function to call
   1017  * @param data data to pass to function
   1018  * @returns #TRUE if the function never returns FALSE
   1019  */
   1020 dbus_bool_t
   1021 _dbus_test_oom_handling (const char             *description,
   1022                          DBusTestMemoryFunction  func,
   1023                          void                   *data)
   1024 {
   1025   int approx_mallocs;
   1026   const char *setting;
   1027   int max_failures_to_try;
   1028   int i;
   1029 
   1030   /* Run once to see about how many mallocs are involved */
   1031 
   1032   _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
   1033 
   1034   _dbus_verbose ("Running once to count mallocs\n");
   1035 
   1036   if (!(* func) (data))
   1037     return FALSE;
   1038 
   1039   approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter ();
   1040 
   1041   _dbus_verbose ("\n=================\n%s: about %d mallocs total\n=================\n",
   1042                  description, approx_mallocs);
   1043 
   1044   setting = _dbus_getenv ("DBUS_TEST_MALLOC_FAILURES");
   1045   if (setting != NULL)
   1046     {
   1047       DBusString str;
   1048       long v;
   1049       _dbus_string_init_const (&str, setting);
   1050       v = 4;
   1051       if (!_dbus_string_parse_int (&str, 0, &v, NULL))
   1052         _dbus_warn ("couldn't parse '%s' as integer\n", setting);
   1053       max_failures_to_try = v;
   1054     }
   1055   else
   1056     {
   1057       max_failures_to_try = 4;
   1058     }
   1059 
   1060   i = setting ? max_failures_to_try - 1 : 1;
   1061   while (i < max_failures_to_try)
   1062     {
   1063       _dbus_set_fail_alloc_failures (i);
   1064       if (!run_failing_each_malloc (approx_mallocs, description, func, data))
   1065         return FALSE;
   1066       ++i;
   1067     }
   1068 
   1069   _dbus_verbose ("\n=================\n%s: all iterations passed\n=================\n",
   1070                  description);
   1071 
   1072   return TRUE;
   1073 }
   1074 #endif /* DBUS_BUILD_TESTS */
   1075 
   1076 /** @} */
   1077