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