dbus-internals.c revision 8ab042b9571dda44a5afcfe50e0d29dc9b58ecae
1/* -*- mode: C; c-file-style: "gnu" -*- */ 2/* dbus-internals.c random utility stuff (internal to D-BUS implementation) 3 * 4 * Copyright (C) 2002 Red Hat, Inc. 5 * 6 * Licensed under the Academic Free License version 1.2 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23#include "dbus-internals.h" 24#include "dbus-protocol.h" 25#include "dbus-test.h" 26#include <stdio.h> 27#include <stdarg.h> 28#include <string.h> 29#include <sys/types.h> 30#include <errno.h> 31#include <unistd.h> 32#include <fcntl.h> 33#include <stdlib.h> 34 35/** 36 * @defgroup DBusInternals D-BUS internal implementation details 37 * @brief Documentation useful when developing or debugging D-BUS itself. 38 * 39 */ 40 41/** 42 * @defgroup DBusInternalsUtils Utilities and portability 43 * @ingroup DBusInternals 44 * @brief Utility functions (_dbus_assert(), _dbus_warn(), etc.) 45 * @{ 46 */ 47 48/** 49 * @def _dbus_assert 50 * 51 * Aborts with an error message if the condition is false. 52 * 53 * @param condition condition which must be true. 54 */ 55 56/** 57 * @def _dbus_assert_not_reached 58 * 59 * Aborts with an error message if called. 60 * The given explanation will be printed. 61 * 62 * @param explanation explanation of what happened if the code was reached. 63 */ 64 65/** 66 * @def _DBUS_N_ELEMENTS 67 * 68 * Computes the number of elements in a fixed-size array using 69 * sizeof(). 70 * 71 * @param array the array to count elements in. 72 */ 73 74/** 75 * @def _DBUS_POINTER_TO_INT 76 * 77 * Safely casts a void* to an integer; should only be used on void* 78 * that actually contain integers, for example one created with 79 * _DBUS_INT_TO_POINTER. Only guaranteed to preserve 32 bits. 80 * (i.e. it's used to store 32-bit ints in pointers, but 81 * can't be used to store 64-bit pointers in ints.) 82 * 83 * @param pointer pointer to extract an integer from. 84 */ 85/** 86 * @def _DBUS_INT_TO_POINTER 87 * 88 * Safely stuffs an integer into a pointer, to be extracted later with 89 * _DBUS_POINTER_TO_INT. Only guaranteed to preserve 32 bits. 90 * 91 * @param integer the integer to stuff into a pointer. 92 */ 93/** 94 * @def _DBUS_ZERO 95 * 96 * Sets all bits in an object to zero. 97 * 98 * @param object the object to be zeroed. 99 */ 100/** 101 * @def _DBUS_INT_MIN 102 * 103 * Minimum value of type "int" 104 */ 105/** 106 * @def _DBUS_INT_MAX 107 * 108 * Maximum value of type "int" 109 */ 110/** 111 * @def _DBUS_MAX_SUN_PATH_LENGTH 112 * 113 * Maximum length of the path to a UNIX domain socket, 114 * sockaddr_un::sun_path member. POSIX requires that all systems 115 * support at least 100 bytes here, including the nul termination. 116 * We use 99 for the max value to allow for the nul. 117 * 118 * We could probably also do sizeof (addr.sun_path) 119 * but this way we are the same on all platforms 120 * which is probably a good idea. 121 */ 122 123/** 124 * @typedef DBusForeachFunction 125 * 126 * Used to iterate over each item in a collection, such as 127 * a DBusList. 128 */ 129 130/** 131 * Prints a warning message to stderr. 132 * 133 * @param format printf-style format string. 134 */ 135void 136_dbus_warn (const char *format, 137 ...) 138{ 139 /* FIXME not portable enough? */ 140 va_list args; 141 142 va_start (args, format); 143 vfprintf (stderr, format, args); 144 va_end (args); 145} 146 147/** 148 * Prints a warning message to stderr 149 * if the user has enabled verbose mode. 150 * This is the real function implementation, 151 * use _dbus_verbose() macro in code. 152 * 153 * @param format printf-style format string. 154 */ 155void 156_dbus_verbose_real (const char *format, 157 ...) 158{ 159 va_list args; 160 static dbus_bool_t verbose = TRUE; 161 static dbus_bool_t initted = FALSE; 162 163 /* things are written a bit oddly here so that 164 * in the non-verbose case we just have the one 165 * conditional and return immediately. 166 */ 167 if (!verbose) 168 return; 169 170 if (!initted) 171 { 172 verbose = _dbus_getenv ("DBUS_VERBOSE") != NULL; 173 initted = TRUE; 174 if (!verbose) 175 return; 176 } 177 178 va_start (args, format); 179 vfprintf (stderr, format, args); 180 va_end (args); 181} 182 183/** 184 * A wrapper around strerror() because some platforms 185 * may be lame and not have strerror(). 186 * 187 * @param error_number errno. 188 * @returns error description. 189 */ 190const char* 191_dbus_strerror (int error_number) 192{ 193 return strerror (error_number); 194} 195 196/** 197 * Converts a UNIX errno into a DBusResultCode. 198 * 199 * @todo should cover more errnos, specifically those 200 * from open(). 201 * 202 * @param error_number the errno. 203 * @returns the result code. 204 */ 205DBusResultCode 206_dbus_result_from_errno (int error_number) 207{ 208 switch (error_number) 209 { 210 case 0: 211 return DBUS_RESULT_SUCCESS; 212 213#ifdef EPROTONOSUPPORT 214 case EPROTONOSUPPORT: 215 return DBUS_RESULT_NOT_SUPPORTED; 216#endif 217#ifdef EAFNOSUPPORT 218 case EAFNOSUPPORT: 219 return DBUS_RESULT_NOT_SUPPORTED; 220#endif 221#ifdef ENFILE 222 case ENFILE: 223 return DBUS_RESULT_LIMITS_EXCEEDED; /* kernel out of memory */ 224#endif 225#ifdef EMFILE 226 case EMFILE: 227 return DBUS_RESULT_LIMITS_EXCEEDED; 228#endif 229#ifdef EACCES 230 case EACCES: 231 return DBUS_RESULT_ACCESS_DENIED; 232#endif 233#ifdef EPERM 234 case EPERM: 235 return DBUS_RESULT_ACCESS_DENIED; 236#endif 237#ifdef ENOBUFS 238 case ENOBUFS: 239 return DBUS_RESULT_NO_MEMORY; 240#endif 241#ifdef ENOMEM 242 case ENOMEM: 243 return DBUS_RESULT_NO_MEMORY; 244#endif 245#ifdef EINVAL 246 case EINVAL: 247 return DBUS_RESULT_FAILED; 248#endif 249#ifdef EBADF 250 case EBADF: 251 return DBUS_RESULT_FAILED; 252#endif 253#ifdef EFAULT 254 case EFAULT: 255 return DBUS_RESULT_FAILED; 256#endif 257#ifdef ENOTSOCK 258 case ENOTSOCK: 259 return DBUS_RESULT_FAILED; 260#endif 261#ifdef EISCONN 262 case EISCONN: 263 return DBUS_RESULT_FAILED; 264#endif 265#ifdef ECONNREFUSED 266 case ECONNREFUSED: 267 return DBUS_RESULT_NO_SERVER; 268#endif 269#ifdef ETIMEDOUT 270 case ETIMEDOUT: 271 return DBUS_RESULT_TIMEOUT; 272#endif 273#ifdef ENETUNREACH 274 case ENETUNREACH: 275 return DBUS_RESULT_NO_NETWORK; 276#endif 277#ifdef EADDRINUSE 278 case EADDRINUSE: 279 return DBUS_RESULT_ADDRESS_IN_USE; 280#endif 281#ifdef EEXIST 282 case EEXIST: 283 return DBUS_RESULT_FILE_NOT_FOUND; 284#endif 285#ifdef ENOENT 286 case ENOENT: 287 return DBUS_RESULT_FILE_NOT_FOUND; 288#endif 289 } 290 291 return DBUS_RESULT_FAILED; 292} 293 294/** 295 * Duplicates a string. Result must be freed with 296 * dbus_free(). Returns #NULL if memory allocation fails. 297 * If the string to be duplicated is #NULL, returns #NULL. 298 * 299 * @param str string to duplicate. 300 * @returns newly-allocated copy. 301 */ 302char* 303_dbus_strdup (const char *str) 304{ 305 int len; 306 char *copy; 307 308 if (str == NULL) 309 return NULL; 310 311 len = strlen (str); 312 313 copy = dbus_malloc (len + 1); 314 if (copy == NULL) 315 return NULL; 316 317 memcpy (copy, str, len + 1); 318 319 return copy; 320} 321 322/** 323 * Sets a file descriptor to be nonblocking. 324 * 325 * @param fd the file descriptor. 326 * @param result address of result code. 327 * @returns #TRUE on success. 328 */ 329dbus_bool_t 330_dbus_set_fd_nonblocking (int fd, 331 DBusResultCode *result) 332{ 333 int val; 334 335 val = fcntl (fd, F_GETFL, 0); 336 if (val < 0) 337 { 338 dbus_set_result (result, _dbus_result_from_errno (errno)); 339 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd, 340 _dbus_strerror (errno)); 341 return FALSE; 342 } 343 344 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0) 345 { 346 dbus_set_result (result, _dbus_result_from_errno (errno)); 347 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n", 348 fd, _dbus_strerror (errno)); 349 350 return FALSE; 351 } 352 353 return TRUE; 354} 355 356/** 357 * Returns a string describing the given type. 358 * 359 * @param type the type to describe 360 * @returns a constant string describing the type 361 */ 362const char * 363_dbus_type_to_string (int type) 364{ 365 switch (type) 366 { 367 case DBUS_TYPE_INVALID: 368 return "invalid"; 369 case DBUS_TYPE_NIL: 370 return "nil"; 371 case DBUS_TYPE_INT32: 372 return "int32"; 373 case DBUS_TYPE_UINT32: 374 return "uint32"; 375 case DBUS_TYPE_DOUBLE: 376 return "double"; 377 case DBUS_TYPE_STRING: 378 return "string"; 379 case DBUS_TYPE_INT32_ARRAY: 380 return "int32 array"; 381 case DBUS_TYPE_UINT32_ARRAY: 382 return "uint32 array"; 383 case DBUS_TYPE_DOUBLE_ARRAY: 384 return "double array"; 385 case DBUS_TYPE_BYTE_ARRAY: 386 return "byte array"; 387 case DBUS_TYPE_STRING_ARRAY: 388 return "string array"; 389 default: 390 return "unknown"; 391 } 392} 393 394/** @} */ 395