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 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 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 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 /* DBUS_DISABLE_ASSERT */ 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; /* fudge factor to ensure reallocs etc. are covered */ 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 /* Run once to see about how many mallocs are involved */ 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 /* DBUS_BUILD_TESTS */ 00564

Generated on Mon Aug 16 17:40:08 2004 for D-BUS by doxygen 1.3.8