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