Main Page   Modules   Data Structures   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 1.2
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   
00195   /* things are written a bit oddly here so that
00196    * in the non-verbose case we just have the one
00197    * conditional and return immediately.
00198    */
00199   if (!verbose)
00200     return;
00201   
00202   if (!verbose_initted)
00203     {
00204       verbose = _dbus_getenv ("DBUS_VERBOSE") != NULL;
00205       verbose_initted = TRUE;
00206       if (!verbose)
00207         return;
00208     }
00209 
00210   if (need_pid)
00211     {
00212       int len;
00213       
00214       fprintf (stderr, "%lu: ", _dbus_getpid ());
00215 
00216       len = strlen (format);
00217       if (format[len-1] == '\n')
00218         need_pid = TRUE;
00219       else
00220         need_pid = FALSE;
00221     }
00222   
00223   va_start (args, format);
00224   vfprintf (stderr, format, args);
00225   va_end (args);
00226 }
00227 
00234 void
00235 _dbus_verbose_reset_real (void)
00236 {
00237   verbose_initted = FALSE;
00238 }
00239 
00248 char*
00249 _dbus_strdup (const char *str)
00250 {
00251   int len;
00252   char *copy;
00253   
00254   if (str == NULL)
00255     return NULL;
00256   
00257   len = strlen (str);
00258 
00259   copy = dbus_malloc (len + 1);
00260   if (copy == NULL)
00261     return NULL;
00262 
00263   memcpy (copy, str, len + 1);
00264   
00265   return copy;
00266 }
00267 
00276 char**
00277 _dbus_dup_string_array (const char **array)
00278 {
00279   int len;
00280   int i;
00281   char **copy;
00282   
00283   if (array == NULL)
00284     return NULL;
00285 
00286   for (len = 0; array[len] != NULL; ++len)
00287     ;
00288 
00289   copy = dbus_new0 (char*, len + 1);
00290   if (copy == NULL)
00291     return NULL;
00292 
00293   i = 0;
00294   while (i < len)
00295     {
00296       copy[i] = _dbus_strdup (array[i]);
00297       if (copy[i] == NULL)
00298         {
00299           dbus_free_string_array (copy);
00300           return NULL;
00301         }
00302 
00303       ++i;
00304     }
00305 
00306   return copy;
00307 }
00308 
00316 dbus_bool_t
00317 _dbus_string_array_contains (const char **array,
00318                              const char  *str)
00319 {
00320   int i;
00321 
00322   i = 0;
00323   while (array[i] != NULL)
00324     {
00325       if (strcmp (array[i], str) == 0)
00326         return TRUE;
00327       ++i;
00328     }
00329 
00330   return FALSE;
00331 }
00332 
00339 const char *
00340 _dbus_type_to_string (int type)
00341 {
00342   switch (type)
00343     {
00344     case DBUS_TYPE_INVALID:
00345       return "invalid";
00346     case DBUS_TYPE_NIL:
00347       return "nil";
00348     case DBUS_TYPE_BOOLEAN:
00349       return "boolean";
00350     case DBUS_TYPE_INT32:
00351       return "int32";
00352     case DBUS_TYPE_UINT32:
00353       return "uint32";
00354     case DBUS_TYPE_DOUBLE:
00355       return "double";
00356     case DBUS_TYPE_STRING:
00357       return "string";
00358     case DBUS_TYPE_NAMED:
00359       return "named";
00360     case DBUS_TYPE_ARRAY:
00361       return "array";
00362     case DBUS_TYPE_DICT:
00363       return "dict";
00364     default:
00365       return "unknown";
00366     }
00367 }
00368 
00369 #ifndef DBUS_DISABLE_CHECKS
00370 const char _dbus_return_if_fail_warning_format[] =
00371 "Arguments to %s were incorrect, assertion \"%s\" failed in file %s line %d.\n"
00372 "This is normally a bug in some application using the D-BUS library.\n";
00373 #endif
00374 
00375 #ifndef DBUS_DISABLE_ASSERT
00376 
00387 void
00388 _dbus_real_assert (dbus_bool_t  condition,
00389                    const char  *condition_text,
00390                    const char  *file,
00391                    int          line)
00392 {
00393   if (!condition)
00394     {
00395       _dbus_warn ("Assertion failed \"%s\" file \"%s\" line %d process %lu\n",
00396                   condition_text, file, line, _dbus_getpid ());
00397       _dbus_abort ();
00398     }
00399 }
00400 
00411 void
00412 _dbus_real_assert_not_reached (const char *explanation,
00413                                const char *file,
00414                                int         line)
00415 {
00416   _dbus_warn ("File \"%s\" line %d process %lu should not have been reached: %s\n",
00417               file, line, _dbus_getpid (), explanation);
00418   _dbus_abort ();
00419 }
00420 #endif /* DBUS_DISABLE_ASSERT */
00421   
00422 #ifdef DBUS_BUILD_TESTS
00423 static dbus_bool_t
00424 run_failing_each_malloc (int                    n_mallocs,
00425                          const char            *description,
00426                          DBusTestMemoryFunction func,
00427                          void                  *data)
00428 {
00429   n_mallocs += 10; /* fudge factor to ensure reallocs etc. are covered */
00430   
00431   while (n_mallocs >= 0)
00432     {      
00433       _dbus_set_fail_alloc_counter (n_mallocs);
00434 
00435       _dbus_verbose ("\n===\n%s: (will fail malloc %d with %d failures)\n===\n",
00436                      description, n_mallocs,
00437                      _dbus_get_fail_alloc_failures ());
00438 
00439       if (!(* func) (data))
00440         return FALSE;
00441       
00442       n_mallocs -= 1;
00443     }
00444 
00445   _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
00446 
00447   return TRUE;
00448 }                        
00449 
00463 dbus_bool_t
00464 _dbus_test_oom_handling (const char             *description,
00465                          DBusTestMemoryFunction  func,
00466                          void                   *data)
00467 {
00468   int approx_mallocs;
00469 
00470   /* Run once to see about how many mallocs are involved */
00471   
00472   _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
00473 
00474   _dbus_verbose ("Running once to count mallocs\n");
00475   
00476   if (!(* func) (data))
00477     return FALSE;
00478   
00479   approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter ();
00480 
00481   _dbus_verbose ("\n=================\n%s: about %d mallocs total\n=================\n",
00482                  description, approx_mallocs);
00483 
00484   _dbus_set_fail_alloc_failures (1);
00485   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00486     return FALSE;
00487 
00488   _dbus_set_fail_alloc_failures (2);
00489   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00490     return FALSE;
00491   
00492   _dbus_set_fail_alloc_failures (3);
00493   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00494     return FALSE;
00495 
00496   _dbus_set_fail_alloc_failures (4);
00497   if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00498     return FALSE;
00499   
00500   _dbus_verbose ("\n=================\n%s: all iterations passed\n=================\n",
00501                  description);
00502 
00503   return TRUE;
00504 }
00505 #endif /* DBUS_BUILD_TESTS */
00506 

Generated on Wed Oct 22 14:05:01 2003 for D-BUS by doxygen1.3-rc3