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