D-Bus  1.4.18
dbus-sysdeps.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-sysdeps.c Wrappers around system/libc features shared between UNIX and Windows (internal to D-Bus implementation)
00003  * 
00004  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  * 
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  * 
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 #include "dbus-internals.h"
00027 #include "dbus-sysdeps.h"
00028 #include "dbus-threads.h"
00029 #include "dbus-protocol.h"
00030 #include "dbus-string.h"
00031 #include "dbus-list.h"
00032 
00033 /* NOTE: If you include any unix/windows-specific headers here, you are probably doing something
00034  * wrong and should be putting some code in dbus-sysdeps-unix.c or dbus-sysdeps-win.c.
00035  *
00036  * These are the standard ANSI C headers...
00037  */
00038 #if HAVE_LOCALE_H
00039 #include <locale.h>
00040 #endif
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <stdio.h>
00044 
00045 #ifdef HAVE_ERRNO_H
00046 #include <errno.h>
00047 #endif
00048 
00049 _DBUS_DEFINE_GLOBAL_LOCK (win_fds);
00050 _DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache);
00051 _DBUS_DEFINE_GLOBAL_LOCK (system_users);
00052 
00053 #ifdef DBUS_WIN
00054   #include <stdlib.h>
00055 #elif (defined __APPLE__)
00056 # include <crt_externs.h>
00057 # define environ (*_NSGetEnviron())
00058 #else
00059 extern char **environ;
00060 #endif
00061 
00079 void
00080 _dbus_abort (void)
00081 {
00082   const char *s;
00083   
00084   _dbus_print_backtrace ();
00085   
00086   s = _dbus_getenv ("DBUS_BLOCK_ON_ABORT");
00087   if (s && *s)
00088     {
00089       /* don't use _dbus_warn here since it can _dbus_abort() */
00090       fprintf (stderr, "  Process %lu sleeping for gdb attach\n", _dbus_pid_for_log ());
00091       _dbus_sleep_milliseconds (1000 * 180);
00092     }
00093   
00094   abort ();
00095   _dbus_exit (1); /* in case someone manages to ignore SIGABRT ? */
00096 }
00097 
00111 dbus_bool_t
00112 _dbus_setenv (const char *varname,
00113               const char *value)
00114 {
00115   _dbus_assert (varname != NULL);
00116   
00117   if (value == NULL)
00118     {
00119 #ifdef HAVE_UNSETENV
00120       unsetenv (varname);
00121       return TRUE;
00122 #else
00123       char *putenv_value;
00124       size_t len;
00125 
00126       len = strlen (varname);
00127 
00128       /* Use system malloc to avoid memleaks that dbus_malloc
00129        * will get upset about.
00130        */
00131       
00132       putenv_value = malloc (len + 2);
00133       if (putenv_value == NULL)
00134         return FALSE;
00135 
00136       strcpy (putenv_value, varname);
00137 #if defined(DBUS_WIN)
00138       strcat (putenv_value, "=");
00139 #endif
00140       
00141       return (putenv (putenv_value) == 0);
00142 #endif
00143     }
00144   else
00145     {
00146 #ifdef HAVE_SETENV
00147       return (setenv (varname, value, TRUE) == 0);
00148 #else
00149       char *putenv_value;
00150       size_t len;
00151       size_t varname_len;
00152       size_t value_len;
00153 
00154       varname_len = strlen (varname);
00155       value_len = strlen (value);
00156       
00157       len = varname_len + value_len + 1 /* '=' */ ;
00158 
00159       /* Use system malloc to avoid memleaks that dbus_malloc
00160        * will get upset about.
00161        */
00162       
00163       putenv_value = malloc (len + 1);
00164       if (putenv_value == NULL)
00165         return FALSE;
00166 
00167       strcpy (putenv_value, varname);
00168       strcpy (putenv_value + varname_len, "=");
00169       strcpy (putenv_value + varname_len + 1, value);
00170       
00171       return (putenv (putenv_value) == 0);
00172 #endif
00173     }
00174 }
00175 
00182 const char*
00183 _dbus_getenv (const char *varname)
00184 {  
00185   /* Don't respect any environment variables if the current process is
00186    * setuid.  This is the equivalent of glibc's __secure_getenv().
00187    */
00188   if (_dbus_check_setuid ())
00189     return NULL;
00190   return getenv (varname);
00191 }
00192 
00198 dbus_bool_t
00199 _dbus_clearenv (void)
00200 {
00201   dbus_bool_t rc = TRUE;
00202 
00203 #ifdef HAVE_CLEARENV
00204   if (clearenv () != 0)
00205      rc = FALSE;
00206 #else
00207 
00208   if (environ != NULL)
00209     environ[0] = NULL;
00210 #endif
00211 
00212   return rc;
00213 }
00214 
00221 char **
00222 _dbus_get_environment (void)
00223 {
00224   int i, length;
00225   char **environment;
00226 
00227   _dbus_assert (environ != NULL);
00228 
00229   for (length = 0; environ[length] != NULL; length++);
00230 
00231   /* Add one for NULL */
00232   length++;
00233 
00234   environment = dbus_new0 (char *, length);
00235 
00236   if (environment == NULL)
00237     return NULL;
00238 
00239   for (i = 0; environ[i] != NULL; i++)
00240     {
00241       environment[i] = _dbus_strdup (environ[i]);
00242 
00243       if (environment[i] == NULL)
00244         break;
00245     }
00246 
00247   if (environ[i] != NULL)
00248     {
00249       dbus_free_string_array (environment);
00250       environment = NULL;
00251     }
00252 
00253   return environment;
00254 }
00255 
00264 dbus_bool_t
00265 _dbus_split_paths_and_append (DBusString *dirs, 
00266                               const char *suffix, 
00267                               DBusList  **dir_list)
00268 {
00269    int start;
00270    int i;
00271    int len;
00272    char *cpath;
00273    DBusString file_suffix;
00274 
00275    start = 0;
00276    i = 0;
00277 
00278    _dbus_string_init_const (&file_suffix, suffix);
00279 
00280    len = _dbus_string_get_length (dirs);
00281 
00282    while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
00283      {
00284        DBusString path;
00285 
00286        if (!_dbus_string_init (&path))
00287           goto oom;
00288 
00289        if (!_dbus_string_copy_len (dirs,
00290                                    start,
00291                                    i - start,
00292                                    &path,
00293                                    0))
00294           {
00295             _dbus_string_free (&path);
00296             goto oom;
00297           }
00298 
00299         _dbus_string_chop_white (&path);
00300 
00301         /* check for an empty path */
00302         if (_dbus_string_get_length (&path) == 0)
00303           goto next;
00304 
00305         if (!_dbus_concat_dir_and_file (&path,
00306                                         &file_suffix))
00307           {
00308             _dbus_string_free (&path);
00309             goto oom;
00310           }
00311 
00312         if (!_dbus_string_copy_data(&path, &cpath))
00313           {
00314             _dbus_string_free (&path);
00315             goto oom;
00316           }
00317 
00318         if (!_dbus_list_append (dir_list, cpath))
00319           {
00320             _dbus_string_free (&path);              
00321             dbus_free (cpath);
00322             goto oom;
00323           }
00324 
00325        next:
00326         _dbus_string_free (&path);
00327         start = i + 1;
00328     } 
00329       
00330   if (start != len)
00331     { 
00332       DBusString path;
00333 
00334       if (!_dbus_string_init (&path))
00335         goto oom;
00336 
00337       if (!_dbus_string_copy_len (dirs,
00338                                   start,
00339                                   len - start,
00340                                   &path,
00341                                   0))
00342         {
00343           _dbus_string_free (&path);
00344           goto oom;
00345         }
00346 
00347       if (!_dbus_concat_dir_and_file (&path,
00348                                       &file_suffix))
00349         {
00350           _dbus_string_free (&path);
00351           goto oom;
00352         }
00353 
00354       if (!_dbus_string_copy_data(&path, &cpath))
00355         {
00356           _dbus_string_free (&path);
00357           goto oom;
00358         }
00359 
00360       if (!_dbus_list_append (dir_list, cpath))
00361         {
00362           _dbus_string_free (&path);              
00363           dbus_free (cpath);
00364           goto oom;
00365         }
00366 
00367       _dbus_string_free (&path); 
00368     }
00369 
00370   return TRUE;
00371 
00372  oom:
00373   _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); 
00374   _dbus_list_clear (dir_list);
00375   return FALSE;
00376 }
00377 
00392 dbus_bool_t
00393 _dbus_string_append_int (DBusString *str,
00394                          long        value)
00395 {
00396   /* this calculation is from comp.lang.c faq */
00397 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)  /* +1 for '-' */
00398   int orig_len;
00399   int i;
00400   char *buf;
00401   
00402   orig_len = _dbus_string_get_length (str);
00403 
00404   if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
00405     return FALSE;
00406 
00407   buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
00408 
00409   snprintf (buf, MAX_LONG_LEN, "%ld", value);
00410 
00411   i = 0;
00412   while (*buf)
00413     {
00414       ++buf;
00415       ++i;
00416     }
00417   
00418   _dbus_string_shorten (str, MAX_LONG_LEN - i);
00419   
00420   return TRUE;
00421 }
00422 
00430 dbus_bool_t
00431 _dbus_string_append_uint (DBusString    *str,
00432                           unsigned long  value)
00433 {
00434   /* this is wrong, but definitely on the high side. */
00435 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
00436   int orig_len;
00437   int i;
00438   char *buf;
00439   
00440   orig_len = _dbus_string_get_length (str);
00441 
00442   if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
00443     return FALSE;
00444 
00445   buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
00446 
00447   snprintf (buf, MAX_ULONG_LEN, "%lu", value);
00448 
00449   i = 0;
00450   while (*buf)
00451     {
00452       ++buf;
00453       ++i;
00454     }
00455   
00456   _dbus_string_shorten (str, MAX_ULONG_LEN - i);
00457   
00458   return TRUE;
00459 }
00460 
00461 #ifdef DBUS_BUILD_TESTS
00462 
00469 dbus_bool_t
00470 _dbus_string_append_double (DBusString *str,
00471                             double      value)
00472 {
00473 #define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */
00474   int orig_len;
00475   char *buf;
00476   int i;
00477   
00478   orig_len = _dbus_string_get_length (str);
00479 
00480   if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
00481     return FALSE;
00482 
00483   buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
00484 
00485   snprintf (buf, MAX_LONG_LEN, "%g", value);
00486 
00487   i = 0;
00488   while (*buf)
00489     {
00490       ++buf;
00491       ++i;
00492     }
00493   
00494   _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
00495   
00496   return TRUE;
00497 }
00498 #endif /* DBUS_BUILD_TESTS */
00499 
00512 dbus_bool_t
00513 _dbus_string_parse_int (const DBusString *str,
00514                         int               start,
00515                         long             *value_return,
00516                         int              *end_return)
00517 {
00518   long v;
00519   const char *p;
00520   char *end;
00521 
00522   p = _dbus_string_get_const_data_len (str, start,
00523                                        _dbus_string_get_length (str) - start);
00524 
00525   end = NULL;
00526   _dbus_set_errno_to_zero ();
00527   v = strtol (p, &end, 0);
00528   if (end == NULL || end == p || errno != 0)
00529     return FALSE;
00530 
00531   if (value_return)
00532     *value_return = v;
00533   if (end_return)
00534     *end_return = start + (end - p);
00535 
00536   return TRUE;
00537 }
00538 
00551 dbus_bool_t
00552 _dbus_string_parse_uint (const DBusString *str,
00553                          int               start,
00554                          unsigned long    *value_return,
00555                          int              *end_return)
00556 {
00557   unsigned long v;
00558   const char *p;
00559   char *end;
00560 
00561   p = _dbus_string_get_const_data_len (str, start,
00562                                        _dbus_string_get_length (str) - start);
00563 
00564   end = NULL;
00565   _dbus_set_errno_to_zero ();
00566   v = strtoul (p, &end, 0);
00567   if (end == NULL || end == p || errno != 0)
00568     return FALSE;
00569 
00570   if (value_return)
00571     *value_return = v;
00572   if (end_return)
00573     *end_return = start + (end - p);
00574 
00575   return TRUE;
00576 }
00577 
00578 #ifdef DBUS_BUILD_TESTS
00579 static dbus_bool_t
00580 ascii_isspace (char c)
00581 {
00582   return (c == ' ' ||
00583           c == '\f' ||
00584           c == '\n' ||
00585           c == '\r' ||
00586           c == '\t' ||
00587           c == '\v');
00588 }
00589 #endif /* DBUS_BUILD_TESTS */
00590 
00591 #ifdef DBUS_BUILD_TESTS
00592 static dbus_bool_t
00593 ascii_isdigit (char c)
00594 {
00595   return c >= '0' && c <= '9';
00596 }
00597 #endif /* DBUS_BUILD_TESTS */
00598 
00599 #ifdef DBUS_BUILD_TESTS
00600 static dbus_bool_t
00601 ascii_isxdigit (char c)
00602 {
00603   return (ascii_isdigit (c) ||
00604           (c >= 'a' && c <= 'f') ||
00605           (c >= 'A' && c <= 'F'));
00606 }
00607 #endif /* DBUS_BUILD_TESTS */
00608 
00609 #ifdef DBUS_BUILD_TESTS
00610 /* Calls strtod in a locale-independent fashion, by looking at
00611  * the locale data and patching the decimal comma to a point.
00612  *
00613  * Relicensed from glib.
00614  */
00615 static double
00616 ascii_strtod (const char *nptr,
00617               char      **endptr)
00618 {
00619   /* FIXME: The Win32 C library's strtod() doesn't handle hex.
00620    * Presumably many Unixes don't either.
00621    */
00622 
00623   char *fail_pos;
00624   double val;
00625   struct lconv *locale_data;
00626   const char *decimal_point;
00627   int decimal_point_len;
00628   const char *p, *decimal_point_pos;
00629   const char *end = NULL; /* Silence gcc */
00630 
00631   fail_pos = NULL;
00632 
00633 #if HAVE_LOCALECONV
00634   locale_data = localeconv ();
00635   decimal_point = locale_data->decimal_point;
00636 #else
00637   decimal_point = ".";
00638 #endif
00639 
00640   decimal_point_len = strlen (decimal_point);
00641   _dbus_assert (decimal_point_len != 0);
00642   
00643   decimal_point_pos = NULL;
00644   if (decimal_point[0] != '.' ||
00645       decimal_point[1] != 0)
00646     {
00647       p = nptr;
00648       /* Skip leading space */
00649       while (ascii_isspace (*p))
00650         p++;
00651       
00652       /* Skip leading optional sign */
00653       if (*p == '+' || *p == '-')
00654         p++;
00655       
00656       if (p[0] == '0' &&
00657           (p[1] == 'x' || p[1] == 'X'))
00658         {
00659           p += 2;
00660           /* HEX - find the (optional) decimal point */
00661           
00662           while (ascii_isxdigit (*p))
00663             p++;
00664           
00665           if (*p == '.')
00666             {
00667               decimal_point_pos = p++;
00668               
00669               while (ascii_isxdigit (*p))
00670                 p++;
00671               
00672               if (*p == 'p' || *p == 'P')
00673                 p++;
00674               if (*p == '+' || *p == '-')
00675                 p++;
00676               while (ascii_isdigit (*p))
00677                 p++;
00678               end = p;
00679             }
00680         }
00681       else
00682         {
00683           while (ascii_isdigit (*p))
00684             p++;
00685           
00686           if (*p == '.')
00687             {
00688               decimal_point_pos = p++;
00689               
00690               while (ascii_isdigit (*p))
00691                 p++;
00692               
00693               if (*p == 'e' || *p == 'E')
00694                 p++;
00695               if (*p == '+' || *p == '-')
00696                 p++;
00697               while (ascii_isdigit (*p))
00698                 p++;
00699               end = p;
00700             }
00701         }
00702       /* For the other cases, we need not convert the decimal point */
00703     }
00704 
00705   /* Set errno to zero, so that we can distinguish zero results
00706      and underflows */
00707   _dbus_set_errno_to_zero ();
00708   
00709   if (decimal_point_pos)
00710     {
00711       char *copy, *c;
00712 
00713       /* We need to convert the '.' to the locale specific decimal point */
00714       copy = dbus_malloc (end - nptr + 1 + decimal_point_len);
00715       
00716       c = copy;
00717       memcpy (c, nptr, decimal_point_pos - nptr);
00718       c += decimal_point_pos - nptr;
00719       memcpy (c, decimal_point, decimal_point_len);
00720       c += decimal_point_len;
00721       memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
00722       c += end - (decimal_point_pos + 1);
00723       *c = 0;
00724 
00725       val = strtod (copy, &fail_pos);
00726 
00727       if (fail_pos)
00728         {
00729           if (fail_pos > decimal_point_pos)
00730             fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
00731           else
00732             fail_pos = (char *)nptr + (fail_pos - copy);
00733         }
00734       
00735       dbus_free (copy);
00736           
00737     }
00738   else
00739     val = strtod (nptr, &fail_pos);
00740 
00741   if (endptr)
00742     *endptr = fail_pos;
00743   
00744   return val;
00745 }
00746 #endif /* DBUS_BUILD_TESTS */
00747 
00748 #ifdef DBUS_BUILD_TESTS
00749 
00761 dbus_bool_t
00762 _dbus_string_parse_double (const DBusString *str,
00763                            int               start,
00764                            double           *value_return,
00765                            int              *end_return)
00766 {
00767   double v;
00768   const char *p;
00769   char *end;
00770 
00771   p = _dbus_string_get_const_data_len (str, start,
00772                                        _dbus_string_get_length (str) - start);
00773 
00774   /* parsing hex works on linux but isn't portable, so intercept it
00775    * here to get uniform behavior.
00776    */
00777   if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
00778     return FALSE;
00779   
00780   end = NULL;
00781   _dbus_set_errno_to_zero ();
00782   v = ascii_strtod (p, &end);
00783   if (end == NULL || end == p || errno != 0)
00784     return FALSE;
00785 
00786   if (value_return)
00787     *value_return = v;
00788   if (end_return)
00789     *end_return = start + (end - p);
00790 
00791   return TRUE;
00792 }
00793 #endif /* DBUS_BUILD_TESTS */
00794  /* DBusString group */
00796 
00802 void
00803 _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
00804                                           int   n_bytes)
00805 {
00806   long tv_usec;
00807   int i;
00808   
00809   /* fall back to pseudorandom */
00810   _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
00811                  n_bytes);
00812   
00813   _dbus_get_current_time (NULL, &tv_usec);
00814   srand (tv_usec);
00815   
00816   i = 0;
00817   while (i < n_bytes)
00818     {
00819       double r;
00820       unsigned int b;
00821           
00822       r = rand ();
00823       b = (r / (double) RAND_MAX) * 255.0;
00824 
00825       buffer[i] = b;
00826 
00827       ++i;
00828     }
00829 }
00830 
00837 void
00838 _dbus_generate_random_bytes_buffer (char *buffer,
00839                                     int   n_bytes)
00840 {
00841   DBusString str;
00842 
00843   if (!_dbus_string_init (&str))
00844     {
00845       _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00846       return;
00847     }
00848 
00849   if (!_dbus_generate_random_bytes (&str, n_bytes))
00850     {
00851       _dbus_string_free (&str);
00852       _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
00853       return;
00854     }
00855 
00856   _dbus_string_copy_to_buffer (&str, buffer, n_bytes);
00857 
00858   _dbus_string_free (&str);
00859 }
00860 
00869 dbus_bool_t
00870 _dbus_generate_random_ascii (DBusString *str,
00871                              int         n_bytes)
00872 {
00873   static const char letters[] =
00874     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
00875   int i;
00876   int len;
00877   
00878   if (!_dbus_generate_random_bytes (str, n_bytes))
00879     return FALSE;
00880   
00881   len = _dbus_string_get_length (str);
00882   i = len - n_bytes;
00883   while (i < len)
00884     {
00885       _dbus_string_set_byte (str, i,
00886                              letters[_dbus_string_get_byte (str, i) %
00887                                      (sizeof (letters) - 1)]);
00888 
00889       ++i;
00890     }
00891 
00892   _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
00893                                              n_bytes));
00894 
00895   return TRUE;
00896 }
00897 
00908 const char*
00909 _dbus_error_from_errno (int error_number)
00910 {
00911   switch (error_number)
00912     {
00913     case 0:
00914       return DBUS_ERROR_FAILED;
00915       
00916 #ifdef EPROTONOSUPPORT
00917     case EPROTONOSUPPORT:
00918       return DBUS_ERROR_NOT_SUPPORTED;
00919 #endif
00920 #ifdef WSAEPROTONOSUPPORT
00921     case WSAEPROTONOSUPPORT:
00922       return DBUS_ERROR_NOT_SUPPORTED;
00923 #endif
00924 #ifdef EAFNOSUPPORT
00925     case EAFNOSUPPORT:
00926       return DBUS_ERROR_NOT_SUPPORTED;
00927 #endif
00928 #ifdef WSAEAFNOSUPPORT
00929     case WSAEAFNOSUPPORT:
00930       return DBUS_ERROR_NOT_SUPPORTED;
00931 #endif
00932 #ifdef ENFILE
00933     case ENFILE:
00934       return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
00935 #endif
00936 #ifdef EMFILE
00937     case EMFILE:
00938       return DBUS_ERROR_LIMITS_EXCEEDED;
00939 #endif
00940 #ifdef EACCES
00941     case EACCES:
00942       return DBUS_ERROR_ACCESS_DENIED;
00943 #endif
00944 #ifdef EPERM
00945     case EPERM:
00946       return DBUS_ERROR_ACCESS_DENIED;
00947 #endif
00948 #ifdef ENOBUFS
00949     case ENOBUFS:
00950       return DBUS_ERROR_NO_MEMORY;
00951 #endif
00952 #ifdef ENOMEM
00953     case ENOMEM:
00954       return DBUS_ERROR_NO_MEMORY;
00955 #endif
00956 #ifdef ECONNREFUSED
00957     case ECONNREFUSED:
00958       return DBUS_ERROR_NO_SERVER;
00959 #endif
00960 #ifdef WSAECONNREFUSED
00961     case WSAECONNREFUSED:
00962       return DBUS_ERROR_NO_SERVER;
00963 #endif
00964 #ifdef ETIMEDOUT
00965     case ETIMEDOUT:
00966       return DBUS_ERROR_TIMEOUT;
00967 #endif
00968 #ifdef WSAETIMEDOUT
00969     case WSAETIMEDOUT:
00970       return DBUS_ERROR_TIMEOUT;
00971 #endif
00972 #ifdef ENETUNREACH
00973     case ENETUNREACH:
00974       return DBUS_ERROR_NO_NETWORK;
00975 #endif
00976 #ifdef WSAENETUNREACH
00977     case WSAENETUNREACH:
00978       return DBUS_ERROR_NO_NETWORK;
00979 #endif
00980 #ifdef EADDRINUSE
00981     case EADDRINUSE:
00982       return DBUS_ERROR_ADDRESS_IN_USE;
00983 #endif
00984 #ifdef WSAEADDRINUSE
00985     case WSAEADDRINUSE:
00986       return DBUS_ERROR_ADDRESS_IN_USE;
00987 #endif
00988 #ifdef EEXIST
00989     case EEXIST:
00990       return DBUS_ERROR_FILE_EXISTS;
00991 #endif
00992 #ifdef ENOENT
00993     case ENOENT:
00994       return DBUS_ERROR_FILE_NOT_FOUND;
00995 #endif
00996     }
00997 
00998   return DBUS_ERROR_FAILED;
00999 }
01000 
01006 const char*
01007 _dbus_error_from_system_errno (void)
01008 {
01009   return _dbus_error_from_errno (errno);
01010 }
01011 
01015 void
01016 _dbus_set_errno_to_zero (void)
01017 {
01018 #ifdef DBUS_WINCE
01019   SetLastError (0);
01020 #else
01021   errno = 0;
01022 #endif
01023 }
01024 
01029 dbus_bool_t
01030 _dbus_get_is_errno_nonzero (void)
01031 {
01032   return errno != 0;
01033 }
01034 
01039 dbus_bool_t
01040 _dbus_get_is_errno_enomem (void)
01041 {
01042   return errno == ENOMEM;
01043 }
01044 
01049 dbus_bool_t
01050 _dbus_get_is_errno_eintr (void)
01051 {
01052   return errno == EINTR;
01053 }
01054 
01059 dbus_bool_t
01060 _dbus_get_is_errno_epipe (void)
01061 {
01062   return errno == EPIPE;
01063 }
01064 
01069 dbus_bool_t
01070 _dbus_get_is_errno_etoomanyrefs (void)
01071 {
01072 #ifdef ETOOMANYREFS
01073   return errno == ETOOMANYREFS;
01074 #else
01075   return FALSE;
01076 #endif
01077 }
01078 
01083 const char*
01084 _dbus_strerror_from_errno (void)
01085 {
01086   return _dbus_strerror (errno);
01087 }
01088 
01091 /* tests in dbus-sysdeps-util.c */