00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
00196
00197
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
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;
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
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
00506