2006-10-21 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  *
23  */
24
25 #include "dbus-internals.h"
26 #include "dbus-sysdeps.h"
27 #include "dbus-sysdeps-unix.h"
28 #include "dbus-threads.h"
29 #include "dbus-protocol.h"
30 #include "dbus-transport.h"
31 #include "dbus-string.h"
32 #include <sys/types.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <signal.h>
36 #include <unistd.h>
37 #include <stdio.h>
38 #include <fcntl.h>
39 #include <sys/socket.h>
40 #include <dirent.h>
41 #include <sys/un.h>
42 #include <pwd.h>
43 #include <time.h>
44 #include <locale.h>
45 #include <sys/time.h>
46 #include <sys/stat.h>
47 #include <sys/wait.h>
48 #include <netinet/in.h>
49 #include <netdb.h>
50 #include <grp.h>
51
52 #ifdef HAVE_ERRNO_H
53 #include <errno.h>
54 #endif
55 #ifdef HAVE_WRITEV
56 #include <sys/uio.h>
57 #endif
58 #ifdef HAVE_POLL
59 #include <sys/poll.h>
60 #endif
61 #ifdef HAVE_BACKTRACE
62 #include <execinfo.h>
63 #endif
64 #ifdef HAVE_GETPEERUCRED
65 #include <ucred.h>
66 #endif
67
68 #ifndef O_BINARY
69 #define O_BINARY 0
70 #endif
71
72 #ifndef HAVE_SOCKLEN_T
73 #define socklen_t int
74 #endif
75
76 /**
77  * @addtogroup DBusInternalsUtils
78  * @{
79  */
80
81 static dbus_bool_t
82 _dbus_open_socket (int              *fd,
83                    int               domain,
84                    int               type,
85                    int               protocol,
86                    DBusError        *error)
87 {
88   *fd = socket (domain, type, protocol);
89   if (fd >= 0)
90     {
91       return TRUE;
92     }
93   else
94     {
95       dbus_set_error(error,
96                      _dbus_error_from_errno (errno),
97                      "Failed to open socket: %s",
98                      _dbus_strerror (errno));
99       return FALSE;
100     }
101 }
102
103 dbus_bool_t
104 _dbus_open_tcp_socket (int              *fd,
105                        DBusError        *error)
106 {
107   return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
108 }
109
110 /**
111  * Opens a UNIX domain socket (as in the socket() call).
112  * Does not bind the socket.
113  * @param fd return location for socket descriptor
114  * @param error return location for an error
115  * @returns #FALSE if error is set
116  */
117 dbus_bool_t
118 _dbus_open_unix_socket (int              *fd,
119                         DBusError        *error)
120 {
121   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
122 }
123
124 /**
125  * Closes a socket. Should not be used on non-socket
126  * file descriptors or handles.
127  *
128  * @param fd the socket
129  * @param error return location for an error
130  * @returns #FALSE if error is set
131  */
132 dbus_bool_t 
133 _dbus_close_socket (int               fd,
134                     DBusError        *error)
135 {
136   return _dbus_close (fd, error);
137 }
138
139 /**
140  * Like _dbus_read(), but only works on sockets so is
141  * available on Windows.
142  *
143  * @param fd the socket
144  * @param buffer string to append data to
145  * @param count max amount of data to read
146  * @returns number of bytes appended to the string
147  */
148 int
149 _dbus_read_socket (int               fd,
150                    DBusString       *buffer,
151                    int               count)
152 {
153   return _dbus_read (fd, buffer, count);
154 }
155
156 /**
157  * Like _dbus_write(), but only supports sockets
158  * and is thus available on Windows.
159  *
160  * @param fd the file descriptor to write
161  * @param buffer the buffer to write data from
162  * @param start the first byte in the buffer to write
163  * @param len the number of bytes to try to write
164  * @returns the number of bytes written or -1 on error
165  */
166 int
167 _dbus_write_socket (int               fd,
168                     const DBusString *buffer,
169                     int               start,
170                     int               len)
171 {
172   return _dbus_write (fd, buffer, start, len);
173 }
174
175 /**
176  * Like _dbus_write_two() but only works on sockets and is thus
177  * available on Windows.
178  * 
179  * @param fd the file descriptor
180  * @param buffer1 first buffer
181  * @param start1 first byte to write in first buffer
182  * @param len1 number of bytes to write from first buffer
183  * @param buffer2 second buffer, or #NULL
184  * @param start2 first byte to write in second buffer
185  * @param len2 number of bytes to write in second buffer
186  * @returns total bytes written from both buffers, or -1 on error
187  */
188 int
189 _dbus_write_socket_two (int               fd,
190                         const DBusString *buffer1,
191                         int               start1,
192                         int               len1,
193                         const DBusString *buffer2,
194                         int               start2,
195                         int               len2)
196 {
197   return _dbus_write_two (fd, buffer1, start1, len1,
198                           buffer2, start2, len2);
199 }
200
201
202 /**
203  * Thin wrapper around the read() system call that appends
204  * the data it reads to the DBusString buffer. It appends
205  * up to the given count, and returns the same value
206  * and same errno as read(). The only exception is that
207  * _dbus_read() handles EINTR for you. Also, _dbus_read() can
208  * return ENOMEM, even though regular UNIX read doesn't.
209  *
210  * Unlike _dbus_read_socket(), _dbus_read() is not available
211  * on Windows.
212  * 
213  * @param fd the file descriptor to read from
214  * @param buffer the buffer to append data to
215  * @param count the amount of data to read
216  * @returns the number of bytes read or -1
217  */
218 int
219 _dbus_read (int               fd,
220             DBusString       *buffer,
221             int               count)
222 {
223   int bytes_read;
224   int start;
225   char *data;
226
227   _dbus_assert (count >= 0);
228   
229   start = _dbus_string_get_length (buffer);
230
231   if (!_dbus_string_lengthen (buffer, count))
232     {
233       errno = ENOMEM;
234       return -1;
235     }
236
237   data = _dbus_string_get_data_len (buffer, start, count);
238
239  again:
240   
241   bytes_read = read (fd, data, count);
242
243   if (bytes_read < 0)
244     {
245       if (errno == EINTR)
246         goto again;
247       else
248         {
249           /* put length back (note that this doesn't actually realloc anything) */
250           _dbus_string_set_length (buffer, start);
251           return -1;
252         }
253     }
254   else
255     {
256       /* put length back (doesn't actually realloc) */
257       _dbus_string_set_length (buffer, start + bytes_read);
258
259 #if 0
260       if (bytes_read > 0)
261         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
262 #endif
263       
264       return bytes_read;
265     }
266 }
267
268 /**
269  * Thin wrapper around the write() system call that writes a part of a
270  * DBusString and handles EINTR for you.
271  * 
272  * @param fd the file descriptor to write
273  * @param buffer the buffer to write data from
274  * @param start the first byte in the buffer to write
275  * @param len the number of bytes to try to write
276  * @returns the number of bytes written or -1 on error
277  */
278 int
279 _dbus_write (int               fd,
280              const DBusString *buffer,
281              int               start,
282              int               len)
283 {
284   const char *data;
285   int bytes_written;
286   
287   data = _dbus_string_get_const_data_len (buffer, start, len);
288   
289  again:
290
291   bytes_written = write (fd, data, len);
292
293   if (bytes_written < 0 && errno == EINTR)
294     goto again;
295
296 #if 0
297   if (bytes_written > 0)
298     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
299 #endif
300   
301   return bytes_written;
302 }
303
304 /**
305  * Like _dbus_write() but will use writev() if possible
306  * to write both buffers in sequence. The return value
307  * is the number of bytes written in the first buffer,
308  * plus the number written in the second. If the first
309  * buffer is written successfully and an error occurs
310  * writing the second, the number of bytes in the first
311  * is returned (i.e. the error is ignored), on systems that
312  * don't have writev. Handles EINTR for you.
313  * The second buffer may be #NULL.
314  *
315  * @param fd the file descriptor
316  * @param buffer1 first buffer
317  * @param start1 first byte to write in first buffer
318  * @param len1 number of bytes to write from first buffer
319  * @param buffer2 second buffer, or #NULL
320  * @param start2 first byte to write in second buffer
321  * @param len2 number of bytes to write in second buffer
322  * @returns total bytes written from both buffers, or -1 on error
323  */
324 int
325 _dbus_write_two (int               fd,
326                  const DBusString *buffer1,
327                  int               start1,
328                  int               len1,
329                  const DBusString *buffer2,
330                  int               start2,
331                  int               len2)
332 {
333   _dbus_assert (buffer1 != NULL);
334   _dbus_assert (start1 >= 0);
335   _dbus_assert (start2 >= 0);
336   _dbus_assert (len1 >= 0);
337   _dbus_assert (len2 >= 0);
338   
339 #ifdef HAVE_WRITEV
340   {
341     struct iovec vectors[2];
342     const char *data1;
343     const char *data2;
344     int bytes_written;
345
346     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
347
348     if (buffer2 != NULL)
349       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
350     else
351       {
352         data2 = NULL;
353         start2 = 0;
354         len2 = 0;
355       }
356    
357     vectors[0].iov_base = (char*) data1;
358     vectors[0].iov_len = len1;
359     vectors[1].iov_base = (char*) data2;
360     vectors[1].iov_len = len2;
361
362   again:
363    
364     bytes_written = writev (fd,
365                             vectors,
366                             data2 ? 2 : 1);
367
368     if (bytes_written < 0 && errno == EINTR)
369       goto again;
370    
371     return bytes_written;
372   }
373 #else /* HAVE_WRITEV */
374   {
375     int ret1;
376     
377     ret1 = _dbus_write (fd, buffer1, start1, len1);
378     if (ret1 == len1 && buffer2 != NULL)
379       {
380         ret2 = _dbus_write (fd, buffer2, start2, len2);
381         if (ret2 < 0)
382           ret2 = 0; /* we can't report an error as the first write was OK */
383        
384         return ret1 + ret2;
385       }
386     else
387       return ret1;
388   }
389 #endif /* !HAVE_WRITEV */   
390 }
391
392 #define _DBUS_MAX_SUN_PATH_LENGTH 99
393
394 /**
395  * @def _DBUS_MAX_SUN_PATH_LENGTH
396  *
397  * Maximum length of the path to a UNIX domain socket,
398  * sockaddr_un::sun_path member. POSIX requires that all systems
399  * support at least 100 bytes here, including the nul termination.
400  * We use 99 for the max value to allow for the nul.
401  *
402  * We could probably also do sizeof (addr.sun_path)
403  * but this way we are the same on all platforms
404  * which is probably a good idea.
405  */
406
407 /**
408  * Creates a socket and connects it to the UNIX domain socket at the
409  * given path.  The connection fd is returned, and is set up as
410  * nonblocking.
411  * 
412  * Uses abstract sockets instead of filesystem-linked sockets if
413  * requested (it's possible only on Linux; see "man 7 unix" on Linux).
414  * On non-Linux abstract socket usage always fails.
415  *
416  * @param path the path to UNIX domain socket
417  * @param abstract #TRUE to use abstract namespace
418  * @param error return location for error code
419  * @returns connection file descriptor or -1 on error
420  */
421 int
422 _dbus_connect_unix_socket (const char     *path,
423                            dbus_bool_t     abstract,
424                            DBusError      *error)
425 {
426   int fd;
427   size_t path_len;
428   struct sockaddr_un addr;  
429
430   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
431
432   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
433                  path, abstract);
434   
435   
436   if (!_dbus_open_unix_socket (&fd, error))
437     {
438       _DBUS_ASSERT_ERROR_IS_SET(error);
439       return -1;
440     }
441   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
442
443   _DBUS_ZERO (addr);
444   addr.sun_family = AF_UNIX;
445   path_len = strlen (path);
446
447   if (abstract)
448     {
449 #ifdef HAVE_ABSTRACT_SOCKETS
450       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
451       path_len++; /* Account for the extra nul byte added to the start of sun_path */
452
453       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
454         {
455           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
456                       "Abstract socket name too long\n");
457           _dbus_close (fd, NULL);
458           return -1;
459         }
460         
461       strncpy (&addr.sun_path[1], path, path_len);
462       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
463 #else /* HAVE_ABSTRACT_SOCKETS */
464       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
465                       "Operating system does not support abstract socket namespace\n");
466       _dbus_close (fd, NULL);
467       return -1;
468 #endif /* ! HAVE_ABSTRACT_SOCKETS */
469     }
470   else
471     {
472       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
473         {
474           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
475                       "Socket name too long\n");
476           _dbus_close (fd, NULL);
477           return -1;
478         }
479
480       strncpy (addr.sun_path, path, path_len);
481     }
482   
483   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
484     {      
485       dbus_set_error (error,
486                       _dbus_error_from_errno (errno),
487                       "Failed to connect to socket %s: %s",
488                       path, _dbus_strerror (errno));
489
490       _dbus_close (fd, NULL);
491       fd = -1;
492       
493       return -1;
494     }
495
496   if (!_dbus_set_fd_nonblocking (fd, error))
497     {
498       _DBUS_ASSERT_ERROR_IS_SET (error);
499       
500       _dbus_close (fd, NULL);
501       fd = -1;
502
503       return -1;
504     }
505
506   return fd;
507 }
508
509 /**
510  * Enables or disables the reception of credentials on the given socket during
511  * the next message transmission.  This is only effective if the #LOCAL_CREDS
512  * system feature exists, in which case the other side of the connection does
513  * not have to do anything special to send the credentials.
514  *
515  * @param fd socket on which to change the #LOCAL_CREDS flag.
516  * @param on whether to enable or disable the #LOCAL_CREDS flag.
517  */
518 static dbus_bool_t
519 _dbus_set_local_creds (int fd, dbus_bool_t on)
520 {
521   dbus_bool_t retval = TRUE;
522
523 #if defined(LOCAL_CREDS) && !defined(HAVE_CMSGCRED)
524   int val = on ? 1 : 0;
525   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
526     {
527       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
528       retval = FALSE;
529     }
530   else
531     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
532                    on ? "enabled" : "disabled", fd);
533 #endif
534
535   return retval;
536 }
537
538 /**
539  * Creates a socket and binds it to the given path,
540  * then listens on the socket. The socket is
541  * set to be nonblocking.
542  *
543  * Uses abstract sockets instead of filesystem-linked
544  * sockets if requested (it's possible only on Linux;
545  * see "man 7 unix" on Linux).
546  * On non-Linux abstract socket usage always fails.
547  *
548  * @param path the socket name
549  * @param abstract #TRUE to use abstract namespace
550  * @param error return location for errors
551  * @returns the listening file descriptor or -1 on error
552  */
553 int
554 _dbus_listen_unix_socket (const char     *path,
555                           dbus_bool_t     abstract,
556                           DBusError      *error)
557 {
558   int listen_fd;
559   struct sockaddr_un addr;
560   size_t path_len;
561
562   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
563
564   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
565                  path, abstract);
566   
567   if (!_dbus_open_unix_socket (&listen_fd, error))
568     {
569       _DBUS_ASSERT_ERROR_IS_SET(error);
570       return -1;
571     }
572   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
573
574   _DBUS_ZERO (addr);
575   addr.sun_family = AF_UNIX;
576   path_len = strlen (path);
577   
578   if (abstract)
579     {
580 #ifdef HAVE_ABSTRACT_SOCKETS
581       /* remember that abstract names aren't nul-terminated so we rely
582        * on sun_path being filled in with zeroes above.
583        */
584       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
585       path_len++; /* Account for the extra nul byte added to the start of sun_path */
586
587       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
588         {
589           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
590                       "Abstract socket name too long\n");
591           _dbus_close (listen_fd, NULL);
592           return -1;
593         }
594       
595       strncpy (&addr.sun_path[1], path, path_len);
596       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
597 #else /* HAVE_ABSTRACT_SOCKETS */
598       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
599                       "Operating system does not support abstract socket namespace\n");
600       _dbus_close (listen_fd, NULL);
601       return -1;
602 #endif /* ! HAVE_ABSTRACT_SOCKETS */
603     }
604   else
605     {
606       /* Discussed security implications of this with Nalin,
607        * and we couldn't think of where it would kick our ass, but
608        * it still seems a bit sucky. It also has non-security suckage;
609        * really we'd prefer to exit if the socket is already in use.
610        * But there doesn't seem to be a good way to do this.
611        *
612        * Just to be extra careful, I threw in the stat() - clearly
613        * the stat() can't *fix* any security issue, but it at least
614        * avoids inadvertent/accidental data loss.
615        */
616       {
617         struct stat sb;
618
619         if (stat (path, &sb) == 0 &&
620             S_ISSOCK (sb.st_mode))
621           unlink (path);
622       }
623
624       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
625         {
626           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
627                       "Abstract socket name too long\n");
628           _dbus_close (listen_fd, NULL);
629           return -1;
630         }
631         
632       strncpy (addr.sun_path, path, path_len);
633     }
634   
635   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
636     {
637       dbus_set_error (error, _dbus_error_from_errno (errno),
638                       "Failed to bind socket \"%s\": %s",
639                       path, _dbus_strerror (errno));
640       _dbus_close (listen_fd, NULL);
641       return -1;
642     }
643
644   if (listen (listen_fd, 30 /* backlog */) < 0)
645     {
646       dbus_set_error (error, _dbus_error_from_errno (errno),
647                       "Failed to listen on socket \"%s\": %s",
648                       path, _dbus_strerror (errno));
649       _dbus_close (listen_fd, NULL);
650       return -1;
651     }
652
653   if (!_dbus_set_local_creds (listen_fd, TRUE))
654     {
655       dbus_set_error (error, _dbus_error_from_errno (errno),
656                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
657                       path, _dbus_strerror (errno));
658       close (listen_fd);
659       return -1;
660     }
661
662   if (!_dbus_set_fd_nonblocking (listen_fd, error))
663     {
664       _DBUS_ASSERT_ERROR_IS_SET (error);
665       _dbus_close (listen_fd, NULL);
666       return -1;
667     }
668   
669   /* Try opening up the permissions, but if we can't, just go ahead
670    * and continue, maybe it will be good enough.
671    */
672   if (!abstract && chmod (path, 0777) < 0)
673     _dbus_warn ("Could not set mode 0777 on socket %s\n",
674                 path);
675   
676   return listen_fd;
677 }
678
679 /**
680  * Creates a socket and connects to a socket at the given host 
681  * and port. The connection fd is returned, and is set up as
682  * nonblocking.
683  *
684  * @param host the host name to connect to
685  * @param port the prot to connect to
686  * @param error return location for error code
687  * @returns connection file descriptor or -1 on error
688  */
689 int
690 _dbus_connect_tcp_socket (const char     *host,
691                           dbus_uint32_t   port,
692                           DBusError      *error)
693 {
694   int fd;
695   struct sockaddr_in addr;
696   struct hostent *he;
697   struct in_addr *haddr;
698
699   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
700  
701   
702   if (!_dbus_open_tcp_socket (&fd, error))
703     {
704       _DBUS_ASSERT_ERROR_IS_SET(error);
705       
706       return -1;
707     }
708   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
709       
710   if (host == NULL)
711     host = "localhost";
712
713   he = gethostbyname (host);
714   if (he == NULL) 
715     {
716       dbus_set_error (error,
717                       _dbus_error_from_errno (errno),
718                       "Failed to lookup hostname: %s",
719                       host);
720       _dbus_close (fd, NULL);
721       return -1;
722     }
723   
724   haddr = ((struct in_addr *) (he->h_addr_list)[0]);
725
726   _DBUS_ZERO (addr);
727   memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
728   addr.sin_family = AF_INET;
729   addr.sin_port = htons (port);
730   
731   if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
732     {      
733       dbus_set_error (error,
734                        _dbus_error_from_errno (errno),
735                       "Failed to connect to socket %s:%d %s",
736                       host, port, _dbus_strerror (errno));
737
738       _dbus_close (fd, NULL);
739       fd = -1;
740       
741       return -1;
742     }
743
744   if (!_dbus_set_fd_nonblocking (fd, error))
745     {
746       _dbus_close (fd, NULL);
747       fd = -1;
748
749       return -1;
750     }
751
752   return fd;
753 }
754
755 /**
756  * Creates a socket and binds it to the given path,
757  * then listens on the socket. The socket is
758  * set to be nonblocking. 
759  *
760  * @param host the host name to listen on
761  * @param port the prot to listen on
762  * @param error return location for errors
763  * @returns the listening file descriptor or -1 on error
764  */
765 int
766 _dbus_listen_tcp_socket (const char     *host,
767                          dbus_uint32_t   port,
768                          DBusError      *error)
769 {
770   int listen_fd;
771   struct sockaddr_in addr;
772   struct hostent *he;
773   struct in_addr *haddr;
774
775   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
776   
777   
778   if (!_dbus_open_tcp_socket (&listen_fd, error))
779     {
780       _DBUS_ASSERT_ERROR_IS_SET(error);
781       return -1;
782     }
783   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
784
785   he = gethostbyname (host);
786   if (he == NULL) 
787     {
788       dbus_set_error (error,
789                       _dbus_error_from_errno (errno),
790                       "Failed to lookup hostname: %s",
791                       host);
792       _dbus_close (listen_fd, NULL);
793       return -1;
794     }
795   
796   haddr = ((struct in_addr *) (he->h_addr_list)[0]);
797
798   _DBUS_ZERO (addr);
799   memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
800   addr.sin_family = AF_INET;
801   addr.sin_port = htons (port);
802
803   if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
804     {
805       dbus_set_error (error, _dbus_error_from_errno (errno),
806                       "Failed to bind socket \"%s:%d\": %s",
807                       host, port, _dbus_strerror (errno));
808       _dbus_close (listen_fd, NULL);
809       return -1;
810     }
811
812   if (listen (listen_fd, 30 /* backlog */) < 0)
813     {
814       dbus_set_error (error, _dbus_error_from_errno (errno),  
815                       "Failed to listen on socket \"%s:%d\": %s",
816                       host, port, _dbus_strerror (errno));
817       _dbus_close (listen_fd, NULL);
818       return -1;
819     }
820
821   if (!_dbus_set_fd_nonblocking (listen_fd, error))
822     {
823       _dbus_close (listen_fd, NULL);
824       return -1;
825     }
826   
827   return listen_fd;
828 }
829
830 static dbus_bool_t
831 write_credentials_byte (int             server_fd,
832                         DBusError      *error)
833 {
834   int bytes_written;
835   char buf[1] = { '\0' };
836 #if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
837   struct {
838           struct cmsghdr hdr;
839           struct cmsgcred cred;
840   } cmsg;
841   struct iovec iov;
842   struct msghdr msg;
843 #endif
844
845 #if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
846   iov.iov_base = buf;
847   iov.iov_len = 1;
848
849   memset (&msg, 0, sizeof (msg));
850   msg.msg_iov = &iov;
851   msg.msg_iovlen = 1;
852
853   msg.msg_control = &cmsg;
854   msg.msg_controllen = sizeof (cmsg);
855   memset (&cmsg, 0, sizeof (cmsg));
856   cmsg.hdr.cmsg_len = sizeof (cmsg);
857   cmsg.hdr.cmsg_level = SOL_SOCKET;
858   cmsg.hdr.cmsg_type = SCM_CREDS;
859 #endif
860
861   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
862   
863  again:
864
865 #if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
866   bytes_written = sendmsg (server_fd, &msg, 0);
867 #else
868   bytes_written = write (server_fd, buf, 1);
869 #endif
870
871   if (bytes_written < 0 && errno == EINTR)
872     goto again;
873
874   if (bytes_written < 0)
875     {
876       dbus_set_error (error, _dbus_error_from_errno (errno),
877                       "Failed to write credentials byte: %s",
878                      _dbus_strerror (errno));
879       return FALSE;
880     }
881   else if (bytes_written == 0)
882     {
883       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
884                       "wrote zero bytes writing credentials byte");
885       return FALSE;
886     }
887   else
888     {
889       _dbus_assert (bytes_written == 1);
890       _dbus_verbose ("wrote credentials byte\n");
891       return TRUE;
892     }
893 }
894
895 /**
896  * Reads a single byte which must be nul (an error occurs otherwise),
897  * and reads unix credentials if available. Fills in pid/uid/gid with
898  * -1 if no credentials are available. Return value indicates whether
899  * a byte was read, not whether we got valid credentials. On some
900  * systems, such as Linux, reading/writing the byte isn't actually
901  * required, but we do it anyway just to avoid multiple codepaths.
902  * 
903  * Fails if no byte is available, so you must select() first.
904  *
905  * The point of the byte is that on some systems we have to
906  * use sendmsg()/recvmsg() to transmit credentials.
907  *
908  * @param client_fd the client file descriptor
909  * @param credentials struct to fill with credentials of client
910  * @param error location to store error code
911  * @returns #TRUE on success
912  */
913 dbus_bool_t
914 _dbus_read_credentials_unix_socket  (int              client_fd,
915                                      DBusCredentials *credentials,
916                                      DBusError       *error)
917 {
918   struct msghdr msg;
919   struct iovec iov;
920   char buf;
921
922 #ifdef HAVE_CMSGCRED 
923   struct {
924           struct cmsghdr hdr;
925           struct cmsgcred cred;
926   } cmsg;
927
928 #elif defined(LOCAL_CREDS)
929   struct {
930           struct cmsghdr hdr;
931           struct sockcred cred;
932   } cmsg;
933 #endif
934
935   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
936   
937   /* The POSIX spec certainly doesn't promise this, but
938    * we need these assertions to fail as soon as we're wrong about
939    * it so we can do the porting fixups
940    */
941   _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
942   _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
943   _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
944
945   _dbus_credentials_clear (credentials);
946
947   /* Systems supporting LOCAL_CREDS are configured to have this feature
948    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
949    * the connection.  Therefore, the received message must carry the
950    * credentials information without doing anything special.
951    */
952
953   iov.iov_base = &buf;
954   iov.iov_len = 1;
955
956   memset (&msg, 0, sizeof (msg));
957   msg.msg_iov = &iov;
958   msg.msg_iovlen = 1;
959
960 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
961   memset (&cmsg, 0, sizeof (cmsg));
962   msg.msg_control = &cmsg;
963   msg.msg_controllen = sizeof (cmsg);
964 #endif
965
966  again:
967   if (recvmsg (client_fd, &msg, 0) < 0)
968     {
969       if (errno == EINTR)
970         goto again;
971
972       dbus_set_error (error, _dbus_error_from_errno (errno),
973                       "Failed to read credentials byte: %s",
974                       _dbus_strerror (errno));
975       return FALSE;
976     }
977
978   if (buf != '\0')
979     {
980       dbus_set_error (error, DBUS_ERROR_FAILED,
981                       "Credentials byte was not nul");
982       return FALSE;
983     }
984
985 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
986   if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
987     {
988       dbus_set_error (error, DBUS_ERROR_FAILED,
989                       "Message from recvmsg() was not SCM_CREDS");
990       return FALSE;
991     }
992 #endif
993
994   _dbus_verbose ("read credentials byte\n");
995
996   {
997 #ifdef SO_PEERCRED
998     struct ucred cr;   
999     int cr_len = sizeof (cr);
1000    
1001     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1002         cr_len == sizeof (cr))
1003       {
1004         credentials->pid = cr.pid;
1005         credentials->uid = cr.uid;
1006         credentials->gid = cr.gid;
1007       }
1008     else
1009       {
1010         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1011                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1012       }
1013 #elif defined(HAVE_CMSGCRED)
1014     credentials->pid = cmsg.cred.cmcred_pid;
1015     credentials->uid = cmsg.cred.cmcred_euid;
1016     credentials->gid = cmsg.cred.cmcred_groups[0];
1017 #elif defined(LOCAL_CREDS)
1018     credentials->pid = DBUS_PID_UNSET;
1019     credentials->uid = cmsg.cred.sc_uid;
1020     credentials->gid = cmsg.cred.sc_gid;
1021     /* Since we have already got the credentials from this socket, we can
1022      * disable its LOCAL_CREDS flag if it was ever set. */
1023     _dbus_set_local_creds (client_fd, FALSE);
1024 #elif defined(HAVE_GETPEEREID)
1025     uid_t euid;
1026     gid_t egid;
1027     if (getpeereid (client_fd, &euid, &egid) == 0)
1028       {
1029         credentials->uid = euid;
1030         credentials->gid = egid;
1031       }
1032     else
1033       {
1034         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1035       }
1036 #elif defined(HAVE_GETPEERUCRED)
1037     ucred_t * ucred = NULL;
1038     if (getpeerucred (client_fd, &ucred) == 0)
1039       {
1040         credentials->pid = ucred_getpid (ucred);
1041         credentials->uid = ucred_geteuid (ucred);
1042         credentials->gid = ucred_getegid (ucred);
1043       }
1044     else
1045       {
1046         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1047       }
1048     if (ucred != NULL)
1049       ucred_free (ucred);
1050 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1051     _dbus_verbose ("Socket credentials not supported on this OS\n");
1052 #endif
1053   }
1054
1055   _dbus_verbose ("Credentials:"
1056                  "  pid "DBUS_PID_FORMAT
1057                  "  uid "DBUS_UID_FORMAT
1058                  "  gid "DBUS_GID_FORMAT"\n",
1059                  credentials->pid,
1060                  credentials->uid,
1061                  credentials->gid);
1062     
1063   return TRUE;
1064 }
1065
1066 /**
1067  * Sends a single nul byte with our UNIX credentials as ancillary
1068  * data.  Returns #TRUE if the data was successfully written.  On
1069  * systems that don't support sending credentials, just writes a byte,
1070  * doesn't send any credentials.  On some systems, such as Linux,
1071  * reading/writing the byte isn't actually required, but we do it
1072  * anyway just to avoid multiple codepaths.
1073  *
1074  * Fails if no byte can be written, so you must select() first.
1075  *
1076  * The point of the byte is that on some systems we have to
1077  * use sendmsg()/recvmsg() to transmit credentials.
1078  *
1079  * @param server_fd file descriptor for connection to server
1080  * @param error return location for error code
1081  * @returns #TRUE if the byte was sent
1082  */
1083 dbus_bool_t
1084 _dbus_send_credentials_unix_socket  (int              server_fd,
1085                                      DBusError       *error)
1086 {
1087   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1088   
1089   if (write_credentials_byte (server_fd, error))
1090     return TRUE;
1091   else
1092     return FALSE;
1093 }
1094
1095 /**
1096  * Accepts a connection on a listening socket.
1097  * Handles EINTR for you.
1098  *
1099  * @param listen_fd the listen file descriptor
1100  * @returns the connection fd of the client, or -1 on error
1101  */
1102 int
1103 _dbus_accept  (int listen_fd)
1104 {
1105   int client_fd;
1106   struct sockaddr addr;
1107   socklen_t addrlen;
1108
1109   addrlen = sizeof (addr);
1110   
1111  retry:
1112   client_fd = accept (listen_fd, &addr, &addrlen);
1113   
1114   if (client_fd < 0)
1115     {
1116       if (errno == EINTR)
1117         goto retry;
1118     }
1119   
1120   return client_fd;
1121 }
1122
1123 /**
1124  * Checks to make sure the given directory is 
1125  * private to the user 
1126  *
1127  * @param dir the name of the directory
1128  * @param error error return
1129  * @returns #FALSE on failure
1130  **/
1131 dbus_bool_t
1132 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1133 {
1134   const char *directory;
1135   struct stat sb;
1136         
1137   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1138     
1139   directory = _dbus_string_get_const_data (dir);
1140         
1141   if (stat (directory, &sb) < 0)
1142     {
1143       dbus_set_error (error, _dbus_error_from_errno (errno),
1144                       "%s", _dbus_strerror (errno));
1145    
1146       return FALSE;
1147     }
1148     
1149   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1150       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1151     {
1152       dbus_set_error (error, DBUS_ERROR_FAILED,
1153                      "%s directory is not private to the user", directory);
1154       return FALSE;
1155     }
1156     
1157   return TRUE;
1158 }
1159
1160 static dbus_bool_t
1161 fill_user_info_from_passwd (struct passwd *p,
1162                             DBusUserInfo  *info,
1163                             DBusError     *error)
1164 {
1165   _dbus_assert (p->pw_name != NULL);
1166   _dbus_assert (p->pw_dir != NULL);
1167   
1168   info->uid = p->pw_uid;
1169   info->primary_gid = p->pw_gid;
1170   info->username = _dbus_strdup (p->pw_name);
1171   info->homedir = _dbus_strdup (p->pw_dir);
1172   
1173   if (info->username == NULL ||
1174       info->homedir == NULL)
1175     {
1176       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1177       return FALSE;
1178     }
1179
1180   return TRUE;
1181 }
1182
1183 static dbus_bool_t
1184 fill_user_info (DBusUserInfo       *info,
1185                 dbus_uid_t          uid,
1186                 const DBusString   *username,
1187                 DBusError          *error)
1188 {
1189   const char *username_c;
1190   
1191   /* exactly one of username/uid provided */
1192   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1193   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1194
1195   info->uid = DBUS_UID_UNSET;
1196   info->primary_gid = DBUS_GID_UNSET;
1197   info->group_ids = NULL;
1198   info->n_group_ids = 0;
1199   info->username = NULL;
1200   info->homedir = NULL;
1201   
1202   if (username != NULL)
1203     username_c = _dbus_string_get_const_data (username);
1204   else
1205     username_c = NULL;
1206
1207   /* For now assuming that the getpwnam() and getpwuid() flavors
1208    * are always symmetrical, if not we have to add more configure
1209    * checks
1210    */
1211   
1212 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1213   {
1214     struct passwd *p;
1215     int result;
1216     char buf[1024];
1217     struct passwd p_str;
1218
1219     p = NULL;
1220 #ifdef HAVE_POSIX_GETPWNAM_R
1221     if (uid != DBUS_UID_UNSET)
1222       result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
1223                            &p);
1224     else
1225       result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
1226                            &p);
1227 #else
1228     if (uid != DBUS_UID_UNSET)
1229       p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
1230     else
1231       p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
1232     result = 0;
1233 #endif /* !HAVE_POSIX_GETPWNAM_R */
1234     if (result == 0 && p == &p_str)
1235       {
1236         if (!fill_user_info_from_passwd (p, info, error))
1237           return FALSE;
1238       }
1239     else
1240       {
1241         dbus_set_error (error, _dbus_error_from_errno (errno),
1242                         "User \"%s\" unknown or no memory to allocate password entry\n",
1243                         username_c ? username_c : "???");
1244         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1245         return FALSE;
1246       }
1247   }
1248 #else /* ! HAVE_GETPWNAM_R */
1249   {
1250     /* I guess we're screwed on thread safety here */
1251     struct passwd *p;
1252
1253     if (uid != DBUS_UID_UNSET)
1254       p = getpwuid (uid);
1255     else
1256       p = getpwnam (username_c);
1257
1258     if (p != NULL)
1259       {
1260         if (!fill_user_info_from_passwd (p, info, error))
1261           return FALSE;
1262       }
1263     else
1264       {
1265         dbus_set_error (error, _dbus_error_from_errno (errno),
1266                         "User \"%s\" unknown or no memory to allocate password entry\n",
1267                         username_c ? username_c : "???");
1268         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1269         return FALSE;
1270       }
1271   }
1272 #endif  /* ! HAVE_GETPWNAM_R */
1273
1274   /* Fill this in so we can use it to get groups */
1275   username_c = info->username;
1276   
1277 #ifdef HAVE_GETGROUPLIST
1278   {
1279     gid_t *buf;
1280     int buf_count;
1281     int i;
1282     
1283     buf_count = 17;
1284     buf = dbus_new (gid_t, buf_count);
1285     if (buf == NULL)
1286       {
1287         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1288         goto failed;
1289       }
1290     
1291     if (getgrouplist (username_c,
1292                       info->primary_gid,
1293                       buf, &buf_count) < 0)
1294       {
1295         gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1296         if (new == NULL)
1297           {
1298             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1299             dbus_free (buf);
1300             goto failed;
1301           }
1302         
1303         buf = new;
1304
1305         errno = 0;
1306         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
1307           {
1308             dbus_set_error (error,
1309                             _dbus_error_from_errno (errno),
1310                             "Failed to get groups for username \"%s\" primary GID "
1311                             DBUS_GID_FORMAT ": %s\n",
1312                             username_c, info->primary_gid,
1313                             _dbus_strerror (errno));
1314             dbus_free (buf);
1315             goto failed;
1316           }
1317       }
1318
1319     info->group_ids = dbus_new (dbus_gid_t, buf_count);
1320     if (info->group_ids == NULL)
1321       {
1322         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1323         dbus_free (buf);
1324         goto failed;
1325       }
1326     
1327     for (i = 0; i < buf_count; ++i)
1328       info->group_ids[i] = buf[i];
1329
1330     info->n_group_ids = buf_count;
1331     
1332     dbus_free (buf);
1333   }
1334 #else  /* HAVE_GETGROUPLIST */
1335   {
1336     /* We just get the one group ID */
1337     info->group_ids = dbus_new (dbus_gid_t, 1);
1338     if (info->group_ids == NULL)
1339       {
1340         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1341         goto failed;
1342       }
1343
1344     info->n_group_ids = 1;
1345
1346     (info->group_ids)[0] = info->primary_gid;
1347   }
1348 #endif /* HAVE_GETGROUPLIST */
1349
1350   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1351   
1352   return TRUE;
1353   
1354  failed:
1355   _DBUS_ASSERT_ERROR_IS_SET (error);
1356   return FALSE;
1357 }
1358
1359 /**
1360  * Gets user info for the given username.
1361  *
1362  * @param info user info object to initialize
1363  * @param username the username
1364  * @param error error return
1365  * @returns #TRUE on success
1366  */
1367 dbus_bool_t
1368 _dbus_user_info_fill (DBusUserInfo     *info,
1369                       const DBusString *username,
1370                       DBusError        *error)
1371 {
1372   return fill_user_info (info, DBUS_UID_UNSET,
1373                          username, error);
1374 }
1375
1376 /**
1377  * Gets user info for the given user ID.
1378  *
1379  * @param info user info object to initialize
1380  * @param uid the user ID
1381  * @param error error return
1382  * @returns #TRUE on success
1383  */
1384 dbus_bool_t
1385 _dbus_user_info_fill_uid (DBusUserInfo *info,
1386                           dbus_uid_t    uid,
1387                           DBusError    *error)
1388 {
1389   return fill_user_info (info, uid,
1390                          NULL, error);
1391 }
1392
1393 /**
1394  * Gets the credentials of the current process.
1395  *
1396  * @param credentials credentials to fill in.
1397  */
1398 void
1399 _dbus_credentials_from_current_process (DBusCredentials *credentials)
1400 {
1401   /* The POSIX spec certainly doesn't promise this, but
1402    * we need these assertions to fail as soon as we're wrong about
1403    * it so we can do the porting fixups
1404    */
1405   _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
1406   _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
1407   _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
1408   
1409   credentials->pid = getpid ();
1410   credentials->uid = getuid ();
1411   credentials->gid = getgid ();
1412 }
1413
1414 /**
1415  * Gets our process ID
1416  * @returns process ID
1417  */
1418 unsigned long
1419 _dbus_getpid (void)
1420 {
1421   return getpid ();
1422 }
1423
1424 /** Gets our UID
1425  * @returns process UID
1426  */
1427 dbus_uid_t
1428 _dbus_getuid (void)
1429 {
1430   return getuid ();
1431 }
1432
1433 #ifdef DBUS_BUILD_TESTS
1434 /** Gets our GID
1435  * @returns process GID
1436  */
1437 dbus_gid_t
1438 _dbus_getgid (void)
1439 {
1440   return getgid ();
1441 }
1442 #endif
1443
1444 /**
1445  * Wrapper for poll().
1446  *
1447  * @param fds the file descriptors to poll
1448  * @param n_fds number of descriptors in the array
1449  * @param timeout_milliseconds timeout or -1 for infinite
1450  * @returns numbers of fds with revents, or <0 on error
1451  */
1452 int
1453 _dbus_poll (DBusPollFD *fds,
1454             int         n_fds,
1455             int         timeout_milliseconds)
1456 {
1457 #ifdef HAVE_POLL
1458   /* This big thing is a constant expression and should get optimized
1459    * out of existence. So it's more robust than a configure check at
1460    * no cost.
1461    */
1462   if (_DBUS_POLLIN == POLLIN &&
1463       _DBUS_POLLPRI == POLLPRI &&
1464       _DBUS_POLLOUT == POLLOUT &&
1465       _DBUS_POLLERR == POLLERR &&
1466       _DBUS_POLLHUP == POLLHUP &&
1467       _DBUS_POLLNVAL == POLLNVAL &&
1468       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
1469       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
1470       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
1471       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
1472       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
1473       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
1474       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
1475     {
1476       return poll ((struct pollfd*) fds,
1477                    n_fds, 
1478                    timeout_milliseconds);
1479     }
1480   else
1481     {
1482       /* We have to convert the DBusPollFD to an array of
1483        * struct pollfd, poll, and convert back.
1484        */
1485       _dbus_warn ("didn't implement poll() properly for this system yet\n");
1486       return -1;
1487     }
1488 #else /* ! HAVE_POLL */
1489
1490   fd_set read_set, write_set, err_set;
1491   int max_fd = 0;
1492   int i;
1493   struct timeval tv;
1494   int ready;
1495   
1496   FD_ZERO (&read_set);
1497   FD_ZERO (&write_set);
1498   FD_ZERO (&err_set);
1499
1500   for (i = 0; i < n_fds; i++)
1501     {
1502       DBusPollFD *fdp = &fds[i];
1503
1504       if (fdp->events & _DBUS_POLLIN)
1505         FD_SET (fdp->fd, &read_set);
1506
1507       if (fdp->events & _DBUS_POLLOUT)
1508         FD_SET (fdp->fd, &write_set);
1509
1510       FD_SET (fdp->fd, &err_set);
1511
1512       max_fd = MAX (max_fd, fdp->fd);
1513     }
1514     
1515   tv.tv_sec = timeout_milliseconds / 1000;
1516   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
1517
1518   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
1519                   timeout_milliseconds < 0 ? NULL : &tv);
1520
1521   if (ready > 0)
1522     {
1523       for (i = 0; i < n_fds; i++)
1524         {
1525           DBusPollFD *fdp = &fds[i];
1526
1527           fdp->revents = 0;
1528
1529           if (FD_ISSET (fdp->fd, &read_set))
1530             fdp->revents |= _DBUS_POLLIN;
1531
1532           if (FD_ISSET (fdp->fd, &write_set))
1533             fdp->revents |= _DBUS_POLLOUT;
1534
1535           if (FD_ISSET (fdp->fd, &err_set))
1536             fdp->revents |= _DBUS_POLLERR;
1537         }
1538     }
1539
1540   return ready;
1541 #endif
1542 }
1543
1544 /**
1545  * Get current time, as in gettimeofday().
1546  *
1547  * @param tv_sec return location for number of seconds
1548  * @param tv_usec return location for number of microseconds (thousandths)
1549  */
1550 void
1551 _dbus_get_current_time (long *tv_sec,
1552                         long *tv_usec)
1553 {
1554   struct timeval t;
1555
1556   gettimeofday (&t, NULL);
1557
1558   if (tv_sec)
1559     *tv_sec = t.tv_sec;
1560   if (tv_usec)
1561     *tv_usec = t.tv_usec;
1562 }
1563
1564 /**
1565  * Appends the contents of the given file to the string,
1566  * returning error code. At the moment, won't open a file
1567  * more than a megabyte in size.
1568  *
1569  * @param str the string to append to
1570  * @param filename filename to load
1571  * @param error place to set an error
1572  * @returns #FALSE if error was set
1573  */
1574 dbus_bool_t
1575 _dbus_file_get_contents (DBusString       *str,
1576                          const DBusString *filename,
1577                          DBusError        *error)
1578 {
1579   int fd;
1580   struct stat sb;
1581   int orig_len;
1582   int total;
1583   const char *filename_c;
1584
1585   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1586   
1587   filename_c = _dbus_string_get_const_data (filename);
1588   
1589   /* O_BINARY useful on Cygwin */
1590   fd = open (filename_c, O_RDONLY | O_BINARY);
1591   if (fd < 0)
1592     {
1593       dbus_set_error (error, _dbus_error_from_errno (errno),
1594                       "Failed to open \"%s\": %s",
1595                       filename_c,
1596                       _dbus_strerror (errno));
1597       return FALSE;
1598     }
1599
1600   if (fstat (fd, &sb) < 0)
1601     {
1602       dbus_set_error (error, _dbus_error_from_errno (errno),
1603                       "Failed to stat \"%s\": %s",
1604                       filename_c,
1605                       _dbus_strerror (errno));
1606
1607       _dbus_verbose ("fstat() failed: %s",
1608                      _dbus_strerror (errno));
1609       
1610       _dbus_close (fd, NULL);
1611       
1612       return FALSE;
1613     }
1614
1615   if (sb.st_size > _DBUS_ONE_MEGABYTE)
1616     {
1617       dbus_set_error (error, DBUS_ERROR_FAILED,
1618                       "File size %lu of \"%s\" is too large.",
1619                       (unsigned long) sb.st_size, filename_c);
1620       _dbus_close (fd, NULL);
1621       return FALSE;
1622     }
1623   
1624   total = 0;
1625   orig_len = _dbus_string_get_length (str);
1626   if (sb.st_size > 0 && S_ISREG (sb.st_mode))
1627     {
1628       int bytes_read;
1629
1630       while (total < (int) sb.st_size)
1631         {
1632           bytes_read = _dbus_read (fd, str,
1633                                    sb.st_size - total);
1634           if (bytes_read <= 0)
1635             {
1636               dbus_set_error (error, _dbus_error_from_errno (errno),
1637                               "Error reading \"%s\": %s",
1638                               filename_c,
1639                               _dbus_strerror (errno));
1640
1641               _dbus_verbose ("read() failed: %s",
1642                              _dbus_strerror (errno));
1643               
1644               _dbus_close (fd, NULL);
1645               _dbus_string_set_length (str, orig_len);
1646               return FALSE;
1647             }
1648           else
1649             total += bytes_read;
1650         }
1651
1652       _dbus_close (fd, NULL);
1653       return TRUE;
1654     }
1655   else if (sb.st_size != 0)
1656     {
1657       _dbus_verbose ("Can only open regular files at the moment.\n");
1658       dbus_set_error (error, DBUS_ERROR_FAILED,
1659                       "\"%s\" is not a regular file",
1660                       filename_c);
1661       _dbus_close (fd, NULL);
1662       return FALSE;
1663     }
1664   else
1665     {
1666       _dbus_close (fd, NULL);
1667       return TRUE;
1668     }
1669 }
1670
1671 /**
1672  * Writes a string out to a file. If the file exists,
1673  * it will be atomically overwritten by the new data.
1674  *
1675  * @param str the string to write out
1676  * @param filename the file to save string to
1677  * @param error error to be filled in on failure
1678  * @returns #FALSE on failure
1679  */
1680 dbus_bool_t
1681 _dbus_string_save_to_file (const DBusString *str,
1682                            const DBusString *filename,
1683                            DBusError        *error)
1684 {
1685   int fd;
1686   int bytes_to_write;
1687   const char *filename_c;
1688   DBusString tmp_filename;
1689   const char *tmp_filename_c;
1690   int total;
1691   dbus_bool_t need_unlink;
1692   dbus_bool_t retval;
1693
1694   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1695   
1696   fd = -1;
1697   retval = FALSE;
1698   need_unlink = FALSE;
1699   
1700   if (!_dbus_string_init (&tmp_filename))
1701     {
1702       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1703       return FALSE;
1704     }
1705
1706   if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
1707     {
1708       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1709       _dbus_string_free (&tmp_filename);
1710       return FALSE;
1711     }
1712   
1713   if (!_dbus_string_append (&tmp_filename, "."))
1714     {
1715       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1716       _dbus_string_free (&tmp_filename);
1717       return FALSE;
1718     }
1719
1720 #define N_TMP_FILENAME_RANDOM_BYTES 8
1721   if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
1722     {
1723       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1724       _dbus_string_free (&tmp_filename);
1725       return FALSE;
1726     }
1727     
1728   filename_c = _dbus_string_get_const_data (filename);
1729   tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
1730
1731   fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
1732              0600);
1733   if (fd < 0)
1734     {
1735       dbus_set_error (error, _dbus_error_from_errno (errno),
1736                       "Could not create %s: %s", tmp_filename_c,
1737                       _dbus_strerror (errno));
1738       goto out;
1739     }
1740
1741   need_unlink = TRUE;
1742   
1743   total = 0;
1744   bytes_to_write = _dbus_string_get_length (str);
1745
1746   while (total < bytes_to_write)
1747     {
1748       int bytes_written;
1749
1750       bytes_written = _dbus_write (fd, str, total,
1751                                    bytes_to_write - total);
1752
1753       if (bytes_written <= 0)
1754         {
1755           dbus_set_error (error, _dbus_error_from_errno (errno),
1756                           "Could not write to %s: %s", tmp_filename_c,
1757                           _dbus_strerror (errno));
1758           
1759           goto out;
1760         }
1761
1762       total += bytes_written;
1763     }
1764
1765   if (!_dbus_close (fd, NULL))
1766     {
1767       dbus_set_error (error, _dbus_error_from_errno (errno),
1768                       "Could not close file %s: %s",
1769                       tmp_filename_c, _dbus_strerror (errno));
1770
1771       goto out;
1772     }
1773
1774   fd = -1;
1775   
1776   if (rename (tmp_filename_c, filename_c) < 0)
1777     {
1778       dbus_set_error (error, _dbus_error_from_errno (errno),
1779                       "Could not rename %s to %s: %s",
1780                       tmp_filename_c, filename_c,
1781                       _dbus_strerror (errno));
1782
1783       goto out;
1784     }
1785
1786   need_unlink = FALSE;
1787   
1788   retval = TRUE;
1789   
1790  out:
1791   /* close first, then unlink, to prevent ".nfs34234235" garbage
1792    * files
1793    */
1794
1795   if (fd >= 0)
1796     _dbus_close (fd, NULL);
1797         
1798   if (need_unlink && unlink (tmp_filename_c) < 0)
1799     _dbus_verbose ("Failed to unlink temp file %s: %s\n",
1800                    tmp_filename_c, _dbus_strerror (errno));
1801
1802   _dbus_string_free (&tmp_filename);
1803
1804   if (!retval)
1805     _DBUS_ASSERT_ERROR_IS_SET (error);
1806   
1807   return retval;
1808 }
1809
1810 /** Creates the given file, failing if the file already exists.
1811  *
1812  * @param filename the filename
1813  * @param error error location
1814  * @returns #TRUE if we created the file and it didn't exist
1815  */
1816 dbus_bool_t
1817 _dbus_create_file_exclusively (const DBusString *filename,
1818                                DBusError        *error)
1819 {
1820   int fd;
1821   const char *filename_c;
1822
1823   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1824   
1825   filename_c = _dbus_string_get_const_data (filename);
1826   
1827   fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
1828              0600);
1829   if (fd < 0)
1830     {
1831       dbus_set_error (error,
1832                       DBUS_ERROR_FAILED,
1833                       "Could not create file %s: %s\n",
1834                       filename_c,
1835                       _dbus_strerror (errno));
1836       return FALSE;
1837     }
1838
1839   if (!_dbus_close (fd, NULL))
1840     {
1841       dbus_set_error (error,
1842                       DBUS_ERROR_FAILED,
1843                       "Could not close file %s: %s\n",
1844                       filename_c,
1845                       _dbus_strerror (errno));
1846       return FALSE;
1847     }
1848   
1849   return TRUE;
1850 }
1851
1852 /**
1853  * Deletes the given file.
1854  *
1855  * @param filename the filename
1856  * @param error error location
1857  * 
1858  * @returns #TRUE if unlink() succeeded
1859  */
1860 dbus_bool_t
1861 _dbus_delete_file (const DBusString *filename,
1862                    DBusError        *error)
1863 {
1864   const char *filename_c;
1865
1866   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1867   
1868   filename_c = _dbus_string_get_const_data (filename);
1869
1870   if (unlink (filename_c) < 0)
1871     {
1872       dbus_set_error (error, DBUS_ERROR_FAILED,
1873                       "Failed to delete file %s: %s\n",
1874                       filename_c, _dbus_strerror (errno));
1875       return FALSE;
1876     }
1877   else
1878     return TRUE;
1879 }
1880
1881 /**
1882  * Creates a directory; succeeds if the directory
1883  * is created or already existed.
1884  *
1885  * @param filename directory filename
1886  * @param error initialized error object
1887  * @returns #TRUE on success
1888  */
1889 dbus_bool_t
1890 _dbus_create_directory (const DBusString *filename,
1891                         DBusError        *error)
1892 {
1893   const char *filename_c;
1894
1895   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1896   
1897   filename_c = _dbus_string_get_const_data (filename);
1898
1899   if (mkdir (filename_c, 0700) < 0)
1900     {
1901       if (errno == EEXIST)
1902         return TRUE;
1903       
1904       dbus_set_error (error, DBUS_ERROR_FAILED,
1905                       "Failed to create directory %s: %s\n",
1906                       filename_c, _dbus_strerror (errno));
1907       return FALSE;
1908     }
1909   else
1910     return TRUE;
1911 }
1912
1913 /**
1914  * Appends the given filename to the given directory.
1915  *
1916  * @todo it might be cute to collapse multiple '/' such as "foo//"
1917  * concat "//bar"
1918  *
1919  * @param dir the directory name
1920  * @param next_component the filename
1921  * @returns #TRUE on success
1922  */
1923 dbus_bool_t
1924 _dbus_concat_dir_and_file (DBusString       *dir,
1925                            const DBusString *next_component)
1926 {
1927   dbus_bool_t dir_ends_in_slash;
1928   dbus_bool_t file_starts_with_slash;
1929
1930   if (_dbus_string_get_length (dir) == 0 ||
1931       _dbus_string_get_length (next_component) == 0)
1932     return TRUE;
1933   
1934   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
1935                                                     _dbus_string_get_length (dir) - 1);
1936
1937   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
1938
1939   if (dir_ends_in_slash && file_starts_with_slash)
1940     {
1941       _dbus_string_shorten (dir, 1);
1942     }
1943   else if (!(dir_ends_in_slash || file_starts_with_slash))
1944     {
1945       if (!_dbus_string_append_byte (dir, '/'))
1946         return FALSE;
1947     }
1948
1949   return _dbus_string_copy (next_component, 0, dir,
1950                             _dbus_string_get_length (dir));
1951 }
1952
1953 /** nanoseconds in a second */
1954 #define NANOSECONDS_PER_SECOND       1000000000
1955 /** microseconds in a second */
1956 #define MICROSECONDS_PER_SECOND      1000000
1957 /** milliseconds in a second */
1958 #define MILLISECONDS_PER_SECOND      1000
1959 /** nanoseconds in a millisecond */
1960 #define NANOSECONDS_PER_MILLISECOND  1000000
1961 /** microseconds in a millisecond */
1962 #define MICROSECONDS_PER_MILLISECOND 1000
1963
1964 /**
1965  * Sleeps the given number of milliseconds.
1966  * @param milliseconds number of milliseconds
1967  */
1968 void
1969 _dbus_sleep_milliseconds (int milliseconds)
1970 {
1971 #ifdef HAVE_NANOSLEEP
1972   struct timespec req;
1973   struct timespec rem;
1974
1975   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
1976   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
1977   rem.tv_sec = 0;
1978   rem.tv_nsec = 0;
1979
1980   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
1981     req = rem;
1982 #elif defined (HAVE_USLEEP)
1983   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
1984 #else /* ! HAVE_USLEEP */
1985   sleep (MAX (milliseconds / 1000, 1));
1986 #endif
1987 }
1988
1989 static dbus_bool_t
1990 _dbus_generate_pseudorandom_bytes (DBusString *str,
1991                                    int         n_bytes)
1992 {
1993   int old_len;
1994   char *p;
1995   
1996   old_len = _dbus_string_get_length (str);
1997
1998   if (!_dbus_string_lengthen (str, n_bytes))
1999     return FALSE;
2000
2001   p = _dbus_string_get_data_len (str, old_len, n_bytes);
2002
2003   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2004
2005   return TRUE;
2006 }
2007
2008 /**
2009  * Generates the given number of random bytes,
2010  * using the best mechanism we can come up with.
2011  *
2012  * @param str the string
2013  * @param n_bytes the number of random bytes to append to string
2014  * @returns #TRUE on success, #FALSE if no memory
2015  */
2016 dbus_bool_t
2017 _dbus_generate_random_bytes (DBusString *str,
2018                              int         n_bytes)
2019 {
2020   int old_len;
2021   int fd;
2022
2023   /* FALSE return means "no memory", if it could
2024    * mean something else then we'd need to return
2025    * a DBusError. So we always fall back to pseudorandom
2026    * if the I/O fails.
2027    */
2028   
2029   old_len = _dbus_string_get_length (str);
2030   fd = -1;
2031
2032   /* note, urandom on linux will fall back to pseudorandom */
2033   fd = open ("/dev/urandom", O_RDONLY);
2034   if (fd < 0)
2035     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2036
2037   if (_dbus_read (fd, str, n_bytes) != n_bytes)
2038     {
2039       _dbus_close (fd, NULL);
2040       _dbus_string_set_length (str, old_len);
2041       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2042     }
2043
2044   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2045                  n_bytes);
2046   
2047   _dbus_close (fd, NULL);
2048   
2049   return TRUE;
2050 }
2051
2052 /**
2053  * Exit the process, returning the given value.
2054  *
2055  * @param code the exit code
2056  */
2057 void
2058 _dbus_exit (int code)
2059 {
2060   _exit (code);
2061 }
2062
2063 /**
2064  * A wrapper around strerror() because some platforms
2065  * may be lame and not have strerror().
2066  *
2067  * @param error_number errno.
2068  * @returns error description.
2069  */
2070 const char*
2071 _dbus_strerror (int error_number)
2072 {
2073   const char *msg;
2074   
2075   msg = strerror (error_number);
2076   if (msg == NULL)
2077     msg = "unknown";
2078
2079   return msg;
2080 }
2081
2082 /**
2083  * signal (SIGPIPE, SIG_IGN);
2084  */
2085 void
2086 _dbus_disable_sigpipe (void)
2087 {
2088   signal (SIGPIPE, SIG_IGN);
2089 }
2090
2091 /**
2092  * Sets the file descriptor to be close
2093  * on exec. Should be called for all file
2094  * descriptors in D-Bus code.
2095  *
2096  * @param fd the file descriptor
2097  */
2098 void
2099 _dbus_fd_set_close_on_exec (int fd)
2100 {
2101   int val;
2102   
2103   val = fcntl (fd, F_GETFD, 0);
2104   
2105   if (val < 0)
2106     return;
2107
2108   val |= FD_CLOEXEC;
2109   
2110   fcntl (fd, F_SETFD, val);
2111 }
2112
2113 /**
2114  * Closes a file descriptor.
2115  *
2116  * @param fd the file descriptor
2117  * @param error error object
2118  * @returns #FALSE if error set
2119  */
2120 dbus_bool_t
2121 _dbus_close (int        fd,
2122              DBusError *error)
2123 {
2124   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2125   
2126  again:
2127   if (close (fd) < 0)
2128     {
2129       if (errno == EINTR)
2130         goto again;
2131
2132       dbus_set_error (error, _dbus_error_from_errno (errno),
2133                       "Could not close fd %d", fd);
2134       return FALSE;
2135     }
2136
2137   return TRUE;
2138 }
2139
2140 /**
2141  * Sets a file descriptor to be nonblocking.
2142  *
2143  * @param fd the file descriptor.
2144  * @param error address of error location.
2145  * @returns #TRUE on success.
2146  */
2147 dbus_bool_t
2148 _dbus_set_fd_nonblocking (int             fd,
2149                           DBusError      *error)
2150 {
2151   int val;
2152
2153   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2154   
2155   val = fcntl (fd, F_GETFL, 0);
2156   if (val < 0)
2157     {
2158       dbus_set_error (error, _dbus_error_from_errno (errno),
2159                       "Failed to get flags from file descriptor %d: %s",
2160                       fd, _dbus_strerror (errno));
2161       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2162                      _dbus_strerror (errno));
2163       return FALSE;
2164     }
2165
2166   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2167     {
2168       dbus_set_error (error, _dbus_error_from_errno (errno),
2169                       "Failed to set nonblocking flag of file descriptor %d: %s",
2170                       fd, _dbus_strerror (errno));
2171       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2172                      fd, _dbus_strerror (errno));
2173
2174       return FALSE;
2175     }
2176
2177   return TRUE;
2178 }
2179
2180 /**
2181  * On GNU libc systems, print a crude backtrace to stderr.  On other
2182  * systems, print "no backtrace support" and block for possible gdb
2183  * attachment if an appropriate environment variable is set.
2184  */
2185 void
2186 _dbus_print_backtrace (void)
2187 {  
2188 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2189   void *bt[500];
2190   int bt_size;
2191   int i;
2192   char **syms;
2193   
2194   bt_size = backtrace (bt, 500);
2195
2196   syms = backtrace_symbols (bt, bt_size);
2197   
2198   i = 0;
2199   while (i < bt_size)
2200     {
2201       /* don't use dbus_warn since it can _dbus_abort() */
2202       fprintf (stderr, "  %s\n", syms[i]);
2203       ++i;
2204     }
2205   fflush (stderr);
2206
2207   free (syms);
2208 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2209   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
2210 #else
2211   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2212 #endif
2213 }
2214
2215 /**
2216  * Creates a full-duplex pipe (as in socketpair()).
2217  * Sets both ends of the pipe nonblocking.
2218  *
2219  * @todo libdbus only uses this for the debug-pipe server, so in
2220  * principle it could be in dbus-sysdeps-util.c, except that
2221  * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2222  * debug-pipe server is used.
2223  * 
2224  * @param fd1 return location for one end
2225  * @param fd2 return location for the other end
2226  * @param blocking #TRUE if pipe should be blocking
2227  * @param error error return
2228  * @returns #FALSE on failure (if error is set)
2229  */
2230 dbus_bool_t
2231 _dbus_full_duplex_pipe (int        *fd1,
2232                         int        *fd2,
2233                         dbus_bool_t blocking,
2234                         DBusError  *error)
2235 {
2236 #ifdef HAVE_SOCKETPAIR
2237   int fds[2];
2238
2239   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2240   
2241   if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2242     {
2243       dbus_set_error (error, _dbus_error_from_errno (errno),
2244                       "Could not create full-duplex pipe");
2245       return FALSE;
2246     }
2247
2248   if (!blocking &&
2249       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2250        !_dbus_set_fd_nonblocking (fds[1], NULL)))
2251     {
2252       dbus_set_error (error, _dbus_error_from_errno (errno),
2253                       "Could not set full-duplex pipe nonblocking");
2254       
2255       _dbus_close (fds[0], NULL);
2256       _dbus_close (fds[1], NULL);
2257       
2258       return FALSE;
2259     }
2260   
2261   *fd1 = fds[0];
2262   *fd2 = fds[1];
2263
2264   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2265                  *fd1, *fd2);
2266   
2267   return TRUE;  
2268 #else
2269   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2270   dbus_set_error (error, DBUS_ERROR_FAILED,
2271                   "_dbus_full_duplex_pipe() not implemented on this OS");
2272   return FALSE;
2273 #endif
2274 }
2275
2276
2277 /**
2278  * Measure the length of the given format string and arguments,
2279  * not including the terminating nul.
2280  *
2281  * @param format a printf-style format string
2282  * @param args arguments for the format string
2283  * @returns length of the given format string and args
2284  */
2285 int
2286 _dbus_printf_string_upper_bound (const char *format,
2287                                  va_list     args)
2288 {
2289   char c;
2290   return vsnprintf (&c, 1, format, args);
2291 }
2292
2293 /**
2294  * Gets the temporary files directory by inspecting the environment variables 
2295  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2296  *
2297  * @returns location of temp directory
2298  */
2299 const char*
2300 _dbus_get_tmpdir(void)
2301 {
2302   static const char* tmpdir = NULL;
2303
2304   if (tmpdir == NULL)
2305     {
2306       /* TMPDIR is what glibc uses, then
2307        * glibc falls back to the P_tmpdir macro which
2308        * just expands to "/tmp"
2309        */
2310       if (tmpdir == NULL)
2311         tmpdir = getenv("TMPDIR");
2312
2313       /* These two env variables are probably
2314        * broken, but maybe some OS uses them?
2315        */
2316       if (tmpdir == NULL)
2317         tmpdir = getenv("TMP");
2318       if (tmpdir == NULL)
2319         tmpdir = getenv("TEMP");
2320
2321       /* And this is the sane fallback. */
2322       if (tmpdir == NULL)
2323         tmpdir = "/tmp";
2324     }
2325   
2326   _dbus_assert(tmpdir != NULL);
2327   
2328   return tmpdir;
2329 }
2330
2331 /**
2332  * Determines the address of the session bus by querying a
2333  * platform-specific method.
2334  *
2335  * If successful, returns #TRUE and appends the address to @p
2336  * address. If a failure happens, returns #FALSE and
2337  * sets an error in @p error.
2338  *
2339  * @param address a DBusString where the address can be stored
2340  * @param error a DBusError to store the error in case of failure
2341  * @returns #TRUE on success, #FALSE if an error happened
2342  */
2343 dbus_bool_t
2344 _dbus_get_autolaunch_address (DBusString *address,
2345                               DBusError  *error)
2346 {
2347   static char *argv[5];
2348   int address_pipe[2];
2349   pid_t pid;
2350   int ret;
2351   int status;
2352   int orig_len;
2353   int i;
2354   DBusString uuid;
2355   dbus_bool_t retval;
2356   
2357   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2358   retval = FALSE;
2359
2360   _dbus_string_init (&uuid);
2361   
2362   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
2363     {
2364       _DBUS_SET_OOM (error);
2365       goto out;
2366     }
2367   
2368   i = 0;
2369   argv[i] = DBUS_BINDIR "/dbus-launch";
2370   ++i;
2371   argv[i] = "--autolaunch";
2372   ++i;
2373   argv[i] = /* const cast */ (char*) _dbus_string_get_const_data (&uuid);
2374   ++i;
2375   argv[i] = "--binary-syntax";
2376   ++i;
2377   argv[i] = NULL;
2378   ++i;
2379
2380   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
2381   
2382   orig_len = _dbus_string_get_length (address);
2383   
2384 #define READ_END        0
2385 #define WRITE_END       1
2386   if (pipe (address_pipe) < 0)
2387     {
2388       dbus_set_error (error, _dbus_error_from_errno (errno),
2389                       "Failed to create a pipe: %s",
2390                       _dbus_strerror (errno));
2391       _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
2392                      _dbus_strerror (errno));
2393       goto out;
2394     }
2395
2396   pid = fork ();
2397   if (pid < 0)
2398     {
2399       dbus_set_error (error, _dbus_error_from_errno (errno),
2400                       "Failed to fork(): %s",
2401                       _dbus_strerror (errno));
2402       _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
2403                      _dbus_strerror (errno));
2404       goto out;
2405     }
2406
2407   if (pid == 0)
2408     {
2409       /* child process */
2410       int fd = open ("/dev/null", O_RDWR);
2411       if (fd == -1)
2412         /* huh?! can't open /dev/null? */
2413         _exit (1);
2414
2415       /* set-up stdXXX */
2416       close (address_pipe[READ_END]);
2417       close (0);                /* close stdin */
2418       close (1);                /* close stdout */
2419       close (2);                /* close stderr */
2420
2421       if (dup2 (fd, 0) == -1)
2422         _exit (1);
2423       if (dup2 (address_pipe[WRITE_END], 1) == -1)
2424         _exit (1);
2425       if (dup2 (fd, 2) == -1)
2426         _exit (1);
2427
2428       close (fd);
2429       close (address_pipe[WRITE_END]);
2430
2431       execv (argv[0], argv);
2432
2433       /* failed, try searching PATH */
2434       argv[0] = "dbus-launch";
2435       execvp ("dbus-launch", argv);
2436
2437       /* still nothing, we failed */
2438       _exit (1);
2439     }
2440
2441   /* parent process */
2442   close (address_pipe[WRITE_END]);
2443   ret = 0;
2444   do 
2445     {
2446       ret = _dbus_read (address_pipe[READ_END], address, 1024);
2447     }
2448   while (ret > 0);
2449
2450   /* reap the child process to avoid it lingering as zombie */
2451   do
2452     {
2453       ret = waitpid (pid, &status, 0);
2454     }
2455   while (ret == -1 && errno == EINTR);
2456
2457   /* We succeeded if the process exited with status 0 and
2458      anything was read */
2459   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
2460       _dbus_string_get_length (address) == orig_len)
2461     {
2462       /* The process ended with error */
2463       _dbus_string_set_length (address, orig_len);
2464       dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
2465                       "Failed to execute dbus-launch to autolaunch D-Bus session");
2466       goto out;
2467     }
2468
2469   retval = TRUE;
2470   
2471  out:
2472   if (retval)
2473     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2474   else
2475     _DBUS_ASSERT_ERROR_IS_SET (error);
2476   
2477   _dbus_string_free (&uuid);
2478   return retval;
2479 }
2480
2481 /**
2482  * Reads the uuid of the machine we're running on from
2483  * the dbus configuration. Optionally try to create it
2484  * (only root can do this usually).
2485  *
2486  * On UNIX, reads a file that gets created by dbus-uuidgen
2487  * in a post-install script. On Windows, if there's a standard
2488  * machine uuid we could just use that, but I can't find one
2489  * with the right properties (the hardware profile guid can change
2490  * without rebooting I believe). If there's no standard one
2491  * we might want to use the registry instead of a file for
2492  * this, and I'm not sure how we'd ensure the uuid gets created.
2493  *
2494  * @param machine_id guid to init with the machine's uuid
2495  * @param create_if_not_found try to create the uuid if it doesn't exist
2496  * @param error the error return
2497  * @returns #FALSE if the error is set
2498  */
2499 dbus_bool_t
2500 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
2501                                dbus_bool_t create_if_not_found,
2502                                DBusError  *error)
2503 {
2504   DBusString filename;
2505   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
2506   return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
2507 }
2508
2509 /** @} end of sysdeps */
2510
2511 /* tests in dbus-sysdeps-util.c */