Merge branch 'reversed-dns-37095'
[platform/upstream/dbus.git] / dbus / dbus-sysdeps.c
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  * Split paths into a list of char strings
212  * 
213  * @param dirs string with pathes 
214  * @param suffix string concated to each path in dirs
215  * @param dir_list contains a list of splitted pathes
216  * return #TRUE is pathes could be splittes,#FALSE in oom case 
217  */
218 dbus_bool_t
219 _dbus_split_paths_and_append (DBusString *dirs, 
220                               const char *suffix, 
221                               DBusList  **dir_list)
222 {
223    int start;
224    int i;
225    int len;
226    char *cpath;
227    DBusString file_suffix;
228
229    start = 0;
230    i = 0;
231
232    _dbus_string_init_const (&file_suffix, suffix);
233
234    len = _dbus_string_get_length (dirs);
235
236    while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i))
237      {
238        DBusString path;
239
240        if (!_dbus_string_init (&path))
241           goto oom;
242
243        if (!_dbus_string_copy_len (dirs,
244                                    start,
245                                    i - start,
246                                    &path,
247                                    0))
248           {
249             _dbus_string_free (&path);
250             goto oom;
251           }
252
253         _dbus_string_chop_white (&path);
254
255         /* check for an empty path */
256         if (_dbus_string_get_length (&path) == 0)
257           goto next;
258
259         if (!_dbus_concat_dir_and_file (&path,
260                                         &file_suffix))
261           {
262             _dbus_string_free (&path);
263             goto oom;
264           }
265
266         if (!_dbus_string_copy_data(&path, &cpath))
267           {
268             _dbus_string_free (&path);
269             goto oom;
270           }
271
272         if (!_dbus_list_append (dir_list, cpath))
273           {
274             _dbus_string_free (&path);              
275             dbus_free (cpath);
276             goto oom;
277           }
278
279        next:
280         _dbus_string_free (&path);
281         start = i + 1;
282     } 
283       
284   if (start != len)
285     { 
286       DBusString path;
287
288       if (!_dbus_string_init (&path))
289         goto oom;
290
291       if (!_dbus_string_copy_len (dirs,
292                                   start,
293                                   len - start,
294                                   &path,
295                                   0))
296         {
297           _dbus_string_free (&path);
298           goto oom;
299         }
300
301       if (!_dbus_concat_dir_and_file (&path,
302                                       &file_suffix))
303         {
304           _dbus_string_free (&path);
305           goto oom;
306         }
307
308       if (!_dbus_string_copy_data(&path, &cpath))
309         {
310           _dbus_string_free (&path);
311           goto oom;
312         }
313
314       if (!_dbus_list_append (dir_list, cpath))
315         {
316           _dbus_string_free (&path);              
317           dbus_free (cpath);
318           goto oom;
319         }
320
321       _dbus_string_free (&path); 
322     }
323
324   return TRUE;
325
326  oom:
327   _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); 
328   _dbus_list_clear (dir_list);
329   return FALSE;
330 }
331
332 /** @} */
333
334 /**
335  * @addtogroup DBusString
336  *
337  * @{
338  */
339 /**
340  * Appends an integer to a DBusString.
341  * 
342  * @param str the string
343  * @param value the integer value
344  * @returns #FALSE if not enough memory or other failure.
345  */
346 dbus_bool_t
347 _dbus_string_append_int (DBusString *str,
348                          long        value)
349 {
350   /* this calculation is from comp.lang.c faq */
351 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1)  /* +1 for '-' */
352   int orig_len;
353   int i;
354   char *buf;
355   
356   orig_len = _dbus_string_get_length (str);
357
358   if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
359     return FALSE;
360
361   buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
362
363   snprintf (buf, MAX_LONG_LEN, "%ld", value);
364
365   i = 0;
366   while (*buf)
367     {
368       ++buf;
369       ++i;
370     }
371   
372   _dbus_string_shorten (str, MAX_LONG_LEN - i);
373   
374   return TRUE;
375 }
376
377 /**
378  * Appends an unsigned integer to a DBusString.
379  * 
380  * @param str the string
381  * @param value the integer value
382  * @returns #FALSE if not enough memory or other failure.
383  */
384 dbus_bool_t
385 _dbus_string_append_uint (DBusString    *str,
386                           unsigned long  value)
387 {
388   /* this is wrong, but definitely on the high side. */
389 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
390   int orig_len;
391   int i;
392   char *buf;
393   
394   orig_len = _dbus_string_get_length (str);
395
396   if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
397     return FALSE;
398
399   buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
400
401   snprintf (buf, MAX_ULONG_LEN, "%lu", value);
402
403   i = 0;
404   while (*buf)
405     {
406       ++buf;
407       ++i;
408     }
409   
410   _dbus_string_shorten (str, MAX_ULONG_LEN - i);
411   
412   return TRUE;
413 }
414
415 #ifdef DBUS_BUILD_TESTS
416 /**
417  * Appends a double to a DBusString.
418  * 
419  * @param str the string
420  * @param value the floating point value
421  * @returns #FALSE if not enough memory or other failure.
422  */
423 dbus_bool_t
424 _dbus_string_append_double (DBusString *str,
425                             double      value)
426 {
427 #define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */
428   int orig_len;
429   char *buf;
430   int i;
431   
432   orig_len = _dbus_string_get_length (str);
433
434   if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
435     return FALSE;
436
437   buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
438
439   snprintf (buf, MAX_LONG_LEN, "%g", value);
440
441   i = 0;
442   while (*buf)
443     {
444       ++buf;
445       ++i;
446     }
447   
448   _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
449   
450   return TRUE;
451 }
452 #endif /* DBUS_BUILD_TESTS */
453
454 /**
455  * Parses an integer contained in a DBusString. Either return parameter
456  * may be #NULL if you aren't interested in it. The integer is parsed
457  * and stored in value_return. Return parameters are not initialized
458  * if the function returns #FALSE.
459  *
460  * @param str the string
461  * @param start the byte index of the start of the integer
462  * @param value_return return location of the integer value or #NULL
463  * @param end_return return location of the end of the integer, or #NULL
464  * @returns #TRUE on success
465  */
466 dbus_bool_t
467 _dbus_string_parse_int (const DBusString *str,
468                         int               start,
469                         long             *value_return,
470                         int              *end_return)
471 {
472   long v;
473   const char *p;
474   char *end;
475
476   p = _dbus_string_get_const_data_len (str, start,
477                                        _dbus_string_get_length (str) - start);
478
479   end = NULL;
480   _dbus_set_errno_to_zero ();
481   v = strtol (p, &end, 0);
482   if (end == NULL || end == p || errno != 0)
483     return FALSE;
484
485   if (value_return)
486     *value_return = v;
487   if (end_return)
488     *end_return = start + (end - p);
489
490   return TRUE;
491 }
492
493 /**
494  * Parses an unsigned integer contained in a DBusString. Either return
495  * parameter may be #NULL if you aren't interested in it. The integer
496  * is parsed and stored in value_return. Return parameters are not
497  * initialized if the function returns #FALSE.
498  *
499  * @param str the string
500  * @param start the byte index of the start of the integer
501  * @param value_return return location of the integer value or #NULL
502  * @param end_return return location of the end of the integer, or #NULL
503  * @returns #TRUE on success
504  */
505 dbus_bool_t
506 _dbus_string_parse_uint (const DBusString *str,
507                          int               start,
508                          unsigned long    *value_return,
509                          int              *end_return)
510 {
511   unsigned long v;
512   const char *p;
513   char *end;
514
515   p = _dbus_string_get_const_data_len (str, start,
516                                        _dbus_string_get_length (str) - start);
517
518   end = NULL;
519   _dbus_set_errno_to_zero ();
520   v = strtoul (p, &end, 0);
521   if (end == NULL || end == p || errno != 0)
522     return FALSE;
523
524   if (value_return)
525     *value_return = v;
526   if (end_return)
527     *end_return = start + (end - p);
528
529   return TRUE;
530 }
531
532 #ifdef DBUS_BUILD_TESTS
533 static dbus_bool_t
534 ascii_isspace (char c)
535 {
536   return (c == ' ' ||
537           c == '\f' ||
538           c == '\n' ||
539           c == '\r' ||
540           c == '\t' ||
541           c == '\v');
542 }
543 #endif /* DBUS_BUILD_TESTS */
544
545 #ifdef DBUS_BUILD_TESTS
546 static dbus_bool_t
547 ascii_isdigit (char c)
548 {
549   return c >= '0' && c <= '9';
550 }
551 #endif /* DBUS_BUILD_TESTS */
552
553 #ifdef DBUS_BUILD_TESTS
554 static dbus_bool_t
555 ascii_isxdigit (char c)
556 {
557   return (ascii_isdigit (c) ||
558           (c >= 'a' && c <= 'f') ||
559           (c >= 'A' && c <= 'F'));
560 }
561 #endif /* DBUS_BUILD_TESTS */
562
563 #ifdef DBUS_BUILD_TESTS
564 /* Calls strtod in a locale-independent fashion, by looking at
565  * the locale data and patching the decimal comma to a point.
566  *
567  * Relicensed from glib.
568  */
569 static double
570 ascii_strtod (const char *nptr,
571               char      **endptr)
572 {
573   /* FIXME: The Win32 C library's strtod() doesn't handle hex.
574    * Presumably many Unixes don't either.
575    */
576
577   char *fail_pos;
578   double val;
579   struct lconv *locale_data;
580   const char *decimal_point;
581   int decimal_point_len;
582   const char *p, *decimal_point_pos;
583   const char *end = NULL; /* Silence gcc */
584
585   fail_pos = NULL;
586
587 #if HAVE_LOCALECONV
588   locale_data = localeconv ();
589   decimal_point = locale_data->decimal_point;
590 #else
591   decimal_point = ".";
592 #endif
593
594   decimal_point_len = strlen (decimal_point);
595   _dbus_assert (decimal_point_len != 0);
596   
597   decimal_point_pos = NULL;
598   if (decimal_point[0] != '.' ||
599       decimal_point[1] != 0)
600     {
601       p = nptr;
602       /* Skip leading space */
603       while (ascii_isspace (*p))
604         p++;
605       
606       /* Skip leading optional sign */
607       if (*p == '+' || *p == '-')
608         p++;
609       
610       if (p[0] == '0' &&
611           (p[1] == 'x' || p[1] == 'X'))
612         {
613           p += 2;
614           /* HEX - find the (optional) decimal point */
615           
616           while (ascii_isxdigit (*p))
617             p++;
618           
619           if (*p == '.')
620             {
621               decimal_point_pos = p++;
622               
623               while (ascii_isxdigit (*p))
624                 p++;
625               
626               if (*p == 'p' || *p == 'P')
627                 p++;
628               if (*p == '+' || *p == '-')
629                 p++;
630               while (ascii_isdigit (*p))
631                 p++;
632               end = p;
633             }
634         }
635       else
636         {
637           while (ascii_isdigit (*p))
638             p++;
639           
640           if (*p == '.')
641             {
642               decimal_point_pos = p++;
643               
644               while (ascii_isdigit (*p))
645                 p++;
646               
647               if (*p == 'e' || *p == 'E')
648                 p++;
649               if (*p == '+' || *p == '-')
650                 p++;
651               while (ascii_isdigit (*p))
652                 p++;
653               end = p;
654             }
655         }
656       /* For the other cases, we need not convert the decimal point */
657     }
658
659   /* Set errno to zero, so that we can distinguish zero results
660      and underflows */
661   _dbus_set_errno_to_zero ();
662   
663   if (decimal_point_pos)
664     {
665       char *copy, *c;
666
667       /* We need to convert the '.' to the locale specific decimal point */
668       copy = dbus_malloc (end - nptr + 1 + decimal_point_len);
669       
670       c = copy;
671       memcpy (c, nptr, decimal_point_pos - nptr);
672       c += decimal_point_pos - nptr;
673       memcpy (c, decimal_point, decimal_point_len);
674       c += decimal_point_len;
675       memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
676       c += end - (decimal_point_pos + 1);
677       *c = 0;
678
679       val = strtod (copy, &fail_pos);
680
681       if (fail_pos)
682         {
683           if (fail_pos > decimal_point_pos)
684             fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
685           else
686             fail_pos = (char *)nptr + (fail_pos - copy);
687         }
688       
689       dbus_free (copy);
690           
691     }
692   else
693     val = strtod (nptr, &fail_pos);
694
695   if (endptr)
696     *endptr = fail_pos;
697   
698   return val;
699 }
700 #endif /* DBUS_BUILD_TESTS */
701
702 #ifdef DBUS_BUILD_TESTS
703 /**
704  * Parses a floating point number contained in a DBusString. Either
705  * return parameter may be #NULL if you aren't interested in it. The
706  * integer is parsed and stored in value_return. Return parameters are
707  * not initialized if the function returns #FALSE.
708  *
709  * @param str the string
710  * @param start the byte index of the start of the float
711  * @param value_return return location of the float value or #NULL
712  * @param end_return return location of the end of the float, or #NULL
713  * @returns #TRUE on success
714  */
715 dbus_bool_t
716 _dbus_string_parse_double (const DBusString *str,
717                            int               start,
718                            double           *value_return,
719                            int              *end_return)
720 {
721   double v;
722   const char *p;
723   char *end;
724
725   p = _dbus_string_get_const_data_len (str, start,
726                                        _dbus_string_get_length (str) - start);
727
728   /* parsing hex works on linux but isn't portable, so intercept it
729    * here to get uniform behavior.
730    */
731   if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
732     return FALSE;
733   
734   end = NULL;
735   _dbus_set_errno_to_zero ();
736   v = ascii_strtod (p, &end);
737   if (end == NULL || end == p || errno != 0)
738     return FALSE;
739
740   if (value_return)
741     *value_return = v;
742   if (end_return)
743     *end_return = start + (end - p);
744
745   return TRUE;
746 }
747 #endif /* DBUS_BUILD_TESTS */
748
749 /** @} */ /* DBusString group */
750
751 /**
752  * @addtogroup DBusInternalsUtils
753  * @{
754  */
755
756 void
757 _dbus_generate_pseudorandom_bytes_buffer (char *buffer,
758                                           int   n_bytes)
759 {
760   long tv_usec;
761   int i;
762   
763   /* fall back to pseudorandom */
764   _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
765                  n_bytes);
766   
767   _dbus_get_current_time (NULL, &tv_usec);
768   srand (tv_usec);
769   
770   i = 0;
771   while (i < n_bytes)
772     {
773       double r;
774       unsigned int b;
775           
776       r = rand ();
777       b = (r / (double) RAND_MAX) * 255.0;
778
779       buffer[i] = b;
780
781       ++i;
782     }
783 }
784
785 /**
786  * Fills n_bytes of the given buffer with random bytes.
787  *
788  * @param buffer an allocated buffer
789  * @param n_bytes the number of bytes in buffer to write to
790  */
791 void
792 _dbus_generate_random_bytes_buffer (char *buffer,
793                                     int   n_bytes)
794 {
795   DBusString str;
796
797   if (!_dbus_string_init (&str))
798     {
799       _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
800       return;
801     }
802
803   if (!_dbus_generate_random_bytes (&str, n_bytes))
804     {
805       _dbus_string_free (&str);
806       _dbus_generate_pseudorandom_bytes_buffer (buffer, n_bytes);
807       return;
808     }
809
810   _dbus_string_copy_to_buffer (&str, buffer, n_bytes);
811
812   _dbus_string_free (&str);
813 }
814
815 /**
816  * Generates the given number of random bytes, where the bytes are
817  * chosen from the alphanumeric ASCII subset.
818  *
819  * @param str the string
820  * @param n_bytes the number of random ASCII bytes to append to string
821  * @returns #TRUE on success, #FALSE if no memory or other failure
822  */
823 dbus_bool_t
824 _dbus_generate_random_ascii (DBusString *str,
825                              int         n_bytes)
826 {
827   static const char letters[] =
828     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
829   int i;
830   int len;
831   
832   if (!_dbus_generate_random_bytes (str, n_bytes))
833     return FALSE;
834   
835   len = _dbus_string_get_length (str);
836   i = len - n_bytes;
837   while (i < len)
838     {
839       _dbus_string_set_byte (str, i,
840                              letters[_dbus_string_get_byte (str, i) %
841                                      (sizeof (letters) - 1)]);
842
843       ++i;
844     }
845
846   _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
847                                              n_bytes));
848
849   return TRUE;
850 }
851
852 /**
853  * Converts a UNIX errno, or Windows errno or WinSock error value into
854  * a #DBusError name.
855  *
856  * @todo should cover more errnos, specifically those
857  * from open().
858  * 
859  * @param error_number the errno.
860  * @returns an error name
861  */
862 const char*
863 _dbus_error_from_errno (int error_number)
864 {
865   switch (error_number)
866     {
867     case 0:
868       return DBUS_ERROR_FAILED;
869       
870 #ifdef EPROTONOSUPPORT
871     case EPROTONOSUPPORT:
872       return DBUS_ERROR_NOT_SUPPORTED;
873 #endif
874 #ifdef WSAEPROTONOSUPPORT
875     case WSAEPROTONOSUPPORT:
876       return DBUS_ERROR_NOT_SUPPORTED;
877 #endif
878 #ifdef EAFNOSUPPORT
879     case EAFNOSUPPORT:
880       return DBUS_ERROR_NOT_SUPPORTED;
881 #endif
882 #ifdef WSAEAFNOSUPPORT
883     case WSAEAFNOSUPPORT:
884       return DBUS_ERROR_NOT_SUPPORTED;
885 #endif
886 #ifdef ENFILE
887     case ENFILE:
888       return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
889 #endif
890 #ifdef EMFILE
891     case EMFILE:
892       return DBUS_ERROR_LIMITS_EXCEEDED;
893 #endif
894 #ifdef EACCES
895     case EACCES:
896       return DBUS_ERROR_ACCESS_DENIED;
897 #endif
898 #ifdef EPERM
899     case EPERM:
900       return DBUS_ERROR_ACCESS_DENIED;
901 #endif
902 #ifdef ENOBUFS
903     case ENOBUFS:
904       return DBUS_ERROR_NO_MEMORY;
905 #endif
906 #ifdef ENOMEM
907     case ENOMEM:
908       return DBUS_ERROR_NO_MEMORY;
909 #endif
910 #ifdef ECONNREFUSED
911     case ECONNREFUSED:
912       return DBUS_ERROR_NO_SERVER;
913 #endif
914 #ifdef WSAECONNREFUSED
915     case WSAECONNREFUSED:
916       return DBUS_ERROR_NO_SERVER;
917 #endif
918 #ifdef ETIMEDOUT
919     case ETIMEDOUT:
920       return DBUS_ERROR_TIMEOUT;
921 #endif
922 #ifdef WSAETIMEDOUT
923     case WSAETIMEDOUT:
924       return DBUS_ERROR_TIMEOUT;
925 #endif
926 #ifdef ENETUNREACH
927     case ENETUNREACH:
928       return DBUS_ERROR_NO_NETWORK;
929 #endif
930 #ifdef WSAENETUNREACH
931     case WSAENETUNREACH:
932       return DBUS_ERROR_NO_NETWORK;
933 #endif
934 #ifdef EADDRINUSE
935     case EADDRINUSE:
936       return DBUS_ERROR_ADDRESS_IN_USE;
937 #endif
938 #ifdef WSAEADDRINUSE
939     case WSAEADDRINUSE:
940       return DBUS_ERROR_ADDRESS_IN_USE;
941 #endif
942 #ifdef EEXIST
943     case EEXIST:
944       return DBUS_ERROR_FILE_EXISTS;
945 #endif
946 #ifdef ENOENT
947     case ENOENT:
948       return DBUS_ERROR_FILE_NOT_FOUND;
949 #endif
950     }
951
952   return DBUS_ERROR_FAILED;
953 }
954
955 /**
956  * Converts the current system errno value into a #DBusError name.
957  *
958  * @returns an error name
959  */
960 const char*
961 _dbus_error_from_system_errno (void)
962 {
963   return _dbus_error_from_errno (errno);
964 }
965
966 /**
967  * Assign 0 to the global errno variable
968  */
969 void
970 _dbus_set_errno_to_zero (void)
971 {
972 #ifdef DBUS_WINCE
973   SetLastError (0);
974 #else
975   errno = 0;
976 #endif
977 }
978
979 /**
980  * See if errno is set
981  * @returns #TRUE if errno is not 0
982  */
983 dbus_bool_t
984 _dbus_get_is_errno_nonzero (void)
985 {
986   return errno != 0;
987 }
988
989 /**
990  * See if errno is ENOMEM
991  * @returns #TRUE if errno == ENOMEM
992  */
993 dbus_bool_t
994 _dbus_get_is_errno_enomem (void)
995 {
996   return errno == ENOMEM;
997 }
998
999 /**
1000  * See if errno is EINTR
1001  * @returns #TRUE if errno == EINTR
1002  */
1003 dbus_bool_t
1004 _dbus_get_is_errno_eintr (void)
1005 {
1006   return errno == EINTR;
1007 }
1008
1009 /**
1010  * See if errno is EPIPE
1011  * @returns #TRUE if errno == EPIPE
1012  */
1013 dbus_bool_t
1014 _dbus_get_is_errno_epipe (void)
1015 {
1016   return errno == EPIPE;
1017 }
1018
1019 /**
1020  * Get error message from errno
1021  * @returns _dbus_strerror(errno)
1022  */
1023 const char*
1024 _dbus_strerror_from_errno (void)
1025 {
1026   return _dbus_strerror (errno);
1027 }
1028
1029 /** @} end of sysdeps */
1030
1031 /* tests in dbus-sysdeps-util.c */