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 int len;
00195
00196
00197
00198
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
00212 if (need_pid)
00213 fprintf (stderr, "%lu: ", _dbus_getpid ());
00214
00215
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
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;
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
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
00565