Main Page | Modules | Data Structures | Directories | File List | Data Fields | Related Pages

dbus-internals.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-internals.c  random utility stuff (internal to D-BUS implementation)
00003  *
00004  * Copyright (C) 2002, 2003  Red Hat, Inc.
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 #include "dbus-internals.h"
00024 #include "dbus-protocol.h"
00025 #include "dbus-test.h"
00026 #include <stdio.h>
00027 #include <stdarg.h>
00028 #include <string.h>
00029 #include <sys/types.h>
00030 #include <errno.h>
00031 #include <unistd.h>
00032 #include <fcntl.h>
00033 #include <stdlib.h>
00034 
00158 const char _dbus_no_memory_message[] = "Not enough memory";
00159 
00165 void
00166 _dbus_warn (const char *format,
00167             ...)
00168 {
00169   /* FIXME not portable enough? */
00170   va_list args;
00171 
00172   va_start (args, format);
00173   vfprintf (stderr, format, args);
00174   va_end (args);
00175 }
00176 
00177 static dbus_bool_t verbose_initted = FALSE;
00178 
00187 void
00188 _dbus_verbose_real (const char *format,
00189                     ...)
00190 {
00191   va_list args;
00192   static dbus_bool_t verbose = TRUE;
00193   static dbus_bool_t need_pid = TRUE;
00194   int len;
00195   
00196   /* things are written a bit oddly here so that
00197    * in the non-verbose case we just have the one
00198    * conditional and return immediately.
00199    */
00200   if (!verbose)
00201     return;
00202   
00203   if (!verbose_initted)
00204     {
00205       verbose = _dbus_getenv ("DBUS_VERBOSE") != NULL;
00206       verbose_initted = TRUE;
00207       if (!verbose)
00208         return;
00209     }
00210 
00211   /* Print out pid before the line */
00212   if (need_pid)
00213     fprintf (stderr, "%lu: ", _dbus_getpid ());
00214 
00215   /* Only print pid again if the next line is a new line */
00216   len = strlen (format);
00217   if (format[len-1] == '\n')
00218     need_pid = TRUE;
00219   else
00220     need_pid = FALSE;
00221   
00222   va_start (args, format);
00223   vfprintf (stderr, format, args);
00224   va_end (args);
00225 
00226   fflush (stderr);
00227 }
00228 
00235 void
00236 _dbus_verbose_reset_real (void)
00237 {
00238   verbose_initted = FALSE;
00239 }
00240 
00249 char*
00250 _dbus_strdup (const char *str)
00251 {
00252   size_t len;
00253   char *copy;
00254   
00255   if (str == NULL)
00256     return NULL;
00257   
00258   len = strlen (str);
00259 
00260   copy = dbus_malloc (len + 1);
00261   if (copy == NULL)
00262     return NULL;
00263 
00264   memcpy (copy, str, len + 1);
00265   
00266   return copy;
00267 }
00268 
00277 void*
00278 _dbus_memdup (const void  *mem,
00279               size_t       n_bytes)
00280 {
00281   void *copy;
00282 
00283   copy = dbus_malloc (n_bytes);
00284   if (copy == NULL)
00285     return NULL;
00286 
00287   memcpy (copy, mem, n_bytes);
00288   
00289   return copy;
00290 }
00291 
00300 char**
00301 _dbus_dup_string_array (const char **array)
00302 {
00303   int len;
00304   int i;
00305   char **copy;
00306   
00307   if (array == NULL)
00308     return NULL;
00309 
00310   for (len = 0; array[len] != NULL; ++len)
00311     ;
00312 
00313   copy = dbus_new0 (char*, len + 1);
00314   if (copy == NULL)
00315     return NULL;
00316 
00317   i = 0;
00318   while (i < len)
00319     {
00320       copy[i] = _dbus_strdup (array[i]);
00321       if (copy[i] == NULL)
00322         {
00323           dbus_free_string_array (copy);
00324           return NULL;
00325         }
00326 
00327       ++i;
00328     }
00329 
00330   return copy;
00331 }
00332 
00340 dbus_bool_t
00341 _dbus_string_array_contains (const char **array,
00342                              const char  *str)
00343 {
00344   int i;
00345 
00346   i = 0;
00347   while (array[i] != NULL)
00348     {
00349       if (strcmp (array[i], str) == 0)
00350         return TRUE;
00351       ++i;
00352     }
00353 
00354   return FALSE;
00355 }
00356 
00363 const char *
00364 _dbus_type_to_string (int type)
00365 {
00366   switch (type)
00367     {
00368     case DBUS_TYPE_INVALID:
00369       return "invalid";
00370     case DBUS_TYPE_NIL:
00371       return "nil";
00372     case DBUS_TYPE_BOOLEAN:
00373       return "boolean";
00374     case DBUS_TYPE_INT32:
00375       return "int32";
00376     case DBUS_TYPE_UINT32:
00377       return "uint32";
00378     case DBUS_TYPE_DOUBLE:
00379       return "double";
00380     case DBUS_TYPE_STRING:
00381       return "string";
00382     case DBUS_TYPE_CUSTOM:
00383       return "custom";
00384     case DBUS_TYPE_ARRAY:
00385       return "array";
00386     case DBUS_TYPE_DICT:
00387       return "dict";
00388     default:
00389       return "unknown";
00390     }
00391 }
00392 
00399 const char *
00400 _dbus_header_field_to_string (int header_field)
00401 {
00402   switch (header_field)
00403     {
00404     case DBUS_HEADER_FIELD_INVALID:
00405       return "invalid";
00406     case DBUS_HEADER_FIELD_PATH:
00407       return "path";
00408     case DBUS_HEADER_FIELD_INTERFACE:
00409       return "interface";
00410     case DBUS_HEADER_FIELD_MEMBER:
00411       return "member";
00412     case DBUS_HEADER_FIELD_ERROR_NAME:
00413       return "error-name";
00414     case DBUS_HEADER_FIELD_REPLY_SERIAL:
00415       return "reply-serial";
00416     case DBUS_HEADER_FIELD_DESTINATION:
00417       return "destination";
00418     case DBUS_HEADER_FIELD_SENDER:
00419       return "sender";
00420     case DBUS_HEADER_FIELD_SIGNATURE:
00421       return "signature";
00422     default:
00423       return "unknown";
00424     }
00425 }
00426 
00427 #ifndef DBUS_DISABLE_CHECKS
00428 
00429 const char _dbus_return_if_fail_warning_format[] =
00430 "%lu: arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\n"
00431 "This is normally a bug in some application using the D-BUS library.\n";
00432 #endif
00433 
00434 #ifndef DBUS_DISABLE_ASSERT
00435 
00446 void
00447 _dbus_real_assert (dbus_bool_t  condition,
00448                    const char  *condition_text,
00449                    const char  *file,
00450                    int          line)
00451 {
00452   if (_DBUS_UNLIKELY (!condition))
00453     {
00454       _dbus_warn ("%lu: assertion failed \"%s\" file \"%s\" line %d\n",
00455                   _dbus_getpid (), condition_text, file, line);
00456       _dbus_abort ();
00457     }
00458 }
00459 
00470 void
00471 _dbus_real_assert_not_reached (const char *explanation,
00472                                const char *file,
00473                                int         line)
00474 {
00475   _dbus_warn ("File \"%s\" line %d process %lu should not have been reached: %s\n",
00476               file, line, _dbus_getpid (), explanation);
00477   _dbus_abort ();
00478 }
00479 #endif /* DBUS_DISABLE_ASSERT */
00480   
00481 #ifdef DBUS_BUILD_TESTS
00482 static dbus_bool_t
00483 run_failing_each_malloc (int                    n_mallocs,
00484                          const char            *description,
00485                          DBusTestMemoryFunction func,
00486                          void                  *data)
00487 {
00488   n_mallocs += 10; /* fudge factor to ensure reallocs etc. are covered */
00489   
00490   while (n_mallocs >= 0)
00491     {      
00492       _dbus_set_fail_alloc_counter (n_mallocs);
00493 
00494       _dbus_verbose ("\n===\n%s: (will fail malloc %d with %d failures)\n===\n",
00495                      description, n_mallocs,
00496                      _dbus_get_fail_alloc_failures ());
00497 
00498       if (!(* func) (data))
00499         return FALSE;
00500       
00501       n_mallocs -= 1;
00502     }
00503 
00504   _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
00505 
00506   return TRUE;
00507 }                        
00508 
00522 dbus_bool_t
00523 _dbus_test_oom_handling (const char             *description,
00524                          DBusTestMemoryFunction  func,
00525                          void                   *data)
00526 {
00527   int approx_mallocs;
00528 
00529   /* Run once to see about how many mallocs are involved */
00530   
00531   _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
00532 
00533   _dbus_verbose ("Running once to count mallocs\n");
00534   
00535   if (!(* func) (data))
00536     return FALSE;
00537   
00538   approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter ();
00539 
00540   _dbus_verbose ("\n=================\n%s: about %d mallocs total\n=================\n",
00541                  description, approx_mallocs);
00542 
00543   _dbus_set_fail_alloc_failures (1);
00544   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00545     return FALSE;
00546 
00547   _dbus_set_fail_alloc_failures (2);
00548   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00549     return FALSE;
00550   
00551   _dbus_set_fail_alloc_failures (3);
00552   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00553     return FALSE;
00554 
00555   _dbus_set_fail_alloc_failures (4);
00556   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00557     return FALSE;
00558   
00559   _dbus_verbose ("\n=================\n%s: all iterations passed\n=================\n",
00560                  description);
00561 
00562   return TRUE;
00563 }
00564 #endif /* DBUS_BUILD_TESTS */
00565 

Generated on Tue Dec 20 14:16:39 2005 for D-BUS by  doxygen 1.4.2