1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-sysdeps.c Wrappers around system/libc features shared between UNIX and Windows (internal to D-Bus implementation) 3 * 4 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc. 5 * Copyright (C) 2003 CodeFactory AB 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #include <config.h> 26 #include "dbus-internals.h" 27 #include "dbus-sysdeps.h" 28 #include "dbus-threads.h" 29 #include "dbus-protocol.h" 30 #include "dbus-string.h" 31 #include "dbus-list.h" 32 33 /* NOTE: If you include any unix/windows-specific headers here, you are probably doing something 34 * wrong and should be putting some code in dbus-sysdeps-unix.c or dbus-sysdeps-win.c. 35 * 36 * These are the standard ANSI C headers... 37 */ 38 #if HAVE_LOCALE_H 39 #include <locale.h> 40 #endif 41 #include <stdlib.h> 42 #include <string.h> 43 #include <stdio.h> 44 45 #ifdef HAVE_ERRNO_H 46 #include <errno.h> 47 #endif 48 49 _DBUS_DEFINE_GLOBAL_LOCK (win_fds); 50 _DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache); 51 _DBUS_DEFINE_GLOBAL_LOCK (system_users); 52 53 #ifdef DBUS_WIN 54 #include <stdlib.h> 55 #elif (defined __APPLE__) 56 # include <crt_externs.h> 57 # define environ (*_NSGetEnviron()) 58 #else 59 extern char **environ; 60 #endif 61 62 /** 63 * @defgroup DBusSysdeps Internal system-dependent API 64 * @ingroup DBusInternals 65 * @brief Internal system-dependent API available on UNIX and Windows 66 * 67 * The system-dependent API has a dual purpose. First, it encapsulates 68 * all usage of operating system APIs for ease of auditing and to 69 * avoid cluttering the rest of the code with bizarre OS quirks and 70 * headers. Second, it abstracts different operating system APIs for 71 * portability. 72 * 73 * @{ 74 */ 75 76 /** 77 * Aborts the program with SIGABRT (dumping core). 78 */ 79 void 80 _dbus_abort (void) 81 { 82 const char *s; 83 84 _dbus_print_backtrace (); 85 86 s = _dbus_getenv ("DBUS_BLOCK_ON_ABORT"); 87 if (s && *s) 88 { 89 /* don't use _dbus_warn here since it can _dbus_abort() */ 90 fprintf (stderr, " Process %lu sleeping for gdb attach\n", _dbus_pid_for_log ()); 91 _dbus_sleep_milliseconds (1000 * 180); 92 } 93 94 abort (); 95 _dbus_exit (1); /* in case someone manages to ignore SIGABRT ? */ 96 } 97 98 /** 99 * Wrapper for setenv(). If the value is #NULL, unsets 100 * the environment variable. 101 * 102 * There is an unfixable memleak in that it is unsafe to 103 * free memory malloced for use with setenv. This is because 104 * we can not rely on internal implementation details of 105 * the underlying libc library. 106 * 107 * @param varname name of environment variable 108 * @param value value of environment variable 109 * @returns #TRUE on success. 110 */ 111 dbus_bool_t 112 _dbus_setenv (const char *varname, 113 const char *value) 114 { 115 _dbus_assert (varname != NULL); 116 117 if (value == NULL) 118 { 119 #ifdef HAVE_UNSETENV 120 unsetenv (varname); 121 return TRUE; 122 #else 123 char *putenv_value; 124 size_t len; 125 126 len = strlen (varname); 127 128 /* Use system malloc to avoid memleaks that dbus_malloc 129 * will get upset about. 130 */ 131 132 putenv_value = malloc (len + 2); 133 if (putenv_value == NULL) 134 return FALSE; 135 136 strcpy (putenv_value, varname); 137 #if defined(DBUS_WIN) 138 strcat (putenv_value, "="); 139 #endif 140 141 return (putenv (putenv_value) == 0); 142 #endif 143 } 144 else 145 { 146 #ifdef HAVE_SETENV 147 return (setenv (varname, value, TRUE) == 0); 148 #else 149 char *putenv_value; 150 size_t len; 151 size_t varname_len; 152 size_t value_len; 153 154 varname_len = strlen (varname); 155 value_len = strlen (value); 156 157 len = varname_len + value_len + 1 /* '=' */ ; 158 159 /* Use system malloc to avoid memleaks that dbus_malloc 160 * will get upset about. 161 */ 162 163 putenv_value = malloc (len + 1); 164 if (putenv_value == NULL) 165 return FALSE; 166 167 strcpy (putenv_value, varname); 168 strcpy (putenv_value + varname_len, "="); 169 strcpy (putenv_value + varname_len + 1, value); 170 171 return (putenv (putenv_value) == 0); 172 #endif 173 } 174 } 175 176 /** 177 * Wrapper for getenv(). 178 * 179 * @param varname name of environment variable 180 * @returns value of environment variable or #NULL if unset 181 */ 182 const char* 183 _dbus_getenv (const char *varname) 184 { 185 return getenv (varname); 186 } 187 188 /** 189 * Wrapper for clearenv(). 190 * 191 * @returns #TRUE on success. 192 */ 193 dbus_bool_t 194 _dbus_clearenv (void) 195 { 196 dbus_bool_t rc = TRUE; 197 198 #ifdef HAVE_CLEARENV 199 if (clearenv () != 0) 200 rc = FALSE; 201 #else 202 203 if (environ != NULL) 204 environ[0] = NULL; 205 #endif 206 207 return rc; 208 } 209 210 /** 211 * Gets a #NULL-terminated list of key=value pairs from the 212 * environment. Use dbus_free_string_array to free it. 213 * 214 * @returns the environment or #NULL on OOM 215 */ 216 char ** 217 _dbus_get_environment (void) 218 { 219 int i, length; 220 char **environment; 221 222 _dbus_assert (environ != NULL); 223 224 for (length = 0; environ[length] != NULL; length++); 225 226 /* Add one for NULL */ 227 length++; 228 229 environment = dbus_new0 (char *, length); 230 231 if (environment == NULL) 232 return NULL; 233 234 for (i = 0; environ[i] != NULL; i++) 235 { 236 environment[i] = _dbus_strdup (environ[i]); 237 238 if (environment[i] == NULL) 239 break; 240 } 241 242 if (environ[i] != NULL) 243 { 244 dbus_free_string_array (environment); 245 environment = NULL; 246 } 247 248 return environment; 249 } 250 251 /** 252 * Split paths into a list of char strings 253 * 254 * @param dirs string with pathes 255 * @param suffix string concated to each path in dirs 256 * @param dir_list contains a list of splitted pathes 257 * return #TRUE is pathes could be splittes,#FALSE in oom case 258 */ 259 dbus_bool_t 260 _dbus_split_paths_and_append (DBusString *dirs, 261 const char *suffix, 262 DBusList **dir_list) 263 { 264 int start; 265 int i; 266 int len; 267 char *cpath; 268 DBusString file_suffix; 269 270 start = 0; 271 i = 0; 272 273 _dbus_string_init_const (&file_suffix, suffix); 274 275 len = _dbus_string_get_length (dirs); 276 277 while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i)) 278 { 279 DBusString path; 280 281 if (!_dbus_string_init (&path)) 282 goto oom; 283 284 if (!_dbus_string_copy_len (dirs, 285 start, 286 i - start, 287 &path, 288 0)) 289 { 290 _dbus_string_free (&path); 291 goto oom; 292 } 293 294 _dbus_string_chop_white (&path); 295 296 /* check for an empty path */ 297 if (_dbus_string_get_length (&path) == 0) 298 goto next; 299 300 if (!_dbus_concat_dir_and_file (&path, 301 &file_suffix)) 302 { 303 _dbus_string_free (&path); 304 goto oom; 305 } 306 307 if (!_dbus_string_copy_data(&path, &cpath)) 308 { 309 _dbus_string_free (&path); 310 goto oom; 311 } 312 313 if (!_dbus_list_append (dir_list, cpath)) 314 { 315 _dbus_string_free (&path); 316 dbus_free (cpath); 317 goto oom; 318 } 319 320 next: 321 _dbus_string_free (&path); 322 start = i + 1; 323 } 324 325 if (start != len) 326 { 327 DBusString path; 328 329 if (!_dbus_string_init (&path)) 330 goto oom; 331 332 if (!_dbus_string_copy_len (dirs, 333 start, 334 len - start, 335 &path, 336 0)) 337 { 338 _dbus_string_free (&path); 339 goto oom; 340 } 341 342 if (!_dbus_concat_dir_and_file (&path, 343 &file_suffix)) 344 { 345 _dbus_string_free (&path); 346 goto oom; 347 } 348 349 if (!_dbus_string_copy_data(&path, &cpath)) 350 { 351 _dbus_string_free (&path); 352 goto oom; 353 } 354 355 if (!_dbus_list_append (dir_list, cpath)) 356 { 357 _dbus_string_free (&path); 358 dbus_free (cpath); 359 goto oom; 360 } 361 362 _dbus_string_free (&path); 363 } 364 365 return TRUE; 366 367 oom: 368 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); 369 _dbus_list_clear (dir_list); 370 return FALSE; 371 } 372 373 /** @} */ 374 375 /** 376 * @addtogroup DBusString 377 * 378 * @{ 379 */ 380 /** 381 * Appends an integer to a DBusString. 382 * 383 * @param str the string 384 * @param value the integer value 385 * @returns #FALSE if not enough memory or other failure. 386 */ 387 dbus_bool_t 388 _dbus_string_append_int (DBusString *str, 389 long value) 390 { 391 /* this calculation is from comp.lang.c faq */ 392 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1) /* +1 for '-' */ 393 int orig_len; 394 int i; 395 char *buf; 396 397 orig_len = _dbus_string_get_length (str); 398 399 if (!_dbus_string_lengthen (str, MAX_LONG_LEN)) 400 return FALSE; 401 402 buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN); 403 404 snprintf (buf, MAX_LONG_LEN, "%ld", value); 405 406 i = 0; 407 while (*buf) 408 { 409 ++buf; 410 ++i; 411 } 412 413 _dbus_string_shorten (str, MAX_LONG_LEN - i); 414 415 return TRUE; 416 } 417 418 /** 419 * Appends an unsigned integer to a DBusString. 420 * 421 * @param str the string 422 * @param value the integer value 423 * @returns #FALSE if not enough memory or other failure. 424 */ 425 dbus_bool_t 426 _dbus_string_append_uint (DBusString *str, 427 unsigned long value) 428 { 429 /* this is wrong, but definitely on the high side. */ 430 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2) 431 int orig_len; 432 int i; 433 char *buf; 434 435 orig_len = _dbus_string_get_length (str); 436 437 if (!_dbus_string_lengthen (str, MAX_ULONG_LEN)) 438 return FALSE; 439 440 buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN); 441 442 snprintf (buf, MAX_ULONG_LEN, "%lu", value); 443 444 i = 0; 445 while (*buf) 446 { 447 ++buf; 448 ++i; 449 } 450 451 _dbus_string_shorten (str, MAX_ULONG_LEN - i); 452 453 return TRUE; 454 } 455 456 #ifdef DBUS_BUILD_TESTS 457 /** 458 * Appends a double to a DBusString. 459 * 460 * @param str the string 461 * @param value the floating point value 462 * @returns #FALSE if not enough memory or other failure. 463 */ 464 dbus_bool_t 465 _dbus_string_append_double (DBusString *str, 466 double value) 467 { 468 #define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */ 469 int orig_len; 470 char *buf; 471 int i; 472 473 orig_len = _dbus_string_get_length (str); 474 475 if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN)) 476 return FALSE; 477 478 buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN); 479 480 snprintf (buf, MAX_LONG_LEN, "%g", value); 481 482 i = 0; 483 while (*buf) 484 { 485 ++buf; 486 ++i; 487 } 488 489 _dbus_string_shorten (str, MAX_DOUBLE_LEN - i); 490 491 return TRUE; 492 } 493 #endif /* DBUS_BUILD_TESTS */ 494 495 /** 496 * Parses an integer contained in a DBusString. Either return parameter 497 * may be #NULL if you aren't interested in it. The integer is parsed 498 * and stored in value_return. Return parameters are not initialized 499 * if the function returns #FALSE. 500 * 501 * @param str the string 502 * @param start the byte index of the start of the integer 503 * @param value_return return location of the integer value or #NULL 504 * @param end_return return location of the end of the integer, or #NULL 505 * @returns #TRUE on success 506 */ 507 dbus_bool_t 508 _dbus_string_parse_int (const DBusString *str, 509 int start, 510 long *value_return, 511 int *end_return) 512 { 513 long v; 514 const char *p; 515 char *end; 516 517 p = _dbus_string_get_const_data_len (str, start, 518 _dbus_string_get_length (str) - start); 519 520 end = NULL; 521 _dbus_set_errno_to_zero (); 522 v = strtol (p, &end, 0); 523 if (end == NULL || end == p || errno != 0) 524 return FALSE; 525 526 if (value_return) 527 *value_return = v; 528 if (end_return) 529 *end_return = start + (end - p); 530 531 return TRUE; 532 } 533 534 /** 535 * Parses an unsigned integer contained in a DBusString. Either return 536 * parameter may be #NULL if you aren't interested in it. The integer 537 * is parsed and stored in value_return. Return parameters are not 538 * initialized if the function returns #FALSE. 539 * 540 * @param str the string 541 * @param start the byte index of the start of the integer 542 * @param value_return return location of the integer value or #NULL 543 * @param end_return return location of the end of the integer, or #NULL 544 * @returns #TRUE on success 545 */ 546 dbus_bool_t 547 _dbus_string_parse_uint (const DBusString *str, 548 int start, 549 unsigned long *value_return, 550 int *end_return) 551 { 552 unsigned long v; 553 const char *p; 554 char *end; 555 556 p = _dbus_string_get_const_data_len (str, start, 557 _dbus_string_get_length (str) - start); 558 559 end = NULL; 560 _dbus_set_errno_to_zero (); 561 v = strtoul (p, &end, 0); 562 if (end == NULL || end == p || errno != 0) 563 return FALSE; 564 565 if (value_return) 566 *value_return = v; 567 if (end_return) 568 *end_return = start + (end - p); 569 570 return TRUE; 571 } 572 573 #ifdef DBUS_BUILD_TESTS 574 static dbus_bool_t 575 ascii_isspace (char c) 576 { 577 return (c == ' ' || 578 c == '\f' || 579 c == '\n' || 580 c == '\r' || 581 c == '\t' || 582 c == '\v'); 583 } 584 #endif /* DBUS_BUILD_TESTS */ 585 586 #ifdef DBUS_BUILD_TESTS 587 static dbus_bool_t 588 ascii_isdigit (char c) 589 { 590 return c >= '0' && c <= '9'; 591 } 592 #endif /* DBUS_BUILD_TESTS */ 593 594 #ifdef DBUS_BUILD_TESTS 595 static dbus_bool_t 596 ascii_isxdigit (char c) 597 { 598 return (ascii_isdigit (c) || 599 (c >= 'a' && c <= 'f') || 600 (c >= 'A' && c <= 'F')); 601 } 602 #endif /* DBUS_BUILD_TESTS */ 603 604 #ifdef DBUS_BUILD_TESTS 605 /* Calls strtod in a locale-independent fashion, by looking at 606 * the locale data and patching the decimal comma to a point. 607 * 608 * Relicensed from glib. 609 */ 610 static double 611 ascii_strtod (const char *nptr, 612 char **endptr) 613 { 614 /* FIXME: The Win32 C library's strtod() doesn't handle hex. 615 * Presumably many Unixes don't either. 616 */ 617 618 char *fail_pos; 619 double val; 620 struct lconv *locale_data; 621 const char *decimal_point; 622 int decimal_point_len; 623 const char *p, *decimal_point_pos; 624 const char *end = NULL; /* Silence gcc */ 625 626 fail_pos = NULL; 627 628 #if HAVE_LOCALECONV 629 locale_data = localeconv (); 630 decimal_point = locale_data->decimal_point; 631 #else 632 decimal_point = "."; 633 #endif 634 635 decimal_point_len = strlen (decimal_point); 636 _dbus_assert (decimal_point_len != 0); 637 638 decimal_point_pos = NULL; 639 if (decimal_point[0] != '.' || 640 decimal_point[1] != 0) 641 { 642 p = nptr; 643 /* Skip leading space */ 644 while (ascii_isspace (*p)) 645 p++; 646 647 /* Skip leading optional sign */ 648 if (*p == '+' || *p == '-') 649 p++; 650 651 if (p[0] == '0' && 652 (p[1] == 'x' || p[1] == 'X')) 653 { 654 p += 2; 655 /* HEX - find the (optional) decimal point */ 656 657 while (ascii_isxdigit (*p)) 658 p++; 659 660 if (*p == '.') 661 { 662 decimal_point_pos = p++; 663 664 while (ascii_isxdigit (*p)) 665 p++; 666 667 if (*p == 'p' || *p == 'P') 668 p++; 669 if (*p == '+' || *p == '-') 670 p++; 671 while (ascii_isdigit (*p)) 672 p++; 673 end = p; 674 } 675 } 676 else 677 { 678 while (ascii_isdigit (*p)) 679 p++; 680 681 if (*p == '.') 682 { 683 decimal_point_pos = p++; 684 685 while (ascii_isdigit (*p)) 686 p++; 687 688 if (*p == 'e' || *p == 'E') 689 p++; 690 if (*p == '+' || *p == '-') 691 p++; 692 while (ascii_isdigit (*p)) 693 p++; 694 end = p; 695 } 696 } 697 /* For the other cases, we need not convert the decimal point */ 698 } 699 700 /* Set errno to zero, so that we can distinguish zero results 701 and underflows */ 702 _dbus_set_errno_to_zero (); 703 704 if (decimal_point_pos) 705 { 706 char *copy, *c; 707 708 /* We need to convert the '.' to the locale specific decimal point */ 709 copy = dbus_malloc (end - nptr + 1 + decimal_point_len); 710 711 c = copy; 712 memcpy (c, nptr, decimal_point_pos - nptr); 713 c += decimal_point_pos - nptr; 714 memcpy (c, decimal_point, decimal_point_len); 715 c += decimal_point_len; 716 memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); 717 c += end - (decimal_point_pos + 1); 718 *c = 0; 719 720 val = strtod (copy, &fail_pos); 721 722 if (fail_pos) 723 { 724 if (fail_pos > decimal_point_pos) 725 fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); 726 else 727 fail_pos = (char *)nptr + (fail_pos - copy); 728 } 729 730 dbus_free (copy); 731 732 } 733 else 734 val = strtod (nptr, &fail_pos); 735 736 if (endptr) 737 *endptr = fail_pos; 738 739 return val; 740 } 741 #endif /* DBUS_BUILD_TESTS */ 742 743 #ifdef DBUS_BUILD_TESTS 744 /** 745 * Parses a floating point number contained in a DBusString. Either 746 * return parameter may be #NULL if you aren't interested in it. The 747 * integer is parsed and stored in value_return. Return parameters are 748 * not initialized if the function returns #FALSE. 749 * 750 * @param str the string 751 * @param start the byte index of the start of the float 752 * @param value_return return location of the float value or #NULL 753 * @param end_return return location of the end of the float, or #NULL 754 * @returns #TRUE on success 755 */ 756 dbus_bool_t 757 _dbus_string_parse_double (const DBusString *str, 758 int start, 759 double *value_return, 760 int *end_return) 761 { 762 double v; 763 const char *p; 764 char *end; 765 766 p = _dbus_string_get_const_data_len (str, start, 767 _dbus_string_get_length (str) - start); 768 769 /* parsing hex works on linux but isn't portable, so intercept it 770 * here to get uniform behavior. 771 */ 772 if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) 773 return FALSE; 774 775 end = NULL; 776 _dbus_set_errno_to_zero (); 777 v = ascii_strtod (p, &end); 778 if (end == NULL || end == p || errno != 0) 779 return FALSE; 780 781 if (value_return) 782 *value_return = v; 783 if (end_return) 784 *end_return = start + (end - p); 785 786 return TRUE; 787 } 788 #endif /* DBUS_BUILD_TESTS */ 789 790 /** @} */ /* DBusString group */ 791 792 /** 793 * @addtogroup DBusInternalsUtils 794 * @{ 795 */ 796 797 void 798 _dbus_generate_pseudorandom_bytes_buffer (char *buffer, 799 int n_bytes) 800 { 801 long tv_usec; 802 int i; 803 804 /* fall back to pseudorandom */ 805 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n", 806 n_bytes); 807 808 _dbus_get_current_time (NULL, &tv_usec); 809 srand (tv_usec); 810 811 i = 0; 812 while (i < n_bytes) 813 { 814 double r; 815 unsigned int b; 816 817 r = rand (); 818 b = (r / (double) RAND_MAX) * 255.0; 819 820 buffer[i] = b; 821 822 ++i; 823 } 824 } 825 826 /** 827 * Fills n_bytes of the given buffer with random bytes. 828 * 829 * @param buffer an allocated buffer 830 * @param n_bytes the number of bytes in buffer to write to 831 */ 832 void 833 _dbus_generate_random_bytes_buffer (char *buffer, 834 int n_bytes) 835 { 836 DBusString str; 837 838 if (!_dbus_string_init (&str)) 839 { 840 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes); 841 return; 842 } 843 844 if (!_dbus_generate_random_bytes (&str, n_bytes)) 845 { 846 _dbus_string_free (&str); 847 _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes); 848 return; 849 } 850 851 _dbus_string_copy_to_buffer (&str, buffer, n_bytes); 852 853 _dbus_string_free (&str); 854 } 855 856 /** 857 * Generates the given number of random bytes, where the bytes are 858 * chosen from the alphanumeric ASCII subset. 859 * 860 * @param str the string 861 * @param n_bytes the number of random ASCII bytes to append to string 862 * @returns #TRUE on success, #FALSE if no memory or other failure 863 */ 864 dbus_bool_t 865 _dbus_generate_random_ascii (DBusString *str, 866 int n_bytes) 867 { 868 static const char letters[] = 869 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; 870 int i; 871 int len; 872 873 if (!_dbus_generate_random_bytes (str, n_bytes)) 874 return FALSE; 875 876 len = _dbus_string_get_length (str); 877 i = len - n_bytes; 878 while (i < len) 879 { 880 _dbus_string_set_byte (str, i, 881 letters[_dbus_string_get_byte (str, i) % 882 (sizeof (letters) - 1)]); 883 884 ++i; 885 } 886 887 _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes, 888 n_bytes)); 889 890 return TRUE; 891 } 892 893 /** 894 * Converts a UNIX errno, or Windows errno or WinSock error value into 895 * a #DBusError name. 896 * 897 * @todo should cover more errnos, specifically those 898 * from open(). 899 * 900 * @param error_number the errno. 901 * @returns an error name 902 */ 903 const char* 904 _dbus_error_from_errno (int error_number) 905 { 906 switch (error_number) 907 { 908 case 0: 909 return DBUS_ERROR_FAILED; 910 911 #ifdef EPROTONOSUPPORT 912 case EPROTONOSUPPORT: 913 return DBUS_ERROR_NOT_SUPPORTED; 914 #endif 915 #ifdef WSAEPROTONOSUPPORT 916 case WSAEPROTONOSUPPORT: 917 return DBUS_ERROR_NOT_SUPPORTED; 918 #endif 919 #ifdef EAFNOSUPPORT 920 case EAFNOSUPPORT: 921 return DBUS_ERROR_NOT_SUPPORTED; 922 #endif 923 #ifdef WSAEAFNOSUPPORT 924 case WSAEAFNOSUPPORT: 925 return DBUS_ERROR_NOT_SUPPORTED; 926 #endif 927 #ifdef ENFILE 928 case ENFILE: 929 return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */ 930 #endif 931 #ifdef EMFILE 932 case EMFILE: 933 return DBUS_ERROR_LIMITS_EXCEEDED; 934 #endif 935 #ifdef EACCES 936 case EACCES: 937 return DBUS_ERROR_ACCESS_DENIED; 938 #endif 939 #ifdef EPERM 940 case EPERM: 941 return DBUS_ERROR_ACCESS_DENIED; 942 #endif 943 #ifdef ENOBUFS 944 case ENOBUFS: 945 return DBUS_ERROR_NO_MEMORY; 946 #endif 947 #ifdef ENOMEM 948 case ENOMEM: 949 return DBUS_ERROR_NO_MEMORY; 950 #endif 951 #ifdef ECONNREFUSED 952 case ECONNREFUSED: 953 return DBUS_ERROR_NO_SERVER; 954 #endif 955 #ifdef WSAECONNREFUSED 956 case WSAECONNREFUSED: 957 return DBUS_ERROR_NO_SERVER; 958 #endif 959 #ifdef ETIMEDOUT 960 case ETIMEDOUT: 961 return DBUS_ERROR_TIMEOUT; 962 #endif 963 #ifdef WSAETIMEDOUT 964 case WSAETIMEDOUT: 965 return DBUS_ERROR_TIMEOUT; 966 #endif 967 #ifdef ENETUNREACH 968 case ENETUNREACH: 969 return DBUS_ERROR_NO_NETWORK; 970 #endif 971 #ifdef WSAENETUNREACH 972 case WSAENETUNREACH: 973 return DBUS_ERROR_NO_NETWORK; 974 #endif 975 #ifdef EADDRINUSE 976 case EADDRINUSE: 977 return DBUS_ERROR_ADDRESS_IN_USE; 978 #endif 979 #ifdef WSAEADDRINUSE 980 case WSAEADDRINUSE: 981 return DBUS_ERROR_ADDRESS_IN_USE; 982 #endif 983 #ifdef EEXIST 984 case EEXIST: 985 return DBUS_ERROR_FILE_EXISTS; 986 #endif 987 #ifdef ENOENT 988 case ENOENT: 989 return DBUS_ERROR_FILE_NOT_FOUND; 990 #endif 991 } 992 993 return DBUS_ERROR_FAILED; 994 } 995 996 /** 997 * Converts the current system errno value into a #DBusError name. 998 * 999 * @returns an error name 1000 */ 1001 const char* 1002 _dbus_error_from_system_errno (void) 1003 { 1004 return _dbus_error_from_errno (errno); 1005 } 1006 1007 /** 1008 * Assign 0 to the global errno variable 1009 */ 1010 void 1011 _dbus_set_errno_to_zero (void) 1012 { 1013 #ifdef DBUS_WINCE 1014 SetLastError (0); 1015 #else 1016 errno = 0; 1017 #endif 1018 } 1019 1020 /** 1021 * See if errno is set 1022 * @returns #TRUE if errno is not 0 1023 */ 1024 dbus_bool_t 1025 _dbus_get_is_errno_nonzero (void) 1026 { 1027 return errno != 0; 1028 } 1029 1030 /** 1031 * See if errno is ENOMEM 1032 * @returns #TRUE if errno == ENOMEM 1033 */ 1034 dbus_bool_t 1035 _dbus_get_is_errno_enomem (void) 1036 { 1037 return errno == ENOMEM; 1038 } 1039 1040 /** 1041 * See if errno is EINTR 1042 * @returns #TRUE if errno == EINTR 1043 */ 1044 dbus_bool_t 1045 _dbus_get_is_errno_eintr (void) 1046 { 1047 return errno == EINTR; 1048 } 1049 1050 /** 1051 * See if errno is EPIPE 1052 * @returns #TRUE if errno == EPIPE 1053 */ 1054 dbus_bool_t 1055 _dbus_get_is_errno_epipe (void) 1056 { 1057 return errno == EPIPE; 1058 } 1059 1060 /** 1061 * Get error message from errno 1062 * @returns _dbus_strerror(errno) 1063 */ 1064 const char* 1065 _dbus_strerror_from_errno (void) 1066 { 1067 return _dbus_strerror (errno); 1068 } 1069 1070 /** @} end of sysdeps */ 1071 1072 /* tests in dbus-sysdeps-util.c */ 1073