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 fflush (stderr);
00228 }
00229
00236 void
00237 _dbus_verbose_reset_real (void)
00238 {
00239 verbose_initted = FALSE;
00240 }
00241
00250 char*
00251 _dbus_strdup (const char *str)
00252 {
00253 size_t len;
00254 char *copy;
00255
00256 if (str == NULL)
00257 return NULL;
00258
00259 len = strlen (str);
00260
00261 copy = dbus_malloc (len + 1);
00262 if (copy == NULL)
00263 return NULL;
00264
00265 memcpy (copy, str, len + 1);
00266
00267 return copy;
00268 }
00269
00278 void*
00279 _dbus_memdup (const void *mem,
00280 size_t n_bytes)
00281 {
00282 void *copy;
00283
00284 copy = dbus_malloc (n_bytes);
00285 if (copy == NULL)
00286 return NULL;
00287
00288 memcpy (copy, mem, n_bytes);
00289
00290 return copy;
00291 }
00292
00301 char**
00302 _dbus_dup_string_array (const char **array)
00303 {
00304 int len;
00305 int i;
00306 char **copy;
00307
00308 if (array == NULL)
00309 return NULL;
00310
00311 for (len = 0; array[len] != NULL; ++len)
00312 ;
00313
00314 copy = dbus_new0 (char*, len + 1);
00315 if (copy == NULL)
00316 return NULL;
00317
00318 i = 0;
00319 while (i < len)
00320 {
00321 copy[i] = _dbus_strdup (array[i]);
00322 if (copy[i] == NULL)
00323 {
00324 dbus_free_string_array (copy);
00325 return NULL;
00326 }
00327
00328 ++i;
00329 }
00330
00331 return copy;
00332 }
00333
00341 dbus_bool_t
00342 _dbus_string_array_contains (const char **array,
00343 const char *str)
00344 {
00345 int i;
00346
00347 i = 0;
00348 while (array[i] != NULL)
00349 {
00350 if (strcmp (array[i], str) == 0)
00351 return TRUE;
00352 ++i;
00353 }
00354
00355 return FALSE;
00356 }
00357
00364 const char *
00365 _dbus_type_to_string (int type)
00366 {
00367 switch (type)
00368 {
00369 case DBUS_TYPE_INVALID:
00370 return "invalid";
00371 case DBUS_TYPE_NIL:
00372 return "nil";
00373 case DBUS_TYPE_BOOLEAN:
00374 return "boolean";
00375 case DBUS_TYPE_INT32:
00376 return "int32";
00377 case DBUS_TYPE_UINT32:
00378 return "uint32";
00379 case DBUS_TYPE_DOUBLE:
00380 return "double";
00381 case DBUS_TYPE_STRING:
00382 return "string";
00383 case DBUS_TYPE_CUSTOM:
00384 return "custom";
00385 case DBUS_TYPE_ARRAY:
00386 return "array";
00387 case DBUS_TYPE_DICT:
00388 return "dict";
00389 default:
00390 return "unknown";
00391 }
00392 }
00393
00400 const char *
00401 _dbus_header_field_to_string (int header_field)
00402 {
00403 switch (header_field)
00404 {
00405 case DBUS_HEADER_FIELD_INVALID:
00406 return "invalid";
00407 case DBUS_HEADER_FIELD_PATH:
00408 return "path";
00409 case DBUS_HEADER_FIELD_INTERFACE:
00410 return "interface";
00411 case DBUS_HEADER_FIELD_MEMBER:
00412 return "member";
00413 case DBUS_HEADER_FIELD_ERROR_NAME:
00414 return "error-name";
00415 case DBUS_HEADER_FIELD_REPLY_SERIAL:
00416 return "reply-serial";
00417 case DBUS_HEADER_FIELD_DESTINATION:
00418 return "destination";
00419 case DBUS_HEADER_FIELD_SENDER:
00420 return "sender";
00421 default:
00422 return "unknown";
00423 }
00424 }
00425
00426 #ifndef DBUS_DISABLE_CHECKS
00427
00428 const char _dbus_return_if_fail_warning_format[] =
00429 "%lu: arguments to %s() were incorrect, assertion \"%s\" failed in file %s line %d.\n"
00430 "This is normally a bug in some application using the D-BUS library.\n";
00431 #endif
00432
00433 #ifndef DBUS_DISABLE_ASSERT
00434
00445 void
00446 _dbus_real_assert (dbus_bool_t condition,
00447 const char *condition_text,
00448 const char *file,
00449 int line)
00450 {
00451 if (_DBUS_UNLIKELY (!condition))
00452 {
00453 _dbus_warn ("%lu: assertion failed \"%s\" file \"%s\" line %d\n",
00454 _dbus_getpid (), condition_text, file, line);
00455 _dbus_abort ();
00456 }
00457 }
00458
00469 void
00470 _dbus_real_assert_not_reached (const char *explanation,
00471 const char *file,
00472 int line)
00473 {
00474 _dbus_warn ("File \"%s\" line %d process %lu should not have been reached: %s\n",
00475 file, line, _dbus_getpid (), explanation);
00476 _dbus_abort ();
00477 }
00478 #endif
00479
00480 #ifdef DBUS_BUILD_TESTS
00481 static dbus_bool_t
00482 run_failing_each_malloc (int n_mallocs,
00483 const char *description,
00484 DBusTestMemoryFunction func,
00485 void *data)
00486 {
00487 n_mallocs += 10;
00488
00489 while (n_mallocs >= 0)
00490 {
00491 _dbus_set_fail_alloc_counter (n_mallocs);
00492
00493 _dbus_verbose ("\n===\n%s: (will fail malloc %d with %d failures)\n===\n",
00494 description, n_mallocs,
00495 _dbus_get_fail_alloc_failures ());
00496
00497 if (!(* func) (data))
00498 return FALSE;
00499
00500 n_mallocs -= 1;
00501 }
00502
00503 _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
00504
00505 return TRUE;
00506 }
00507
00521 dbus_bool_t
00522 _dbus_test_oom_handling (const char *description,
00523 DBusTestMemoryFunction func,
00524 void *data)
00525 {
00526 int approx_mallocs;
00527
00528
00529
00530 _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
00531
00532 _dbus_verbose ("Running once to count mallocs\n");
00533
00534 if (!(* func) (data))
00535 return FALSE;
00536
00537 approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter ();
00538
00539 _dbus_verbose ("\n=================\n%s: about %d mallocs total\n=================\n",
00540 description, approx_mallocs);
00541
00542 _dbus_set_fail_alloc_failures (1);
00543 if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00544 return FALSE;
00545
00546 _dbus_set_fail_alloc_failures (2);
00547 if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00548 return FALSE;
00549
00550 _dbus_set_fail_alloc_failures (3);
00551 if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00552 return FALSE;
00553
00554 _dbus_set_fail_alloc_failures (4);
00555 if (!run_failing_each_malloc (approx_mallocs, description, func, data))
00556 return FALSE;
00557
00558 _dbus_verbose ("\n=================\n%s: all iterations passed\n=================\n",
00559 description);
00560
00561 return TRUE;
00562 }
00563 #endif
00564