memset: replace memset() by _DBUS_ZERO where applicable
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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 <config.h>
26
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-transport.h"
33 #include "dbus-string.h"
34 #include "dbus-userdb.h"
35 #include "dbus-list.h"
36 #include "dbus-credentials.h"
37
38 #include <sys/types.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <signal.h>
42 #include <unistd.h>
43 #include <stdio.h>
44 #include <fcntl.h>
45 #include <sys/socket.h>
46 #include <dirent.h>
47 #include <sys/un.h>
48 #include <pwd.h>
49 #include <time.h>
50 #include <locale.h>
51 #include <sys/time.h>
52 #include <sys/stat.h>
53 #include <sys/wait.h>
54 #include <netinet/in.h>
55 #include <netdb.h>
56 #include <grp.h>
57
58 #ifdef HAVE_ERRNO_H
59 #include <errno.h>
60 #endif
61 #ifdef HAVE_WRITEV
62 #include <sys/uio.h>
63 #endif
64 #ifdef HAVE_POLL
65 #include <sys/poll.h>
66 #endif
67 #ifdef HAVE_BACKTRACE
68 #include <execinfo.h>
69 #endif
70 #ifdef HAVE_GETPEERUCRED
71 #include <ucred.h>
72 #endif
73
74 #ifdef HAVE_ADT
75 #include <bsm/adt.h>
76 #endif
77
78 #ifndef O_BINARY
79 #define O_BINARY 0
80 #endif
81
82 #ifndef AI_ADDRCONFIG
83 #define AI_ADDRCONFIG 0
84 #endif
85
86 #ifndef HAVE_SOCKLEN_T
87 #define socklen_t int
88 #endif
89
90 static dbus_bool_t
91 _dbus_open_socket (int              *fd_p,
92                    int               domain,
93                    int               type,
94                    int               protocol,
95                    DBusError        *error)
96 {
97 #ifdef SOCK_CLOEXEC
98   dbus_bool_t cloexec_done;
99
100   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
101   cloexec_done = *fd_p >= 0;
102
103   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
104   if (*fd_p < 0 && errno == EINVAL)
105 #endif
106     {
107       *fd_p = socket (domain, type, protocol);
108     }
109
110   if (*fd_p >= 0)
111     {
112 #ifdef SOCK_CLOEXEC
113       if (!cloexec_done)
114 #endif
115         {
116           _dbus_fd_set_close_on_exec(*fd_p);
117         }
118
119       _dbus_verbose ("socket fd %d opened\n", *fd_p);
120       return TRUE;
121     }
122   else
123     {
124       dbus_set_error(error,
125                      _dbus_error_from_errno (errno),
126                      "Failed to open socket: %s",
127                      _dbus_strerror (errno));
128       return FALSE;
129     }
130 }
131
132 dbus_bool_t
133 _dbus_open_tcp_socket (int              *fd,
134                        DBusError        *error)
135 {
136   return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
137 }
138
139 /**
140  * Opens a UNIX domain socket (as in the socket() call).
141  * Does not bind the socket.
142  *
143  * This will set FD_CLOEXEC for the socket returned
144  *
145  * @param fd return location for socket descriptor
146  * @param error return location for an error
147  * @returns #FALSE if error is set
148  */
149 dbus_bool_t
150 _dbus_open_unix_socket (int              *fd,
151                         DBusError        *error)
152 {
153   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
154 }
155
156 /**
157  * Closes a socket. Should not be used on non-socket
158  * file descriptors or handles.
159  *
160  * @param fd the socket
161  * @param error return location for an error
162  * @returns #FALSE if error is set
163  */
164 dbus_bool_t 
165 _dbus_close_socket (int               fd,
166                     DBusError        *error)
167 {
168   return _dbus_close (fd, error);
169 }
170
171 /**
172  * Like _dbus_read(), but only works on sockets so is
173  * available on Windows.
174  *
175  * @param fd the socket
176  * @param buffer string to append data to
177  * @param count max amount of data to read
178  * @returns number of bytes appended to the string
179  */
180 int
181 _dbus_read_socket (int               fd,
182                    DBusString       *buffer,
183                    int               count)
184 {
185   return _dbus_read (fd, buffer, count);
186 }
187
188 /**
189  * Like _dbus_write(), but only supports sockets
190  * and is thus available on Windows.
191  *
192  * @param fd the file descriptor to write
193  * @param buffer the buffer to write data from
194  * @param start the first byte in the buffer to write
195  * @param len the number of bytes to try to write
196  * @returns the number of bytes written or -1 on error
197  */
198 int
199 _dbus_write_socket (int               fd,
200                     const DBusString *buffer,
201                     int               start,
202                     int               len)
203 {
204 #ifdef MSG_NOSIGNAL
205   const char *data;
206   int bytes_written;
207
208   data = _dbus_string_get_const_data_len (buffer, start, len);
209
210  again:
211
212   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
213
214   if (bytes_written < 0 && errno == EINTR)
215     goto again;
216
217   return bytes_written;
218
219 #else
220   return _dbus_write (fd, buffer, start, len);
221 #endif
222 }
223
224 /**
225  * Like _dbus_read_socket() but also tries to read unix fds from the
226  * socket. When there are more fds to read than space in the array
227  * passed this function will fail with ENOSPC.
228  *
229  * @param fd the socket
230  * @param buffer string to append data to
231  * @param count max amount of data to read
232  * @param fds array to place read file descriptors in
233  * @param n_fds on input space in fds array, on output how many fds actually got read
234  * @returns number of bytes appended to string
235  */
236 int
237 _dbus_read_socket_with_unix_fds (int               fd,
238                                  DBusString       *buffer,
239                                  int               count,
240                                  int              *fds,
241                                  int              *n_fds) {
242 #ifndef HAVE_UNIX_FD_PASSING
243   int r;
244
245   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
246     return r;
247
248   *n_fds = 0;
249   return r;
250
251 #else
252   int bytes_read;
253   int start;
254   struct msghdr m;
255   struct iovec iov;
256
257   _dbus_assert (count >= 0);
258   _dbus_assert (*n_fds >= 0);
259
260   start = _dbus_string_get_length (buffer);
261
262   if (!_dbus_string_lengthen (buffer, count))
263     {
264       errno = ENOMEM;
265       return -1;
266     }
267
268   _DBUS_ZERO(iov);
269   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
270   iov.iov_len = count;
271
272   _DBUS_ZERO(m);
273   m.msg_iov = &iov;
274   m.msg_iovlen = 1;
275
276   /* Hmm, we have no clue how long the control data will actually be
277      that is queued for us. The least we can do is assume that the
278      caller knows. Hence let's make space for the number of fds that
279      we shall read at max plus the cmsg header. */
280   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
281
282   /* It's probably safe to assume that systems with SCM_RIGHTS also
283      know alloca() */
284   m.msg_control = alloca(m.msg_controllen);
285   memset(m.msg_control, 0, m.msg_controllen);
286
287  again:
288
289   bytes_read = recvmsg(fd, &m, 0
290 #ifdef MSG_CMSG_CLOEXEC
291                        |MSG_CMSG_CLOEXEC
292 #endif
293                        );
294
295   if (bytes_read < 0)
296     {
297       if (errno == EINTR)
298         goto again;
299       else
300         {
301           /* put length back (note that this doesn't actually realloc anything) */
302           _dbus_string_set_length (buffer, start);
303           return -1;
304         }
305     }
306   else
307     {
308       struct cmsghdr *cm;
309       dbus_bool_t found = FALSE;
310
311       if (m.msg_flags & MSG_CTRUNC)
312         {
313           /* Hmm, apparently the control data was truncated. The bad
314              thing is that we might have completely lost a couple of fds
315              without chance to recover them. Hence let's treat this as a
316              serious error. */
317
318           errno = ENOSPC;
319           _dbus_string_set_length (buffer, start);
320           return -1;
321         }
322
323       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
324         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
325           {
326             unsigned i;
327
328             _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
329             *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
330
331             memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
332             found = TRUE;
333
334             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
335                worked, hence we need to go through this list and set
336                CLOEXEC everywhere in any case */
337             for (i = 0; i < *n_fds; i++)
338               _dbus_fd_set_close_on_exec(fds[i]);
339
340             break;
341           }
342
343       if (!found)
344         *n_fds = 0;
345
346       /* put length back (doesn't actually realloc) */
347       _dbus_string_set_length (buffer, start + bytes_read);
348
349 #if 0
350       if (bytes_read > 0)
351         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
352 #endif
353
354       return bytes_read;
355     }
356 #endif
357 }
358
359 int
360 _dbus_write_socket_with_unix_fds(int               fd,
361                                  const DBusString *buffer,
362                                  int               start,
363                                  int               len,
364                                  const int        *fds,
365                                  int               n_fds) {
366
367 #ifndef HAVE_UNIX_FD_PASSING
368
369   if (n_fds > 0) {
370     errno = ENOTSUP;
371     return -1;
372   }
373
374   return _dbus_write_socket(fd, buffer, start, len);
375 #else
376   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
377 #endif
378 }
379
380 int
381 _dbus_write_socket_with_unix_fds_two(int               fd,
382                                      const DBusString *buffer1,
383                                      int               start1,
384                                      int               len1,
385                                      const DBusString *buffer2,
386                                      int               start2,
387                                      int               len2,
388                                      const int        *fds,
389                                      int               n_fds) {
390
391 #ifndef HAVE_UNIX_FD_PASSING
392
393   if (n_fds > 0) {
394     errno = ENOTSUP;
395     return -1;
396   }
397
398   return _dbus_write_socket_two(fd,
399                                 buffer1, start1, len1,
400                                 buffer2, start2, len2);
401 #else
402
403   struct msghdr m;
404   struct cmsghdr *cm;
405   struct iovec iov[2];
406   int bytes_written;
407
408   _dbus_assert (len1 >= 0);
409   _dbus_assert (len2 >= 0);
410   _dbus_assert (n_fds >= 0);
411
412   _DBUS_ZERO(iov);
413   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
414   iov[0].iov_len = len1;
415
416   if (buffer2)
417     {
418       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
419       iov[1].iov_len = len2;
420     }
421
422   _DBUS_ZERO(m);
423   m.msg_iov = iov;
424   m.msg_iovlen = buffer2 ? 2 : 1;
425
426   if (n_fds > 0)
427     {
428       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
429       m.msg_control = alloca(m.msg_controllen);
430       memset(m.msg_control, 0, m.msg_controllen);
431
432       cm = CMSG_FIRSTHDR(&m);
433       cm->cmsg_level = SOL_SOCKET;
434       cm->cmsg_type = SCM_RIGHTS;
435       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
436       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
437     }
438
439  again:
440
441   bytes_written = sendmsg (fd, &m, 0
442 #ifdef MSG_NOSIGNAL
443                            |MSG_NOSIGNAL
444 #endif
445                            );
446
447   if (bytes_written < 0 && errno == EINTR)
448     goto again;
449
450 #if 0
451   if (bytes_written > 0)
452     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
453 #endif
454
455   return bytes_written;
456 #endif
457 }
458
459 /**
460  * write data to a pipe.
461  *
462  * @param pipe the pipe instance
463  * @param buffer the buffer to write data from
464  * @param start the first byte in the buffer to write
465  * @param len the number of bytes to try to write
466  * @param error error return
467  * @returns the number of bytes written or -1 on error
468  */
469 int
470 _dbus_pipe_write (DBusPipe         *pipe,
471                   const DBusString *buffer,
472                   int               start,
473                   int               len,
474                   DBusError        *error)
475 {
476   int written;
477   
478   written = _dbus_write (pipe->fd_or_handle, buffer, start, len);
479   if (written < 0)
480     {
481       dbus_set_error (error, DBUS_ERROR_FAILED,
482                       "Writing to pipe: %s\n",
483                       _dbus_strerror (errno));
484     }
485   return written;
486 }
487
488 /**
489  * close a pipe.
490  *
491  * @param pipe the pipe instance
492  * @param error return location for an error
493  * @returns #FALSE if error is set
494  */
495 int
496 _dbus_pipe_close  (DBusPipe         *pipe,
497                    DBusError        *error)
498 {
499   if (_dbus_close (pipe->fd_or_handle, error) < 0)
500     {
501       return -1;
502     }
503   else
504     {
505       _dbus_pipe_invalidate (pipe);
506       return 0;
507     }
508 }
509
510 /**
511  * Like _dbus_write_two() but only works on sockets and is thus
512  * available on Windows.
513  * 
514  * @param fd the file descriptor
515  * @param buffer1 first buffer
516  * @param start1 first byte to write in first buffer
517  * @param len1 number of bytes to write from first buffer
518  * @param buffer2 second buffer, or #NULL
519  * @param start2 first byte to write in second buffer
520  * @param len2 number of bytes to write in second buffer
521  * @returns total bytes written from both buffers, or -1 on error
522  */
523 int
524 _dbus_write_socket_two (int               fd,
525                         const DBusString *buffer1,
526                         int               start1,
527                         int               len1,
528                         const DBusString *buffer2,
529                         int               start2,
530                         int               len2)
531 {
532 #ifdef MSG_NOSIGNAL
533   struct iovec vectors[2];
534   const char *data1;
535   const char *data2;
536   int bytes_written;
537   struct msghdr m;
538
539   _dbus_assert (buffer1 != NULL);
540   _dbus_assert (start1 >= 0);
541   _dbus_assert (start2 >= 0);
542   _dbus_assert (len1 >= 0);
543   _dbus_assert (len2 >= 0);
544
545   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
546
547   if (buffer2 != NULL)
548     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
549   else
550     {
551       data2 = NULL;
552       start2 = 0;
553       len2 = 0;
554     }
555
556   vectors[0].iov_base = (char*) data1;
557   vectors[0].iov_len = len1;
558   vectors[1].iov_base = (char*) data2;
559   vectors[1].iov_len = len2;
560
561   _DBUS_ZERO(m);
562   m.msg_iov = vectors;
563   m.msg_iovlen = data2 ? 2 : 1;
564
565  again:
566
567   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
568
569   if (bytes_written < 0 && errno == EINTR)
570     goto again;
571
572   return bytes_written;
573
574 #else
575   return _dbus_write_two (fd, buffer1, start1, len1,
576                           buffer2, start2, len2);
577 #endif
578 }
579
580
581 /**
582  * Thin wrapper around the read() system call that appends
583  * the data it reads to the DBusString buffer. It appends
584  * up to the given count, and returns the same value
585  * and same errno as read(). The only exception is that
586  * _dbus_read() handles EINTR for you. Also, _dbus_read() can
587  * return ENOMEM, even though regular UNIX read doesn't.
588  *
589  * Unlike _dbus_read_socket(), _dbus_read() is not available
590  * on Windows.
591  * 
592  * @param fd the file descriptor to read from
593  * @param buffer the buffer to append data to
594  * @param count the amount of data to read
595  * @returns the number of bytes read or -1
596  */
597 int
598 _dbus_read (int               fd,
599             DBusString       *buffer,
600             int               count)
601 {
602   int bytes_read;
603   int start;
604   char *data;
605
606   _dbus_assert (count >= 0);
607   
608   start = _dbus_string_get_length (buffer);
609
610   if (!_dbus_string_lengthen (buffer, count))
611     {
612       errno = ENOMEM;
613       return -1;
614     }
615
616   data = _dbus_string_get_data_len (buffer, start, count);
617
618  again:
619   
620   bytes_read = read (fd, data, count);
621
622   if (bytes_read < 0)
623     {
624       if (errno == EINTR)
625         goto again;
626       else
627         {
628           /* put length back (note that this doesn't actually realloc anything) */
629           _dbus_string_set_length (buffer, start);
630           return -1;
631         }
632     }
633   else
634     {
635       /* put length back (doesn't actually realloc) */
636       _dbus_string_set_length (buffer, start + bytes_read);
637
638 #if 0
639       if (bytes_read > 0)
640         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
641 #endif
642       
643       return bytes_read;
644     }
645 }
646
647 /**
648  * Thin wrapper around the write() system call that writes a part of a
649  * DBusString and handles EINTR for you.
650  * 
651  * @param fd the file descriptor to write
652  * @param buffer the buffer to write data from
653  * @param start the first byte in the buffer to write
654  * @param len the number of bytes to try to write
655  * @returns the number of bytes written or -1 on error
656  */
657 int
658 _dbus_write (int               fd,
659              const DBusString *buffer,
660              int               start,
661              int               len)
662 {
663   const char *data;
664   int bytes_written;
665   
666   data = _dbus_string_get_const_data_len (buffer, start, len);
667   
668  again:
669
670   bytes_written = write (fd, data, len);
671
672   if (bytes_written < 0 && errno == EINTR)
673     goto again;
674
675 #if 0
676   if (bytes_written > 0)
677     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
678 #endif
679   
680   return bytes_written;
681 }
682
683 /**
684  * Like _dbus_write() but will use writev() if possible
685  * to write both buffers in sequence. The return value
686  * is the number of bytes written in the first buffer,
687  * plus the number written in the second. If the first
688  * buffer is written successfully and an error occurs
689  * writing the second, the number of bytes in the first
690  * is returned (i.e. the error is ignored), on systems that
691  * don't have writev. Handles EINTR for you.
692  * The second buffer may be #NULL.
693  *
694  * @param fd the file descriptor
695  * @param buffer1 first buffer
696  * @param start1 first byte to write in first buffer
697  * @param len1 number of bytes to write from first buffer
698  * @param buffer2 second buffer, or #NULL
699  * @param start2 first byte to write in second buffer
700  * @param len2 number of bytes to write in second buffer
701  * @returns total bytes written from both buffers, or -1 on error
702  */
703 int
704 _dbus_write_two (int               fd,
705                  const DBusString *buffer1,
706                  int               start1,
707                  int               len1,
708                  const DBusString *buffer2,
709                  int               start2,
710                  int               len2)
711 {
712   _dbus_assert (buffer1 != NULL);
713   _dbus_assert (start1 >= 0);
714   _dbus_assert (start2 >= 0);
715   _dbus_assert (len1 >= 0);
716   _dbus_assert (len2 >= 0);
717   
718 #ifdef HAVE_WRITEV
719   {
720     struct iovec vectors[2];
721     const char *data1;
722     const char *data2;
723     int bytes_written;
724
725     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
726
727     if (buffer2 != NULL)
728       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
729     else
730       {
731         data2 = NULL;
732         start2 = 0;
733         len2 = 0;
734       }
735    
736     vectors[0].iov_base = (char*) data1;
737     vectors[0].iov_len = len1;
738     vectors[1].iov_base = (char*) data2;
739     vectors[1].iov_len = len2;
740
741   again:
742    
743     bytes_written = writev (fd,
744                             vectors,
745                             data2 ? 2 : 1);
746
747     if (bytes_written < 0 && errno == EINTR)
748       goto again;
749    
750     return bytes_written;
751   }
752 #else /* HAVE_WRITEV */
753   {
754     int ret1;
755     
756     ret1 = _dbus_write (fd, buffer1, start1, len1);
757     if (ret1 == len1 && buffer2 != NULL)
758       {
759         ret2 = _dbus_write (fd, buffer2, start2, len2);
760         if (ret2 < 0)
761           ret2 = 0; /* we can't report an error as the first write was OK */
762        
763         return ret1 + ret2;
764       }
765     else
766       return ret1;
767   }
768 #endif /* !HAVE_WRITEV */   
769 }
770
771 #define _DBUS_MAX_SUN_PATH_LENGTH 99
772
773 /**
774  * @def _DBUS_MAX_SUN_PATH_LENGTH
775  *
776  * Maximum length of the path to a UNIX domain socket,
777  * sockaddr_un::sun_path member. POSIX requires that all systems
778  * support at least 100 bytes here, including the nul termination.
779  * We use 99 for the max value to allow for the nul.
780  *
781  * We could probably also do sizeof (addr.sun_path)
782  * but this way we are the same on all platforms
783  * which is probably a good idea.
784  */
785
786 /**
787  * Creates a socket and connects it to the UNIX domain socket at the
788  * given path.  The connection fd is returned, and is set up as
789  * nonblocking.
790  * 
791  * Uses abstract sockets instead of filesystem-linked sockets if
792  * requested (it's possible only on Linux; see "man 7 unix" on Linux).
793  * On non-Linux abstract socket usage always fails.
794  *
795  * This will set FD_CLOEXEC for the socket returned.
796  *
797  * @param path the path to UNIX domain socket
798  * @param abstract #TRUE to use abstract namespace
799  * @param error return location for error code
800  * @returns connection file descriptor or -1 on error
801  */
802 int
803 _dbus_connect_unix_socket (const char     *path,
804                            dbus_bool_t     abstract,
805                            DBusError      *error)
806 {
807   int fd;
808   size_t path_len;
809   struct sockaddr_un addr;  
810
811   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
812
813   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
814                  path, abstract);
815   
816   
817   if (!_dbus_open_unix_socket (&fd, error))
818     {
819       _DBUS_ASSERT_ERROR_IS_SET(error);
820       return -1;
821     }
822   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
823
824   _DBUS_ZERO (addr);
825   addr.sun_family = AF_UNIX;
826   path_len = strlen (path);
827
828   if (abstract)
829     {
830 #ifdef HAVE_ABSTRACT_SOCKETS
831       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
832       path_len++; /* Account for the extra nul byte added to the start of sun_path */
833
834       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
835         {
836           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
837                       "Abstract socket name too long\n");
838           _dbus_close (fd, NULL);
839           return -1;
840         }
841         
842       strncpy (&addr.sun_path[1], path, path_len);
843       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
844 #else /* HAVE_ABSTRACT_SOCKETS */
845       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
846                       "Operating system does not support abstract socket namespace\n");
847       _dbus_close (fd, NULL);
848       return -1;
849 #endif /* ! HAVE_ABSTRACT_SOCKETS */
850     }
851   else
852     {
853       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
854         {
855           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
856                       "Socket name too long\n");
857           _dbus_close (fd, NULL);
858           return -1;
859         }
860
861       strncpy (addr.sun_path, path, path_len);
862     }
863   
864   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
865     {      
866       dbus_set_error (error,
867                       _dbus_error_from_errno (errno),
868                       "Failed to connect to socket %s: %s",
869                       path, _dbus_strerror (errno));
870
871       _dbus_close (fd, NULL);
872       fd = -1;
873       
874       return -1;
875     }
876
877   if (!_dbus_set_fd_nonblocking (fd, error))
878     {
879       _DBUS_ASSERT_ERROR_IS_SET (error);
880       
881       _dbus_close (fd, NULL);
882       fd = -1;
883
884       return -1;
885     }
886
887   return fd;
888 }
889
890 /**
891  * Enables or disables the reception of credentials on the given socket during
892  * the next message transmission.  This is only effective if the #LOCAL_CREDS
893  * system feature exists, in which case the other side of the connection does
894  * not have to do anything special to send the credentials.
895  *
896  * @param fd socket on which to change the #LOCAL_CREDS flag.
897  * @param on whether to enable or disable the #LOCAL_CREDS flag.
898  */
899 static dbus_bool_t
900 _dbus_set_local_creds (int fd, dbus_bool_t on)
901 {
902   dbus_bool_t retval = TRUE;
903
904 #if defined(HAVE_CMSGCRED)
905   /* NOOP just to make sure only one codepath is used 
906    *      and to prefer CMSGCRED
907    */
908 #elif defined(LOCAL_CREDS) 
909   int val = on ? 1 : 0;
910   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
911     {
912       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
913       retval = FALSE;
914     }
915   else
916     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
917                    on ? "enabled" : "disabled", fd);
918 #endif
919
920   return retval;
921 }
922
923 /**
924  * Creates a socket and binds it to the given path,
925  * then listens on the socket. The socket is
926  * set to be nonblocking.
927  *
928  * Uses abstract sockets instead of filesystem-linked
929  * sockets if requested (it's possible only on Linux;
930  * see "man 7 unix" on Linux).
931  * On non-Linux abstract socket usage always fails.
932  *
933  * This will set FD_CLOEXEC for the socket returned
934  *
935  * @param path the socket name
936  * @param abstract #TRUE to use abstract namespace
937  * @param error return location for errors
938  * @returns the listening file descriptor or -1 on error
939  */
940 int
941 _dbus_listen_unix_socket (const char     *path,
942                           dbus_bool_t     abstract,
943                           DBusError      *error)
944 {
945   int listen_fd;
946   struct sockaddr_un addr;
947   size_t path_len;
948
949   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
950
951   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
952                  path, abstract);
953   
954   if (!_dbus_open_unix_socket (&listen_fd, error))
955     {
956       _DBUS_ASSERT_ERROR_IS_SET(error);
957       return -1;
958     }
959   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
960
961   _DBUS_ZERO (addr);
962   addr.sun_family = AF_UNIX;
963   path_len = strlen (path);
964   
965   if (abstract)
966     {
967 #ifdef HAVE_ABSTRACT_SOCKETS
968       /* remember that abstract names aren't nul-terminated so we rely
969        * on sun_path being filled in with zeroes above.
970        */
971       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
972       path_len++; /* Account for the extra nul byte added to the start of sun_path */
973
974       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
975         {
976           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
977                       "Abstract socket name too long\n");
978           _dbus_close (listen_fd, NULL);
979           return -1;
980         }
981       
982       strncpy (&addr.sun_path[1], path, path_len);
983       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
984 #else /* HAVE_ABSTRACT_SOCKETS */
985       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
986                       "Operating system does not support abstract socket namespace\n");
987       _dbus_close (listen_fd, NULL);
988       return -1;
989 #endif /* ! HAVE_ABSTRACT_SOCKETS */
990     }
991   else
992     {
993       /* Discussed security implications of this with Nalin,
994        * and we couldn't think of where it would kick our ass, but
995        * it still seems a bit sucky. It also has non-security suckage;
996        * really we'd prefer to exit if the socket is already in use.
997        * But there doesn't seem to be a good way to do this.
998        *
999        * Just to be extra careful, I threw in the stat() - clearly
1000        * the stat() can't *fix* any security issue, but it at least
1001        * avoids inadvertent/accidental data loss.
1002        */
1003       {
1004         struct stat sb;
1005
1006         if (stat (path, &sb) == 0 &&
1007             S_ISSOCK (sb.st_mode))
1008           unlink (path);
1009       }
1010
1011       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1012         {
1013           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1014                       "Abstract socket name too long\n");
1015           _dbus_close (listen_fd, NULL);
1016           return -1;
1017         }
1018         
1019       strncpy (addr.sun_path, path, path_len);
1020     }
1021   
1022   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1023     {
1024       dbus_set_error (error, _dbus_error_from_errno (errno),
1025                       "Failed to bind socket \"%s\": %s",
1026                       path, _dbus_strerror (errno));
1027       _dbus_close (listen_fd, NULL);
1028       return -1;
1029     }
1030
1031   if (listen (listen_fd, 30 /* backlog */) < 0)
1032     {
1033       dbus_set_error (error, _dbus_error_from_errno (errno),
1034                       "Failed to listen on socket \"%s\": %s",
1035                       path, _dbus_strerror (errno));
1036       _dbus_close (listen_fd, NULL);
1037       return -1;
1038     }
1039
1040   if (!_dbus_set_local_creds (listen_fd, TRUE))
1041     {
1042       dbus_set_error (error, _dbus_error_from_errno (errno),
1043                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1044                       path, _dbus_strerror (errno));
1045       close (listen_fd);
1046       return -1;
1047     }
1048
1049   if (!_dbus_set_fd_nonblocking (listen_fd, error))
1050     {
1051       _DBUS_ASSERT_ERROR_IS_SET (error);
1052       _dbus_close (listen_fd, NULL);
1053       return -1;
1054     }
1055   
1056   /* Try opening up the permissions, but if we can't, just go ahead
1057    * and continue, maybe it will be good enough.
1058    */
1059   if (!abstract && chmod (path, 0777) < 0)
1060     _dbus_warn ("Could not set mode 0777 on socket %s\n",
1061                 path);
1062   
1063   return listen_fd;
1064 }
1065
1066 /**
1067  * Creates a socket and connects to a socket at the given host 
1068  * and port. The connection fd is returned, and is set up as
1069  * nonblocking.
1070  *
1071  * This will set FD_CLOEXEC for the socket returned
1072  *
1073  * @param host the host name to connect to
1074  * @param port the port to connect to
1075  * @param family the address family to listen on, NULL for all
1076  * @param error return location for error code
1077  * @returns connection file descriptor or -1 on error
1078  */
1079 int
1080 _dbus_connect_tcp_socket (const char     *host,
1081                           const char     *port,
1082                           const char     *family,
1083                           DBusError      *error)
1084 {
1085   int saved_errno = 0;
1086   int fd = -1, res;
1087   struct addrinfo hints;
1088   struct addrinfo *ai, *tmp;
1089
1090   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1091
1092   if (!_dbus_open_tcp_socket (&fd, error))
1093     {
1094       _DBUS_ASSERT_ERROR_IS_SET(error);
1095       return -1;
1096     }
1097
1098   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1099
1100   _DBUS_ZERO (hints);
1101
1102   if (!family)
1103     hints.ai_family = AF_UNSPEC;
1104   else if (!strcmp(family, "ipv4"))
1105     hints.ai_family = AF_INET;
1106   else if (!strcmp(family, "ipv6"))
1107     hints.ai_family = AF_INET6;
1108   else
1109     {
1110       dbus_set_error (error,
1111                       DBUS_ERROR_BAD_ADDRESS,
1112                       "Unknown address family %s", family);
1113       return -1;
1114     }
1115   hints.ai_protocol = IPPROTO_TCP;
1116   hints.ai_socktype = SOCK_STREAM;
1117   hints.ai_flags = AI_ADDRCONFIG;
1118
1119   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1120     {
1121       dbus_set_error (error,
1122                       _dbus_error_from_errno (errno),
1123                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1124                       host, port, gai_strerror(res), res);
1125       _dbus_close (fd, NULL);
1126       return -1;
1127     }
1128
1129   tmp = ai;
1130   while (tmp)
1131     {
1132       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1133         {
1134           freeaddrinfo(ai);
1135           _DBUS_ASSERT_ERROR_IS_SET(error);
1136           return -1;
1137         }
1138       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1139
1140       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1141         {
1142           saved_errno = errno;
1143           _dbus_close(fd, NULL);
1144           fd = -1;
1145           tmp = tmp->ai_next;
1146           continue;
1147         }
1148
1149       break;
1150     }
1151   freeaddrinfo(ai);
1152
1153   if (fd == -1)
1154     {
1155       dbus_set_error (error,
1156                       _dbus_error_from_errno (saved_errno),
1157                       "Failed to connect to socket \"%s:%s\" %s",
1158                       host, port, _dbus_strerror(saved_errno));
1159       return -1;
1160     }
1161
1162
1163   if (!_dbus_set_fd_nonblocking (fd, error))
1164     {
1165       _dbus_close (fd, NULL);
1166       fd = -1;
1167
1168       return -1;
1169     }
1170
1171   return fd;
1172 }
1173
1174 /**
1175  * Creates a socket and binds it to the given path, then listens on
1176  * the socket. The socket is set to be nonblocking.  In case of port=0
1177  * a random free port is used and returned in the port parameter.
1178  * If inaddr_any is specified, the hostname is ignored.
1179  *
1180  * This will set FD_CLOEXEC for the socket returned
1181  *
1182  * @param host the host name to listen on
1183  * @param port the port to listen on, if zero a free port will be used
1184  * @param family the address family to listen on, NULL for all
1185  * @param retport string to return the actual port listened on
1186  * @param fds_p location to store returned file descriptors
1187  * @param error return location for errors
1188  * @returns the number of listening file descriptors or -1 on error
1189  */
1190 int
1191 _dbus_listen_tcp_socket (const char     *host,
1192                          const char     *port,
1193                          const char     *family,
1194                          DBusString     *retport,
1195                          int           **fds_p,
1196                          DBusError      *error)
1197 {
1198   int saved_errno;
1199   int nlisten_fd = 0, *listen_fd = NULL, res, i;
1200   struct addrinfo hints;
1201   struct addrinfo *ai, *tmp;
1202
1203   *fds_p = NULL;
1204   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1205
1206   _DBUS_ZERO (hints);
1207
1208   if (!family)
1209     hints.ai_family = AF_UNSPEC;
1210   else if (!strcmp(family, "ipv4"))
1211     hints.ai_family = AF_INET;
1212   else if (!strcmp(family, "ipv6"))
1213     hints.ai_family = AF_INET6;
1214   else
1215     {
1216       dbus_set_error (error,
1217                       DBUS_ERROR_BAD_ADDRESS,
1218                       "Unknown address family %s", family);
1219       return -1;
1220     }
1221
1222   hints.ai_protocol = IPPROTO_TCP;
1223   hints.ai_socktype = SOCK_STREAM;
1224   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1225
1226  redo_lookup_with_port:
1227   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1228     {
1229       dbus_set_error (error,
1230                       _dbus_error_from_errno (errno),
1231                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1232                       host ? host : "*", port, gai_strerror(res), res);
1233       return -1;
1234     }
1235
1236   tmp = ai;
1237   while (tmp)
1238     {
1239       int fd = -1, *newlisten_fd;
1240       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1241         {
1242           _DBUS_ASSERT_ERROR_IS_SET(error);
1243           goto failed;
1244         }
1245       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1246
1247       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1248         {
1249           saved_errno = errno;
1250           _dbus_close(fd, NULL);
1251           if (saved_errno == EADDRINUSE)
1252             {
1253               /* Depending on kernel policy, it may or may not
1254                  be neccessary to bind to both IPv4 & 6 addresses
1255                  so ignore EADDRINUSE here */
1256               tmp = tmp->ai_next;
1257               continue;
1258             }
1259           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1260                           "Failed to bind socket \"%s:%s\": %s",
1261                           host ? host : "*", port, _dbus_strerror (saved_errno));
1262           goto failed;
1263         }
1264
1265       if (listen (fd, 30 /* backlog */) < 0)
1266         {
1267           saved_errno = errno;
1268           _dbus_close (fd, NULL);
1269           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1270                           "Failed to listen on socket \"%s:%s\": %s",
1271                           host ? host : "*", port, _dbus_strerror (saved_errno));
1272           goto failed;
1273         }
1274
1275       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1276       if (!newlisten_fd)
1277         {
1278           saved_errno = errno;
1279           _dbus_close (fd, NULL);
1280           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1281                           "Failed to allocate file handle array: %s",
1282                           _dbus_strerror (saved_errno));
1283           goto failed;
1284         }
1285       listen_fd = newlisten_fd;
1286       listen_fd[nlisten_fd] = fd;
1287       nlisten_fd++;
1288
1289       if (!_dbus_string_get_length(retport))
1290         {
1291           /* If the user didn't specify a port, or used 0, then
1292              the kernel chooses a port. After the first address
1293              is bound to, we need to force all remaining addresses
1294              to use the same port */
1295           if (!port || !strcmp(port, "0"))
1296             {
1297               struct sockaddr_storage addr;
1298               socklen_t addrlen;
1299               char portbuf[50];
1300
1301               addrlen = sizeof(addr);
1302               getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1303
1304               if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
1305                                      portbuf, sizeof(portbuf),
1306                                      NI_NUMERICHOST)) != 0)
1307                 {
1308                   dbus_set_error (error, _dbus_error_from_errno (errno),
1309                                   "Failed to resolve port \"%s:%s\": %s (%s)",
1310                                   host ? host : "*", port, gai_strerror(res), res);
1311                   goto failed;
1312                 }
1313               if (!_dbus_string_append(retport, portbuf))
1314                 {
1315                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1316                   goto failed;
1317                 }
1318
1319               /* Release current address list & redo lookup */
1320               port = _dbus_string_get_const_data(retport);
1321               freeaddrinfo(ai);
1322               goto redo_lookup_with_port;
1323             }
1324           else
1325             {
1326               if (!_dbus_string_append(retport, port))
1327                 {
1328                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1329                     goto failed;
1330                 }
1331             }
1332         }
1333
1334       tmp = tmp->ai_next;
1335     }
1336   freeaddrinfo(ai);
1337   ai = NULL;
1338
1339   if (!nlisten_fd)
1340     {
1341       errno = EADDRINUSE;
1342       dbus_set_error (error, _dbus_error_from_errno (errno),
1343                       "Failed to bind socket \"%s:%s\": %s",
1344                       host ? host : "*", port, _dbus_strerror (errno));
1345       return -1;
1346     }
1347
1348   for (i = 0 ; i < nlisten_fd ; i++)
1349     {
1350       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1351         {
1352           goto failed;
1353         }
1354     }
1355
1356   *fds_p = listen_fd;
1357
1358   return nlisten_fd;
1359
1360  failed:
1361   if (ai)
1362     freeaddrinfo(ai);
1363   for (i = 0 ; i < nlisten_fd ; i++)
1364     _dbus_close(listen_fd[i], NULL);
1365   dbus_free(listen_fd);
1366   return -1;
1367 }
1368
1369 static dbus_bool_t
1370 write_credentials_byte (int             server_fd,
1371                         DBusError      *error)
1372 {
1373   int bytes_written;
1374   char buf[1] = { '\0' };
1375 #if defined(HAVE_CMSGCRED) 
1376   struct {
1377           struct cmsghdr hdr;
1378           struct cmsgcred cred;
1379   } cmsg;
1380   struct iovec iov;
1381   struct msghdr msg;
1382   iov.iov_base = buf;
1383   iov.iov_len = 1;
1384
1385   _DBUS_ZERO(msg);
1386   msg.msg_iov = &iov;
1387   msg.msg_iovlen = 1;
1388
1389   msg.msg_control = &cmsg;
1390   msg.msg_controllen = sizeof (cmsg);
1391   _DBUS_ZERO(cmsg);
1392   cmsg.hdr.cmsg_len = sizeof (cmsg);
1393   cmsg.hdr.cmsg_level = SOL_SOCKET;
1394   cmsg.hdr.cmsg_type = SCM_CREDS;
1395 #endif
1396
1397   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1398   
1399  again:
1400
1401 #if defined(HAVE_CMSGCRED) 
1402   bytes_written = sendmsg (server_fd, &msg, 0);
1403 #else
1404   bytes_written = write (server_fd, buf, 1);
1405 #endif
1406
1407   if (bytes_written < 0 && errno == EINTR)
1408     goto again;
1409
1410   if (bytes_written < 0)
1411     {
1412       dbus_set_error (error, _dbus_error_from_errno (errno),
1413                       "Failed to write credentials byte: %s",
1414                      _dbus_strerror (errno));
1415       return FALSE;
1416     }
1417   else if (bytes_written == 0)
1418     {
1419       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1420                       "wrote zero bytes writing credentials byte");
1421       return FALSE;
1422     }
1423   else
1424     {
1425       _dbus_assert (bytes_written == 1);
1426       _dbus_verbose ("wrote credentials byte\n");
1427       return TRUE;
1428     }
1429 }
1430
1431 /**
1432  * Reads a single byte which must be nul (an error occurs otherwise),
1433  * and reads unix credentials if available. Clears the credentials
1434  * object, then adds pid/uid if available, so any previous credentials
1435  * stored in the object are lost.
1436  *
1437  * Return value indicates whether a byte was read, not whether
1438  * we got valid credentials. On some systems, such as Linux,
1439  * reading/writing the byte isn't actually required, but we do it
1440  * anyway just to avoid multiple codepaths.
1441  * 
1442  * Fails if no byte is available, so you must select() first.
1443  *
1444  * The point of the byte is that on some systems we have to
1445  * use sendmsg()/recvmsg() to transmit credentials.
1446  *
1447  * @param client_fd the client file descriptor
1448  * @param credentials object to add client credentials to
1449  * @param error location to store error code
1450  * @returns #TRUE on success
1451  */
1452 dbus_bool_t
1453 _dbus_read_credentials_socket  (int              client_fd,
1454                                 DBusCredentials *credentials,
1455                                 DBusError       *error)
1456 {
1457   struct msghdr msg;
1458   struct iovec iov;
1459   char buf;
1460   dbus_uid_t uid_read;
1461   dbus_pid_t pid_read;
1462   int bytes_read;
1463   
1464   uid_read = DBUS_UID_UNSET;
1465   pid_read = DBUS_PID_UNSET;
1466   
1467 #ifdef HAVE_CMSGCRED 
1468   struct {
1469     struct cmsghdr hdr;
1470     struct cmsgcred cred;
1471   } cmsg;
1472
1473 #elif defined(LOCAL_CREDS)
1474   struct {
1475     struct cmsghdr hdr;
1476     struct sockcred cred;
1477   } cmsg;
1478 #endif
1479
1480   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1481   
1482   /* The POSIX spec certainly doesn't promise this, but
1483    * we need these assertions to fail as soon as we're wrong about
1484    * it so we can do the porting fixups
1485    */
1486   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1487   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1488   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1489
1490   _dbus_credentials_clear (credentials);
1491
1492   /* Systems supporting LOCAL_CREDS are configured to have this feature
1493    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1494    * the connection.  Therefore, the received message must carry the
1495    * credentials information without doing anything special.
1496    */
1497
1498   iov.iov_base = &buf;
1499   iov.iov_len = 1;
1500
1501   _DBUS_ZERO(msg);
1502   msg.msg_iov = &iov;
1503   msg.msg_iovlen = 1;
1504
1505 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1506   _DBUS_ZERO(cmsg);
1507   msg.msg_control = &cmsg;
1508   msg.msg_controllen = sizeof (cmsg);
1509 #endif
1510
1511  again:
1512   bytes_read = recvmsg (client_fd, &msg, 0);
1513
1514   if (bytes_read < 0)
1515     {
1516       if (errno == EINTR)
1517         goto again;
1518
1519       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1520        * normally only call read_credentials if the socket was ready
1521        * for reading
1522        */
1523       
1524       dbus_set_error (error, _dbus_error_from_errno (errno),
1525                       "Failed to read credentials byte: %s",
1526                       _dbus_strerror (errno));
1527       return FALSE;
1528     }
1529   else if (bytes_read == 0)
1530     {
1531       /* this should not happen unless we are using recvmsg wrong,
1532        * so is essentially here for paranoia
1533        */
1534       dbus_set_error (error, DBUS_ERROR_FAILED,
1535                       "Failed to read credentials byte (zero-length read)");
1536       return FALSE;
1537     }
1538   else if (buf != '\0')
1539     {
1540       dbus_set_error (error, DBUS_ERROR_FAILED,
1541                       "Credentials byte was not nul");
1542       return FALSE;
1543     }
1544
1545 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1546   if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
1547     {
1548       dbus_set_error (error, DBUS_ERROR_FAILED,
1549                       "Message from recvmsg() was not SCM_CREDS");
1550       return FALSE;
1551     }
1552 #endif
1553
1554   _dbus_verbose ("read credentials byte\n");
1555
1556   {
1557 #ifdef SO_PEERCRED
1558     struct ucred cr;   
1559     int cr_len = sizeof (cr);
1560     
1561     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1562         cr_len == sizeof (cr))
1563       {
1564         pid_read = cr.pid;
1565         uid_read = cr.uid;
1566       }
1567     else
1568       {
1569         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1570                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1571       }
1572 #elif defined(HAVE_CMSGCRED)
1573     pid_read = cmsg.cred.cmcred_pid;
1574     uid_read = cmsg.cred.cmcred_euid;
1575 #elif defined(LOCAL_CREDS)
1576     pid_read = DBUS_PID_UNSET;
1577     uid_read = cmsg.cred.sc_uid;
1578     /* Since we have already got the credentials from this socket, we can
1579      * disable its LOCAL_CREDS flag if it was ever set. */
1580     _dbus_set_local_creds (client_fd, FALSE);
1581 #elif defined(HAVE_GETPEEREID)
1582     uid_t euid;
1583     gid_t egid;
1584     if (getpeereid (client_fd, &euid, &egid) == 0)
1585       {
1586         uid_read = euid;
1587       }
1588     else
1589       {
1590         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1591       }
1592 #elif defined(HAVE_GETPEERUCRED)
1593     ucred_t * ucred = NULL;
1594     if (getpeerucred (client_fd, &ucred) == 0)
1595       {
1596         pid_read = ucred_getpid (ucred);
1597         uid_read = ucred_geteuid (ucred);
1598 #ifdef HAVE_ADT
1599         /* generate audit session data based on socket ucred */
1600         adt_session_data_t *adth = NULL;
1601         adt_export_data_t *data = NULL;
1602         size_t size = 0;
1603         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1604           {
1605             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1606           }
1607         else 
1608           {
1609             if (adt_set_from_ucred (adth, ucred, ADT_NEW)) 
1610               {
1611                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1612               }
1613             else
1614               {
1615                 size = adt_export_session_data (adth, &data);
1616                 if (size <= 0)
1617                   {
1618                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1619                   }
1620                 else
1621                   {
1622                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
1623                     free (data);
1624                   }
1625               }
1626             (void) adt_end_session (adth);
1627           }
1628 #endif /* HAVE_ADT */
1629       }
1630     else
1631       {
1632         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1633       }
1634     if (ucred != NULL)
1635       ucred_free (ucred);
1636 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1637     _dbus_verbose ("Socket credentials not supported on this OS\n");
1638 #endif
1639   }
1640
1641   _dbus_verbose ("Credentials:"
1642                  "  pid "DBUS_PID_FORMAT
1643                  "  uid "DBUS_UID_FORMAT
1644                  "\n",
1645                  pid_read,
1646                  uid_read);
1647
1648   if (pid_read != DBUS_PID_UNSET)
1649     {
1650       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1651         {
1652           _DBUS_SET_OOM (error);
1653           return FALSE;
1654         }
1655     }
1656
1657   if (uid_read != DBUS_UID_UNSET)
1658     {
1659       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1660         {
1661           _DBUS_SET_OOM (error);
1662           return FALSE;
1663         }
1664     }
1665   
1666   return TRUE;
1667 }
1668
1669 /**
1670  * Sends a single nul byte with our UNIX credentials as ancillary
1671  * data.  Returns #TRUE if the data was successfully written.  On
1672  * systems that don't support sending credentials, just writes a byte,
1673  * doesn't send any credentials.  On some systems, such as Linux,
1674  * reading/writing the byte isn't actually required, but we do it
1675  * anyway just to avoid multiple codepaths.
1676  *
1677  * Fails if no byte can be written, so you must select() first.
1678  *
1679  * The point of the byte is that on some systems we have to
1680  * use sendmsg()/recvmsg() to transmit credentials.
1681  *
1682  * @param server_fd file descriptor for connection to server
1683  * @param error return location for error code
1684  * @returns #TRUE if the byte was sent
1685  */
1686 dbus_bool_t
1687 _dbus_send_credentials_socket  (int              server_fd,
1688                                 DBusError       *error)
1689 {
1690   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1691   
1692   if (write_credentials_byte (server_fd, error))
1693     return TRUE;
1694   else
1695     return FALSE;
1696 }
1697
1698 /**
1699  * Accepts a connection on a listening socket.
1700  * Handles EINTR for you.
1701  *
1702  * This will enable FD_CLOEXEC for the returned socket.
1703  *
1704  * @param listen_fd the listen file descriptor
1705  * @returns the connection fd of the client, or -1 on error
1706  */
1707 int
1708 _dbus_accept  (int listen_fd)
1709 {
1710   int client_fd;
1711   struct sockaddr addr;
1712   socklen_t addrlen;
1713 #ifdef HAVE_ACCEPT4
1714   dbus_bool_t cloexec_done;
1715 #endif
1716
1717   addrlen = sizeof (addr);
1718
1719  retry:
1720
1721 #ifdef HAVE_ACCEPT4
1722   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1723   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1724   cloexec_done = client_fd >= 0;
1725
1726   if (client_fd < 0 && errno == ENOSYS)
1727 #endif
1728     {
1729       client_fd = accept (listen_fd, &addr, &addrlen);
1730     }
1731
1732   if (client_fd < 0)
1733     {
1734       if (errno == EINTR)
1735         goto retry;
1736     }
1737
1738   _dbus_verbose ("client fd %d accepted\n", client_fd);
1739
1740 #ifdef HAVE_ACCEPT4
1741   if (!cloexec_done)
1742 #endif
1743     {
1744       _dbus_fd_set_close_on_exec(client_fd);
1745     }
1746
1747   return client_fd;
1748 }
1749
1750 /**
1751  * Checks to make sure the given directory is 
1752  * private to the user 
1753  *
1754  * @param dir the name of the directory
1755  * @param error error return
1756  * @returns #FALSE on failure
1757  **/
1758 dbus_bool_t
1759 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1760 {
1761   const char *directory;
1762   struct stat sb;
1763         
1764   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1765     
1766   directory = _dbus_string_get_const_data (dir);
1767         
1768   if (stat (directory, &sb) < 0)
1769     {
1770       dbus_set_error (error, _dbus_error_from_errno (errno),
1771                       "%s", _dbus_strerror (errno));
1772    
1773       return FALSE;
1774     }
1775     
1776   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1777       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1778     {
1779       dbus_set_error (error, DBUS_ERROR_FAILED,
1780                      "%s directory is not private to the user", directory);
1781       return FALSE;
1782     }
1783     
1784   return TRUE;
1785 }
1786
1787 static dbus_bool_t
1788 fill_user_info_from_passwd (struct passwd *p,
1789                             DBusUserInfo  *info,
1790                             DBusError     *error)
1791 {
1792   _dbus_assert (p->pw_name != NULL);
1793   _dbus_assert (p->pw_dir != NULL);
1794   
1795   info->uid = p->pw_uid;
1796   info->primary_gid = p->pw_gid;
1797   info->username = _dbus_strdup (p->pw_name);
1798   info->homedir = _dbus_strdup (p->pw_dir);
1799   
1800   if (info->username == NULL ||
1801       info->homedir == NULL)
1802     {
1803       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1804       return FALSE;
1805     }
1806
1807   return TRUE;
1808 }
1809
1810 static dbus_bool_t
1811 fill_user_info (DBusUserInfo       *info,
1812                 dbus_uid_t          uid,
1813                 const DBusString   *username,
1814                 DBusError          *error)
1815 {
1816   const char *username_c;
1817   
1818   /* exactly one of username/uid provided */
1819   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1820   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1821
1822   info->uid = DBUS_UID_UNSET;
1823   info->primary_gid = DBUS_GID_UNSET;
1824   info->group_ids = NULL;
1825   info->n_group_ids = 0;
1826   info->username = NULL;
1827   info->homedir = NULL;
1828   
1829   if (username != NULL)
1830     username_c = _dbus_string_get_const_data (username);
1831   else
1832     username_c = NULL;
1833
1834   /* For now assuming that the getpwnam() and getpwuid() flavors
1835    * are always symmetrical, if not we have to add more configure
1836    * checks
1837    */
1838   
1839 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1840   {
1841     struct passwd *p;
1842     int result;
1843     size_t buflen;
1844     char *buf;
1845     struct passwd p_str;
1846
1847     /* retrieve maximum needed size for buf */
1848     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1849
1850     /* sysconf actually returns a long, but everything else expects size_t,
1851      * so just recast here.
1852      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1853      */
1854     if ((long) buflen <= 0)
1855       buflen = 1024;
1856
1857     result = -1;
1858     while (1)
1859       {
1860         buf = dbus_malloc (buflen);
1861         if (buf == NULL)
1862           {
1863             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1864             return FALSE;
1865           }
1866
1867         p = NULL;
1868 #ifdef HAVE_POSIX_GETPWNAM_R
1869         if (uid != DBUS_UID_UNSET)
1870           result = getpwuid_r (uid, &p_str, buf, buflen,
1871                                &p);
1872         else
1873           result = getpwnam_r (username_c, &p_str, buf, buflen,
1874                                &p);
1875 #else
1876         if (uid != DBUS_UID_UNSET)
1877           p = getpwuid_r (uid, &p_str, buf, buflen);
1878         else
1879           p = getpwnam_r (username_c, &p_str, buf, buflen);
1880         result = 0;
1881 #endif /* !HAVE_POSIX_GETPWNAM_R */
1882         //Try a bigger buffer if ERANGE was returned
1883         if (result == ERANGE && buflen < 512 * 1024)
1884           {
1885             dbus_free (buf);
1886             buflen *= 2;
1887           }
1888         else
1889           {
1890             break;
1891           }
1892       }
1893     if (result == 0 && p == &p_str)
1894       {
1895         if (!fill_user_info_from_passwd (p, info, error))
1896           {
1897             dbus_free (buf);
1898             return FALSE;
1899           }
1900         dbus_free (buf);
1901       }
1902     else
1903       {
1904         dbus_set_error (error, _dbus_error_from_errno (errno),
1905                         "User \"%s\" unknown or no memory to allocate password entry\n",
1906                         username_c ? username_c : "???");
1907         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1908         dbus_free (buf);
1909         return FALSE;
1910       }
1911   }
1912 #else /* ! HAVE_GETPWNAM_R */
1913   {
1914     /* I guess we're screwed on thread safety here */
1915     struct passwd *p;
1916
1917     if (uid != DBUS_UID_UNSET)
1918       p = getpwuid (uid);
1919     else
1920       p = getpwnam (username_c);
1921
1922     if (p != NULL)
1923       {
1924         if (!fill_user_info_from_passwd (p, info, error))
1925           {
1926             return FALSE;
1927           }
1928       }
1929     else
1930       {
1931         dbus_set_error (error, _dbus_error_from_errno (errno),
1932                         "User \"%s\" unknown or no memory to allocate password entry\n",
1933                         username_c ? username_c : "???");
1934         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1935         return FALSE;
1936       }
1937   }
1938 #endif  /* ! HAVE_GETPWNAM_R */
1939
1940   /* Fill this in so we can use it to get groups */
1941   username_c = info->username;
1942   
1943 #ifdef HAVE_GETGROUPLIST
1944   {
1945     gid_t *buf;
1946     int buf_count;
1947     int i;
1948     
1949     buf_count = 17;
1950     buf = dbus_new (gid_t, buf_count);
1951     if (buf == NULL)
1952       {
1953         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1954         goto failed;
1955       }
1956     
1957     if (getgrouplist (username_c,
1958                       info->primary_gid,
1959                       buf, &buf_count) < 0)
1960       {
1961         gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1962         if (new == NULL)
1963           {
1964             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1965             dbus_free (buf);
1966             goto failed;
1967           }
1968         
1969         buf = new;
1970
1971         errno = 0;
1972         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
1973           {
1974             dbus_set_error (error,
1975                             _dbus_error_from_errno (errno),
1976                             "Failed to get groups for username \"%s\" primary GID "
1977                             DBUS_GID_FORMAT ": %s\n",
1978                             username_c, info->primary_gid,
1979                             _dbus_strerror (errno));
1980             dbus_free (buf);
1981             goto failed;
1982           }
1983       }
1984
1985     info->group_ids = dbus_new (dbus_gid_t, buf_count);
1986     if (info->group_ids == NULL)
1987       {
1988         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1989         dbus_free (buf);
1990         goto failed;
1991       }
1992     
1993     for (i = 0; i < buf_count; ++i)
1994       info->group_ids[i] = buf[i];
1995
1996     info->n_group_ids = buf_count;
1997     
1998     dbus_free (buf);
1999   }
2000 #else  /* HAVE_GETGROUPLIST */
2001   {
2002     /* We just get the one group ID */
2003     info->group_ids = dbus_new (dbus_gid_t, 1);
2004     if (info->group_ids == NULL)
2005       {
2006         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2007         goto failed;
2008       }
2009
2010     info->n_group_ids = 1;
2011
2012     (info->group_ids)[0] = info->primary_gid;
2013   }
2014 #endif /* HAVE_GETGROUPLIST */
2015
2016   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2017   
2018   return TRUE;
2019   
2020  failed:
2021   _DBUS_ASSERT_ERROR_IS_SET (error);
2022   return FALSE;
2023 }
2024
2025 /**
2026  * Gets user info for the given username.
2027  *
2028  * @param info user info object to initialize
2029  * @param username the username
2030  * @param error error return
2031  * @returns #TRUE on success
2032  */
2033 dbus_bool_t
2034 _dbus_user_info_fill (DBusUserInfo     *info,
2035                       const DBusString *username,
2036                       DBusError        *error)
2037 {
2038   return fill_user_info (info, DBUS_UID_UNSET,
2039                          username, error);
2040 }
2041
2042 /**
2043  * Gets user info for the given user ID.
2044  *
2045  * @param info user info object to initialize
2046  * @param uid the user ID
2047  * @param error error return
2048  * @returns #TRUE on success
2049  */
2050 dbus_bool_t
2051 _dbus_user_info_fill_uid (DBusUserInfo *info,
2052                           dbus_uid_t    uid,
2053                           DBusError    *error)
2054 {
2055   return fill_user_info (info, uid,
2056                          NULL, error);
2057 }
2058
2059 /**
2060  * Adds the credentials of the current process to the
2061  * passed-in credentials object.
2062  *
2063  * @param credentials credentials to add to
2064  * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2065  */
2066 dbus_bool_t
2067 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2068 {
2069   /* The POSIX spec certainly doesn't promise this, but
2070    * we need these assertions to fail as soon as we're wrong about
2071    * it so we can do the porting fixups
2072    */
2073   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2074   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2075   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2076
2077   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2078     return FALSE;
2079   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2080     return FALSE;
2081
2082   return TRUE;
2083 }
2084
2085 /**
2086  * Append to the string the identity we would like to have when we
2087  * authenticate, on UNIX this is the current process UID and on
2088  * Windows something else, probably a Windows SID string.  No escaping
2089  * is required, that is done in dbus-auth.c. The username here
2090  * need not be anything human-readable, it can be the machine-readable
2091  * form i.e. a user id.
2092  * 
2093  * @param str the string to append to
2094  * @returns #FALSE on no memory
2095  */
2096 dbus_bool_t
2097 _dbus_append_user_from_current_process (DBusString *str)
2098 {
2099   return _dbus_string_append_uint (str,
2100                                    _dbus_geteuid ());
2101 }
2102
2103 /**
2104  * Gets our process ID
2105  * @returns process ID
2106  */
2107 dbus_pid_t
2108 _dbus_getpid (void)
2109 {
2110   return getpid ();
2111 }
2112
2113 /** Gets our UID
2114  * @returns process UID
2115  */
2116 dbus_uid_t
2117 _dbus_getuid (void)
2118 {
2119   return getuid ();
2120 }
2121
2122 /** Gets our effective UID
2123  * @returns process effective UID
2124  */
2125 dbus_uid_t
2126 _dbus_geteuid (void)
2127 {
2128   return geteuid ();
2129 }
2130
2131 /**
2132  * The only reason this is separate from _dbus_getpid() is to allow it
2133  * on Windows for logging but not for other purposes.
2134  * 
2135  * @returns process ID to put in log messages
2136  */
2137 unsigned long
2138 _dbus_pid_for_log (void)
2139 {
2140   return getpid ();
2141 }
2142
2143 /**
2144  * Gets a UID from a UID string.
2145  *
2146  * @param uid_str the UID in string form
2147  * @param uid UID to fill in
2148  * @returns #TRUE if successfully filled in UID
2149  */
2150 dbus_bool_t
2151 _dbus_parse_uid (const DBusString      *uid_str,
2152                  dbus_uid_t            *uid)
2153 {
2154   int end;
2155   long val;
2156   
2157   if (_dbus_string_get_length (uid_str) == 0)
2158     {
2159       _dbus_verbose ("UID string was zero length\n");
2160       return FALSE;
2161     }
2162
2163   val = -1;
2164   end = 0;
2165   if (!_dbus_string_parse_int (uid_str, 0, &val,
2166                                &end))
2167     {
2168       _dbus_verbose ("could not parse string as a UID\n");
2169       return FALSE;
2170     }
2171   
2172   if (end != _dbus_string_get_length (uid_str))
2173     {
2174       _dbus_verbose ("string contained trailing stuff after UID\n");
2175       return FALSE;
2176     }
2177
2178   *uid = val;
2179
2180   return TRUE;
2181 }
2182
2183
2184 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2185
2186 #if DBUS_USE_ATOMIC_INT_486_COND
2187 /* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */
2188 /* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */
2189 static inline dbus_int32_t
2190 atomic_exchange_and_add (DBusAtomic            *atomic,
2191                          volatile dbus_int32_t  val)
2192 {
2193   register dbus_int32_t result;
2194
2195   __asm__ __volatile__ ("lock; xaddl %0,%1"
2196                         : "=r" (result), "=m" (atomic->value)
2197                         : "0" (val), "m" (atomic->value));
2198   return result;
2199 }
2200 #endif
2201
2202 /**
2203  * Atomically increments an integer
2204  *
2205  * @param atomic pointer to the integer to increment
2206  * @returns the value before incrementing
2207  *
2208  * @todo implement arch-specific faster atomic ops
2209  */
2210 dbus_int32_t
2211 _dbus_atomic_inc (DBusAtomic *atomic)
2212 {
2213 #if DBUS_USE_ATOMIC_INT_486_COND
2214   return atomic_exchange_and_add (atomic, 1);
2215 #else
2216   dbus_int32_t res;
2217   _DBUS_LOCK (atomic);
2218   res = atomic->value;
2219   atomic->value += 1;
2220   _DBUS_UNLOCK (atomic);
2221   return res;
2222 #endif
2223 }
2224
2225 /**
2226  * Atomically decrement an integer
2227  *
2228  * @param atomic pointer to the integer to decrement
2229  * @returns the value before decrementing
2230  *
2231  * @todo implement arch-specific faster atomic ops
2232  */
2233 dbus_int32_t
2234 _dbus_atomic_dec (DBusAtomic *atomic)
2235 {
2236 #if DBUS_USE_ATOMIC_INT_486_COND
2237   return atomic_exchange_and_add (atomic, -1);
2238 #else
2239   dbus_int32_t res;
2240   
2241   _DBUS_LOCK (atomic);
2242   res = atomic->value;
2243   atomic->value -= 1;
2244   _DBUS_UNLOCK (atomic);
2245   return res;
2246 #endif
2247 }
2248
2249 #ifdef DBUS_BUILD_TESTS
2250 /** Gets our GID
2251  * @returns process GID
2252  */
2253 dbus_gid_t
2254 _dbus_getgid (void)
2255 {
2256   return getgid ();
2257 }
2258 #endif
2259
2260 /**
2261  * Wrapper for poll().
2262  *
2263  * @param fds the file descriptors to poll
2264  * @param n_fds number of descriptors in the array
2265  * @param timeout_milliseconds timeout or -1 for infinite
2266  * @returns numbers of fds with revents, or <0 on error
2267  */
2268 int
2269 _dbus_poll (DBusPollFD *fds,
2270             int         n_fds,
2271             int         timeout_milliseconds)
2272 {
2273 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2274   /* This big thing is a constant expression and should get optimized
2275    * out of existence. So it's more robust than a configure check at
2276    * no cost.
2277    */
2278   if (_DBUS_POLLIN == POLLIN &&
2279       _DBUS_POLLPRI == POLLPRI &&
2280       _DBUS_POLLOUT == POLLOUT &&
2281       _DBUS_POLLERR == POLLERR &&
2282       _DBUS_POLLHUP == POLLHUP &&
2283       _DBUS_POLLNVAL == POLLNVAL &&
2284       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2285       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2286       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2287       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2288       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2289       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2290       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2291     {
2292       return poll ((struct pollfd*) fds,
2293                    n_fds, 
2294                    timeout_milliseconds);
2295     }
2296   else
2297     {
2298       /* We have to convert the DBusPollFD to an array of
2299        * struct pollfd, poll, and convert back.
2300        */
2301       _dbus_warn ("didn't implement poll() properly for this system yet\n");
2302       return -1;
2303     }
2304 #else /* ! HAVE_POLL */
2305
2306   fd_set read_set, write_set, err_set;
2307   int max_fd = 0;
2308   int i;
2309   struct timeval tv;
2310   int ready;
2311   
2312   FD_ZERO (&read_set);
2313   FD_ZERO (&write_set);
2314   FD_ZERO (&err_set);
2315
2316   for (i = 0; i < n_fds; i++)
2317     {
2318       DBusPollFD *fdp = &fds[i];
2319
2320       if (fdp->events & _DBUS_POLLIN)
2321         FD_SET (fdp->fd, &read_set);
2322
2323       if (fdp->events & _DBUS_POLLOUT)
2324         FD_SET (fdp->fd, &write_set);
2325
2326       FD_SET (fdp->fd, &err_set);
2327
2328       max_fd = MAX (max_fd, fdp->fd);
2329     }
2330     
2331   tv.tv_sec = timeout_milliseconds / 1000;
2332   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2333
2334   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2335                   timeout_milliseconds < 0 ? NULL : &tv);
2336
2337   if (ready > 0)
2338     {
2339       for (i = 0; i < n_fds; i++)
2340         {
2341           DBusPollFD *fdp = &fds[i];
2342
2343           fdp->revents = 0;
2344
2345           if (FD_ISSET (fdp->fd, &read_set))
2346             fdp->revents |= _DBUS_POLLIN;
2347
2348           if (FD_ISSET (fdp->fd, &write_set))
2349             fdp->revents |= _DBUS_POLLOUT;
2350
2351           if (FD_ISSET (fdp->fd, &err_set))
2352             fdp->revents |= _DBUS_POLLERR;
2353         }
2354     }
2355
2356   return ready;
2357 #endif
2358 }
2359
2360 /**
2361  * Get current time, as in gettimeofday().
2362  *
2363  * @param tv_sec return location for number of seconds
2364  * @param tv_usec return location for number of microseconds (thousandths)
2365  */
2366 void
2367 _dbus_get_current_time (long *tv_sec,
2368                         long *tv_usec)
2369 {
2370   struct timeval t;
2371
2372   gettimeofday (&t, NULL);
2373
2374   if (tv_sec)
2375     *tv_sec = t.tv_sec;
2376   if (tv_usec)
2377     *tv_usec = t.tv_usec;
2378 }
2379
2380 /**
2381  * Appends the contents of the given file to the string,
2382  * returning error code. At the moment, won't open a file
2383  * more than a megabyte in size.
2384  *
2385  * @param str the string to append to
2386  * @param filename filename to load
2387  * @param error place to set an error
2388  * @returns #FALSE if error was set
2389  */
2390 dbus_bool_t
2391 _dbus_file_get_contents (DBusString       *str,
2392                          const DBusString *filename,
2393                          DBusError        *error)
2394 {
2395   int fd;
2396   struct stat sb;
2397   int orig_len;
2398   int total;
2399   const char *filename_c;
2400
2401   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2402   
2403   filename_c = _dbus_string_get_const_data (filename);
2404   
2405   /* O_BINARY useful on Cygwin */
2406   fd = open (filename_c, O_RDONLY | O_BINARY);
2407   if (fd < 0)
2408     {
2409       dbus_set_error (error, _dbus_error_from_errno (errno),
2410                       "Failed to open \"%s\": %s",
2411                       filename_c,
2412                       _dbus_strerror (errno));
2413       return FALSE;
2414     }
2415
2416   _dbus_verbose ("file fd %d opened\n", fd);
2417   
2418   if (fstat (fd, &sb) < 0)
2419     {
2420       dbus_set_error (error, _dbus_error_from_errno (errno),
2421                       "Failed to stat \"%s\": %s",
2422                       filename_c,
2423                       _dbus_strerror (errno));
2424
2425       _dbus_verbose ("fstat() failed: %s",
2426                      _dbus_strerror (errno));
2427       
2428       _dbus_close (fd, NULL);
2429       
2430       return FALSE;
2431     }
2432
2433   if (sb.st_size > _DBUS_ONE_MEGABYTE)
2434     {
2435       dbus_set_error (error, DBUS_ERROR_FAILED,
2436                       "File size %lu of \"%s\" is too large.",
2437                       (unsigned long) sb.st_size, filename_c);
2438       _dbus_close (fd, NULL);
2439       return FALSE;
2440     }
2441   
2442   total = 0;
2443   orig_len = _dbus_string_get_length (str);
2444   if (sb.st_size > 0 && S_ISREG (sb.st_mode))
2445     {
2446       int bytes_read;
2447
2448       while (total < (int) sb.st_size)
2449         {
2450           bytes_read = _dbus_read (fd, str,
2451                                    sb.st_size - total);
2452           if (bytes_read <= 0)
2453             {
2454               dbus_set_error (error, _dbus_error_from_errno (errno),
2455                               "Error reading \"%s\": %s",
2456                               filename_c,
2457                               _dbus_strerror (errno));
2458
2459               _dbus_verbose ("read() failed: %s",
2460                              _dbus_strerror (errno));
2461               
2462               _dbus_close (fd, NULL);
2463               _dbus_string_set_length (str, orig_len);
2464               return FALSE;
2465             }
2466           else
2467             total += bytes_read;
2468         }
2469
2470       _dbus_close (fd, NULL);
2471       return TRUE;
2472     }
2473   else if (sb.st_size != 0)
2474     {
2475       _dbus_verbose ("Can only open regular files at the moment.\n");
2476       dbus_set_error (error, DBUS_ERROR_FAILED,
2477                       "\"%s\" is not a regular file",
2478                       filename_c);
2479       _dbus_close (fd, NULL);
2480       return FALSE;
2481     }
2482   else
2483     {
2484       _dbus_close (fd, NULL);
2485       return TRUE;
2486     }
2487 }
2488
2489 /**
2490  * Writes a string out to a file. If the file exists,
2491  * it will be atomically overwritten by the new data.
2492  *
2493  * @param str the string to write out
2494  * @param filename the file to save string to
2495  * @param error error to be filled in on failure
2496  * @returns #FALSE on failure
2497  */
2498 dbus_bool_t
2499 _dbus_string_save_to_file (const DBusString *str,
2500                            const DBusString *filename,
2501                            DBusError        *error)
2502 {
2503   int fd;
2504   int bytes_to_write;
2505   const char *filename_c;
2506   DBusString tmp_filename;
2507   const char *tmp_filename_c;
2508   int total;
2509   dbus_bool_t need_unlink;
2510   dbus_bool_t retval;
2511
2512   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2513   
2514   fd = -1;
2515   retval = FALSE;
2516   need_unlink = FALSE;
2517   
2518   if (!_dbus_string_init (&tmp_filename))
2519     {
2520       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2521       return FALSE;
2522     }
2523
2524   if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2525     {
2526       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2527       _dbus_string_free (&tmp_filename);
2528       return FALSE;
2529     }
2530   
2531   if (!_dbus_string_append (&tmp_filename, "."))
2532     {
2533       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2534       _dbus_string_free (&tmp_filename);
2535       return FALSE;
2536     }
2537
2538 #define N_TMP_FILENAME_RANDOM_BYTES 8
2539   if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2540     {
2541       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2542       _dbus_string_free (&tmp_filename);
2543       return FALSE;
2544     }
2545     
2546   filename_c = _dbus_string_get_const_data (filename);
2547   tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2548
2549   fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2550              0600);
2551   if (fd < 0)
2552     {
2553       dbus_set_error (error, _dbus_error_from_errno (errno),
2554                       "Could not create %s: %s", tmp_filename_c,
2555                       _dbus_strerror (errno));
2556       goto out;
2557     }
2558
2559   _dbus_verbose ("tmp file fd %d opened\n", fd);
2560   
2561   need_unlink = TRUE;
2562   
2563   total = 0;
2564   bytes_to_write = _dbus_string_get_length (str);
2565
2566   while (total < bytes_to_write)
2567     {
2568       int bytes_written;
2569
2570       bytes_written = _dbus_write (fd, str, total,
2571                                    bytes_to_write - total);
2572
2573       if (bytes_written <= 0)
2574         {
2575           dbus_set_error (error, _dbus_error_from_errno (errno),
2576                           "Could not write to %s: %s", tmp_filename_c,
2577                           _dbus_strerror (errno));
2578           
2579           goto out;
2580         }
2581
2582       total += bytes_written;
2583     }
2584
2585   if (fsync(fd))
2586     {
2587       dbus_set_error (error, _dbus_error_from_errno (errno),
2588                       "Could not synchronize file %s: %s",
2589                       tmp_filename_c, _dbus_strerror (errno));
2590
2591       goto out;
2592   }
2593
2594   if (!_dbus_close (fd, NULL))
2595     {
2596       dbus_set_error (error, _dbus_error_from_errno (errno),
2597                       "Could not close file %s: %s",
2598                       tmp_filename_c, _dbus_strerror (errno));
2599
2600       goto out;
2601     }
2602
2603   fd = -1;
2604   
2605   if (rename (tmp_filename_c, filename_c) < 0)
2606     {
2607       dbus_set_error (error, _dbus_error_from_errno (errno),
2608                       "Could not rename %s to %s: %s",
2609                       tmp_filename_c, filename_c,
2610                       _dbus_strerror (errno));
2611
2612       goto out;
2613     }
2614
2615   need_unlink = FALSE;
2616   
2617   retval = TRUE;
2618   
2619  out:
2620   /* close first, then unlink, to prevent ".nfs34234235" garbage
2621    * files
2622    */
2623
2624   if (fd >= 0)
2625     _dbus_close (fd, NULL);
2626         
2627   if (need_unlink && unlink (tmp_filename_c) < 0)
2628     _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2629                    tmp_filename_c, _dbus_strerror (errno));
2630
2631   _dbus_string_free (&tmp_filename);
2632
2633   if (!retval)
2634     _DBUS_ASSERT_ERROR_IS_SET (error);
2635   
2636   return retval;
2637 }
2638
2639 /** Makes the file readable by every user in the system.
2640  *
2641  * @param filename the filename
2642  * @param error error location
2643  * @returns #TRUE if the file's permissions could be changed.
2644  */
2645 dbus_bool_t
2646 _dbus_make_file_world_readable(const DBusString *filename,
2647                                DBusError *error)
2648 {
2649   const char *filename_c;
2650
2651   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2652
2653   filename_c = _dbus_string_get_const_data (filename);
2654   if (chmod (filename_c, 0644) == -1)
2655     {
2656       dbus_set_error (error,
2657                       DBUS_ERROR_FAILED,
2658                       "Could not change permissions of file %s: %s\n",
2659                       filename_c,
2660                       _dbus_strerror (errno));
2661       return FALSE;
2662     }
2663   return TRUE;
2664 }
2665
2666 /** Creates the given file, failing if the file already exists.
2667  *
2668  * @param filename the filename
2669  * @param error error location
2670  * @returns #TRUE if we created the file and it didn't exist
2671  */
2672 dbus_bool_t
2673 _dbus_create_file_exclusively (const DBusString *filename,
2674                                DBusError        *error)
2675 {
2676   int fd;
2677   const char *filename_c;
2678
2679   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2680   
2681   filename_c = _dbus_string_get_const_data (filename);
2682   
2683   fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2684              0600);
2685   if (fd < 0)
2686     {
2687       dbus_set_error (error,
2688                       DBUS_ERROR_FAILED,
2689                       "Could not create file %s: %s\n",
2690                       filename_c,
2691                       _dbus_strerror (errno));
2692       return FALSE;
2693     }
2694
2695   _dbus_verbose ("exclusive file fd %d opened\n", fd);
2696   
2697   if (!_dbus_close (fd, NULL))
2698     {
2699       dbus_set_error (error,
2700                       DBUS_ERROR_FAILED,
2701                       "Could not close file %s: %s\n",
2702                       filename_c,
2703                       _dbus_strerror (errno));
2704       return FALSE;
2705     }
2706   
2707   return TRUE;
2708 }
2709
2710 /**
2711  * Deletes the given file.
2712  *
2713  * @param filename the filename
2714  * @param error error location
2715  * 
2716  * @returns #TRUE if unlink() succeeded
2717  */
2718 dbus_bool_t
2719 _dbus_delete_file (const DBusString *filename,
2720                    DBusError        *error)
2721 {
2722   const char *filename_c;
2723
2724   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2725   
2726   filename_c = _dbus_string_get_const_data (filename);
2727
2728   if (unlink (filename_c) < 0)
2729     {
2730       dbus_set_error (error, DBUS_ERROR_FAILED,
2731                       "Failed to delete file %s: %s\n",
2732                       filename_c, _dbus_strerror (errno));
2733       return FALSE;
2734     }
2735   else
2736     return TRUE;
2737 }
2738
2739 /**
2740  * Creates a directory; succeeds if the directory
2741  * is created or already existed.
2742  *
2743  * @param filename directory filename
2744  * @param error initialized error object
2745  * @returns #TRUE on success
2746  */
2747 dbus_bool_t
2748 _dbus_create_directory (const DBusString *filename,
2749                         DBusError        *error)
2750 {
2751   const char *filename_c;
2752
2753   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2754   
2755   filename_c = _dbus_string_get_const_data (filename);
2756
2757   if (mkdir (filename_c, 0700) < 0)
2758     {
2759       if (errno == EEXIST)
2760         return TRUE;
2761       
2762       dbus_set_error (error, DBUS_ERROR_FAILED,
2763                       "Failed to create directory %s: %s\n",
2764                       filename_c, _dbus_strerror (errno));
2765       return FALSE;
2766     }
2767   else
2768     return TRUE;
2769 }
2770
2771 /**
2772  * Appends the given filename to the given directory.
2773  *
2774  * @todo it might be cute to collapse multiple '/' such as "foo//"
2775  * concat "//bar"
2776  *
2777  * @param dir the directory name
2778  * @param next_component the filename
2779  * @returns #TRUE on success
2780  */
2781 dbus_bool_t
2782 _dbus_concat_dir_and_file (DBusString       *dir,
2783                            const DBusString *next_component)
2784 {
2785   dbus_bool_t dir_ends_in_slash;
2786   dbus_bool_t file_starts_with_slash;
2787
2788   if (_dbus_string_get_length (dir) == 0 ||
2789       _dbus_string_get_length (next_component) == 0)
2790     return TRUE;
2791   
2792   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2793                                                     _dbus_string_get_length (dir) - 1);
2794
2795   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2796
2797   if (dir_ends_in_slash && file_starts_with_slash)
2798     {
2799       _dbus_string_shorten (dir, 1);
2800     }
2801   else if (!(dir_ends_in_slash || file_starts_with_slash))
2802     {
2803       if (!_dbus_string_append_byte (dir, '/'))
2804         return FALSE;
2805     }
2806
2807   return _dbus_string_copy (next_component, 0, dir,
2808                             _dbus_string_get_length (dir));
2809 }
2810
2811 /** nanoseconds in a second */
2812 #define NANOSECONDS_PER_SECOND       1000000000
2813 /** microseconds in a second */
2814 #define MICROSECONDS_PER_SECOND      1000000
2815 /** milliseconds in a second */
2816 #define MILLISECONDS_PER_SECOND      1000
2817 /** nanoseconds in a millisecond */
2818 #define NANOSECONDS_PER_MILLISECOND  1000000
2819 /** microseconds in a millisecond */
2820 #define MICROSECONDS_PER_MILLISECOND 1000
2821
2822 /**
2823  * Sleeps the given number of milliseconds.
2824  * @param milliseconds number of milliseconds
2825  */
2826 void
2827 _dbus_sleep_milliseconds (int milliseconds)
2828 {
2829 #ifdef HAVE_NANOSLEEP
2830   struct timespec req;
2831   struct timespec rem;
2832
2833   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2834   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2835   rem.tv_sec = 0;
2836   rem.tv_nsec = 0;
2837
2838   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2839     req = rem;
2840 #elif defined (HAVE_USLEEP)
2841   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2842 #else /* ! HAVE_USLEEP */
2843   sleep (MAX (milliseconds / 1000, 1));
2844 #endif
2845 }
2846
2847 static dbus_bool_t
2848 _dbus_generate_pseudorandom_bytes (DBusString *str,
2849                                    int         n_bytes)
2850 {
2851   int old_len;
2852   char *p;
2853   
2854   old_len = _dbus_string_get_length (str);
2855
2856   if (!_dbus_string_lengthen (str, n_bytes))
2857     return FALSE;
2858
2859   p = _dbus_string_get_data_len (str, old_len, n_bytes);
2860
2861   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2862
2863   return TRUE;
2864 }
2865
2866 /**
2867  * Generates the given number of random bytes,
2868  * using the best mechanism we can come up with.
2869  *
2870  * @param str the string
2871  * @param n_bytes the number of random bytes to append to string
2872  * @returns #TRUE on success, #FALSE if no memory
2873  */
2874 dbus_bool_t
2875 _dbus_generate_random_bytes (DBusString *str,
2876                              int         n_bytes)
2877 {
2878   int old_len;
2879   int fd;
2880
2881   /* FALSE return means "no memory", if it could
2882    * mean something else then we'd need to return
2883    * a DBusError. So we always fall back to pseudorandom
2884    * if the I/O fails.
2885    */
2886   
2887   old_len = _dbus_string_get_length (str);
2888   fd = -1;
2889
2890   /* note, urandom on linux will fall back to pseudorandom */
2891   fd = open ("/dev/urandom", O_RDONLY);
2892   if (fd < 0)
2893     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2894
2895   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2896   
2897   if (_dbus_read (fd, str, n_bytes) != n_bytes)
2898     {
2899       _dbus_close (fd, NULL);
2900       _dbus_string_set_length (str, old_len);
2901       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2902     }
2903
2904   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2905                  n_bytes);
2906   
2907   _dbus_close (fd, NULL);
2908   
2909   return TRUE;
2910 }
2911
2912 /**
2913  * Exit the process, returning the given value.
2914  *
2915  * @param code the exit code
2916  */
2917 void
2918 _dbus_exit (int code)
2919 {
2920   _exit (code);
2921 }
2922
2923 /**
2924  * A wrapper around strerror() because some platforms
2925  * may be lame and not have strerror(). Also, never
2926  * returns NULL.
2927  *
2928  * @param error_number errno.
2929  * @returns error description.
2930  */
2931 const char*
2932 _dbus_strerror (int error_number)
2933 {
2934   const char *msg;
2935   
2936   msg = strerror (error_number);
2937   if (msg == NULL)
2938     msg = "unknown";
2939
2940   return msg;
2941 }
2942
2943 /**
2944  * signal (SIGPIPE, SIG_IGN);
2945  */
2946 void
2947 _dbus_disable_sigpipe (void)
2948 {
2949   signal (SIGPIPE, SIG_IGN);
2950 }
2951
2952 /**
2953  * Sets the file descriptor to be close
2954  * on exec. Should be called for all file
2955  * descriptors in D-Bus code.
2956  *
2957  * @param fd the file descriptor
2958  */
2959 void
2960 _dbus_fd_set_close_on_exec (int fd)
2961 {
2962   int val;
2963   
2964   val = fcntl (fd, F_GETFD, 0);
2965   
2966   if (val < 0)
2967     return;
2968
2969   val |= FD_CLOEXEC;
2970   
2971   fcntl (fd, F_SETFD, val);
2972 }
2973
2974 /**
2975  * Closes a file descriptor.
2976  *
2977  * @param fd the file descriptor
2978  * @param error error object
2979  * @returns #FALSE if error set
2980  */
2981 dbus_bool_t
2982 _dbus_close (int        fd,
2983              DBusError *error)
2984 {
2985   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2986   
2987  again:
2988   if (close (fd) < 0)
2989     {
2990       if (errno == EINTR)
2991         goto again;
2992
2993       dbus_set_error (error, _dbus_error_from_errno (errno),
2994                       "Could not close fd %d", fd);
2995       return FALSE;
2996     }
2997
2998   return TRUE;
2999 }
3000
3001 /**
3002  * Duplicates a file descriptor. Makes sure the fd returned is >= 3
3003  * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
3004  *
3005  * @param fd the file descriptor to duplicate
3006  * @returns duplicated file descriptor
3007  * */
3008 int
3009 _dbus_dup(int        fd,
3010           DBusError *error)
3011 {
3012   int new_fd;
3013
3014 #ifdef F_DUPFD_CLOEXEC
3015   dbus_bool_t cloexec_done;
3016
3017   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3018   cloexec_done = new_fd >= 0;
3019
3020   if (new_fd < 0 && errno == EINVAL)
3021 #endif
3022     {
3023       new_fd = fcntl(fd, F_DUPFD, 3);
3024     }
3025
3026   if (new_fd < 0) {
3027
3028     dbus_set_error (error, _dbus_error_from_errno (errno),
3029                     "Could not duplicate fd %d", fd);
3030     return -1;
3031   }
3032
3033 #ifndef F_DUPFD_CLOEXEC
3034   if (!cloexec_done)
3035 #endif
3036     {
3037       _dbus_fd_set_close_on_exec(new_fd);
3038     }
3039
3040   return new_fd;
3041 }
3042
3043 /**
3044  * Sets a file descriptor to be nonblocking.
3045  *
3046  * @param fd the file descriptor.
3047  * @param error address of error location.
3048  * @returns #TRUE on success.
3049  */
3050 dbus_bool_t
3051 _dbus_set_fd_nonblocking (int             fd,
3052                           DBusError      *error)
3053 {
3054   int val;
3055
3056   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3057   
3058   val = fcntl (fd, F_GETFL, 0);
3059   if (val < 0)
3060     {
3061       dbus_set_error (error, _dbus_error_from_errno (errno),
3062                       "Failed to get flags from file descriptor %d: %s",
3063                       fd, _dbus_strerror (errno));
3064       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3065                      _dbus_strerror (errno));
3066       return FALSE;
3067     }
3068
3069   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3070     {
3071       dbus_set_error (error, _dbus_error_from_errno (errno),
3072                       "Failed to set nonblocking flag of file descriptor %d: %s",
3073                       fd, _dbus_strerror (errno));
3074       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3075                      fd, _dbus_strerror (errno));
3076
3077       return FALSE;
3078     }
3079
3080   return TRUE;
3081 }
3082
3083 /**
3084  * On GNU libc systems, print a crude backtrace to stderr.  On other
3085  * systems, print "no backtrace support" and block for possible gdb
3086  * attachment if an appropriate environment variable is set.
3087  */
3088 void
3089 _dbus_print_backtrace (void)
3090 {  
3091 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3092   void *bt[500];
3093   int bt_size;
3094   int i;
3095   char **syms;
3096   
3097   bt_size = backtrace (bt, 500);
3098
3099   syms = backtrace_symbols (bt, bt_size);
3100   
3101   i = 0;
3102   while (i < bt_size)
3103     {
3104       /* don't use dbus_warn since it can _dbus_abort() */
3105       fprintf (stderr, "  %s\n", syms[i]);
3106       ++i;
3107     }
3108   fflush (stderr);
3109
3110   free (syms);
3111 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3112   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
3113 #else
3114   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3115 #endif
3116 }
3117
3118 /**
3119  * Creates a full-duplex pipe (as in socketpair()).
3120  * Sets both ends of the pipe nonblocking.
3121  *
3122  * Marks both file descriptors as close-on-exec
3123  *
3124  * @todo libdbus only uses this for the debug-pipe server, so in
3125  * principle it could be in dbus-sysdeps-util.c, except that
3126  * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
3127  * debug-pipe server is used.
3128  * 
3129  * @param fd1 return location for one end
3130  * @param fd2 return location for the other end
3131  * @param blocking #TRUE if pipe should be blocking
3132  * @param error error return
3133  * @returns #FALSE on failure (if error is set)
3134  */
3135 dbus_bool_t
3136 _dbus_full_duplex_pipe (int        *fd1,
3137                         int        *fd2,
3138                         dbus_bool_t blocking,
3139                         DBusError  *error)
3140 {
3141 #ifdef HAVE_SOCKETPAIR
3142   int fds[2];
3143   int retval;
3144
3145 #ifdef SOCK_CLOEXEC
3146   dbus_bool_t cloexec_done;
3147
3148   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3149   cloexec_done = retval >= 0;
3150
3151   if (retval < 0 && errno == EINVAL)
3152 #endif
3153     {
3154       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3155     }
3156
3157   if (retval < 0)
3158     {
3159       dbus_set_error (error, _dbus_error_from_errno (errno),
3160                       "Could not create full-duplex pipe");
3161       return FALSE;
3162     }
3163
3164   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3165
3166 #ifdef SOCK_CLOEXEC
3167   if (!cloexec_done)
3168 #endif
3169     {
3170       _dbus_fd_set_close_on_exec (fds[0]);
3171       _dbus_fd_set_close_on_exec (fds[1]);
3172     }
3173
3174   if (!blocking &&
3175       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3176        !_dbus_set_fd_nonblocking (fds[1], NULL)))
3177     {
3178       dbus_set_error (error, _dbus_error_from_errno (errno),
3179                       "Could not set full-duplex pipe nonblocking");
3180       
3181       _dbus_close (fds[0], NULL);
3182       _dbus_close (fds[1], NULL);
3183       
3184       return FALSE;
3185     }
3186   
3187   *fd1 = fds[0];
3188   *fd2 = fds[1];
3189
3190   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3191                  *fd1, *fd2);
3192   
3193   return TRUE;  
3194 #else
3195   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3196   dbus_set_error (error, DBUS_ERROR_FAILED,
3197                   "_dbus_full_duplex_pipe() not implemented on this OS");
3198   return FALSE;
3199 #endif
3200 }
3201
3202 /**
3203  * Measure the length of the given format string and arguments,
3204  * not including the terminating nul.
3205  *
3206  * @param format a printf-style format string
3207  * @param args arguments for the format string
3208  * @returns length of the given format string and args
3209  */
3210 int
3211 _dbus_printf_string_upper_bound (const char *format,
3212                                  va_list     args)
3213 {
3214   char c;
3215   return vsnprintf (&c, 1, format, args);
3216 }
3217
3218 /**
3219  * Gets the temporary files directory by inspecting the environment variables 
3220  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3221  *
3222  * @returns location of temp directory
3223  */
3224 const char*
3225 _dbus_get_tmpdir(void)
3226 {
3227   static const char* tmpdir = NULL;
3228
3229   if (tmpdir == NULL)
3230     {
3231       /* TMPDIR is what glibc uses, then
3232        * glibc falls back to the P_tmpdir macro which
3233        * just expands to "/tmp"
3234        */
3235       if (tmpdir == NULL)
3236         tmpdir = getenv("TMPDIR");
3237
3238       /* These two env variables are probably
3239        * broken, but maybe some OS uses them?
3240        */
3241       if (tmpdir == NULL)
3242         tmpdir = getenv("TMP");
3243       if (tmpdir == NULL)
3244         tmpdir = getenv("TEMP");
3245
3246       /* And this is the sane fallback. */
3247       if (tmpdir == NULL)
3248         tmpdir = "/tmp";
3249     }
3250   
3251   _dbus_assert(tmpdir != NULL);
3252   
3253   return tmpdir;
3254 }
3255
3256 /**
3257  * Determines the address of the session bus by querying a
3258  * platform-specific method.
3259  *
3260  * If successful, returns #TRUE and appends the address to @p
3261  * address. If a failure happens, returns #FALSE and
3262  * sets an error in @p error.
3263  *
3264  * @param address a DBusString where the address can be stored
3265  * @param error a DBusError to store the error in case of failure
3266  * @returns #TRUE on success, #FALSE if an error happened
3267  */
3268 dbus_bool_t
3269 _dbus_get_autolaunch_address (DBusString *address,
3270                               DBusError  *error)
3271 {
3272   static char *argv[6];
3273   int address_pipe[2] = { -1, -1 };
3274   int errors_pipe[2] = { -1, -1 };
3275   pid_t pid;
3276   int ret;
3277   int status;
3278   int orig_len;
3279   int i;
3280   DBusString uuid;
3281   dbus_bool_t retval;
3282   
3283   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3284   retval = FALSE;
3285
3286   if (!_dbus_string_init (&uuid))
3287     {
3288       _DBUS_SET_OOM (error);
3289       return FALSE;
3290     }
3291   
3292   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3293     {
3294       _DBUS_SET_OOM (error);
3295       goto out;
3296     }
3297   
3298   i = 0;
3299   argv[i] = "dbus-launch";
3300   ++i;
3301   argv[i] = "--autolaunch";
3302   ++i;
3303   argv[i] = _dbus_string_get_data (&uuid);
3304   ++i;
3305   argv[i] = "--binary-syntax";
3306   ++i;
3307   argv[i] = "--close-stderr";
3308   ++i;
3309   argv[i] = NULL;
3310   ++i;
3311
3312   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3313   
3314   orig_len = _dbus_string_get_length (address);
3315   
3316 #define READ_END        0
3317 #define WRITE_END       1
3318   if (pipe (address_pipe) < 0)
3319     {
3320       dbus_set_error (error, _dbus_error_from_errno (errno),
3321                       "Failed to create a pipe: %s",
3322                       _dbus_strerror (errno));
3323       _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
3324                      _dbus_strerror (errno));
3325       goto out;
3326     }
3327   if (pipe (errors_pipe) < 0)
3328     {
3329       dbus_set_error (error, _dbus_error_from_errno (errno),
3330                       "Failed to create a pipe: %s",
3331                       _dbus_strerror (errno));
3332       _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
3333                      _dbus_strerror (errno));
3334       goto out;
3335     }
3336
3337   pid = fork ();
3338   if (pid < 0)
3339     {
3340       dbus_set_error (error, _dbus_error_from_errno (errno),
3341                       "Failed to fork(): %s",
3342                       _dbus_strerror (errno));
3343       _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
3344                      _dbus_strerror (errno));
3345       goto out;
3346     }
3347
3348   if (pid == 0)
3349     {
3350       /* child process */
3351       int maxfds;
3352       int fd;
3353
3354       fd = open ("/dev/null", O_RDWR);
3355       if (fd == -1)
3356         /* huh?! can't open /dev/null? */
3357         _exit (1);
3358
3359       _dbus_verbose ("/dev/null fd %d opened\n", fd);
3360       
3361       /* set-up stdXXX */
3362       close (address_pipe[READ_END]);
3363       close (errors_pipe[READ_END]);
3364       close (0);                /* close stdin */
3365       close (1);                /* close stdout */
3366       close (2);                /* close stderr */
3367
3368       if (dup2 (fd, 0) == -1)
3369         _exit (1);
3370       if (dup2 (address_pipe[WRITE_END], 1) == -1)
3371         _exit (1);
3372       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3373         _exit (1);
3374
3375       maxfds = sysconf (_SC_OPEN_MAX);
3376       /* Pick something reasonable if for some reason sysconf
3377        * says unlimited.
3378        */
3379       if (maxfds < 0)
3380         maxfds = 1024;
3381       /* close all inherited fds */
3382       for (i = 3; i < maxfds; i++)
3383         close (i);
3384
3385       execv (DBUS_BINDIR "/dbus-launch", argv);
3386
3387       /* failed, try searching PATH */
3388       execvp ("dbus-launch", argv);
3389
3390       /* still nothing, we failed */
3391       _exit (1);
3392     }
3393
3394   /* parent process */
3395   close (address_pipe[WRITE_END]);
3396   close (errors_pipe[WRITE_END]);
3397   address_pipe[WRITE_END] = -1;
3398   errors_pipe[WRITE_END] = -1;
3399
3400   ret = 0;
3401   do 
3402     {
3403       ret = _dbus_read (address_pipe[READ_END], address, 1024);
3404     }
3405   while (ret > 0);
3406
3407   /* reap the child process to avoid it lingering as zombie */
3408   do
3409     {
3410       ret = waitpid (pid, &status, 0);
3411     }
3412   while (ret == -1 && errno == EINTR);
3413
3414   /* We succeeded if the process exited with status 0 and
3415      anything was read */
3416   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
3417       _dbus_string_get_length (address) == orig_len)
3418     {
3419       /* The process ended with error */
3420       DBusString error_message;
3421       _dbus_string_init (&error_message);
3422       ret = 0;
3423       do
3424         {
3425           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3426         }
3427       while (ret > 0);
3428
3429       _dbus_string_set_length (address, orig_len);
3430       if (_dbus_string_get_length (&error_message) > 0)
3431         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3432                         "dbus-launch failed to autolaunch D-Bus session: %s",
3433                         _dbus_string_get_data (&error_message));
3434       else
3435         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3436                         "Failed to execute dbus-launch to autolaunch D-Bus session");
3437       goto out;
3438     }
3439
3440   retval = TRUE;
3441   
3442  out:
3443   if (retval)
3444     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3445   else
3446     _DBUS_ASSERT_ERROR_IS_SET (error);
3447
3448   if (address_pipe[0] != -1)
3449     close (address_pipe[0]);
3450   if (address_pipe[1] != -1)
3451     close (address_pipe[1]);
3452   if (errors_pipe[0] != -1)
3453     close (errors_pipe[0]);
3454   if (errors_pipe[1] != -1)
3455     close (errors_pipe[1]);
3456
3457   _dbus_string_free (&uuid);
3458   return retval;
3459 }
3460
3461 /**
3462  * Reads the uuid of the machine we're running on from
3463  * the dbus configuration. Optionally try to create it
3464  * (only root can do this usually).
3465  *
3466  * On UNIX, reads a file that gets created by dbus-uuidgen
3467  * in a post-install script. On Windows, if there's a standard
3468  * machine uuid we could just use that, but I can't find one
3469  * with the right properties (the hardware profile guid can change
3470  * without rebooting I believe). If there's no standard one
3471  * we might want to use the registry instead of a file for
3472  * this, and I'm not sure how we'd ensure the uuid gets created.
3473  *
3474  * @param machine_id guid to init with the machine's uuid
3475  * @param create_if_not_found try to create the uuid if it doesn't exist
3476  * @param error the error return
3477  * @returns #FALSE if the error is set
3478  */
3479 dbus_bool_t
3480 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
3481                                dbus_bool_t create_if_not_found,
3482                                DBusError  *error)
3483 {
3484   DBusString filename;
3485   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3486   return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3487 }
3488
3489 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3490 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3491
3492
3493 /**
3494  * Returns the standard directories for a session bus to look for service 
3495  * activation files 
3496  *
3497  * On UNIX this should be the standard xdg freedesktop.org data directories:
3498  *
3499  * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3500  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3501  *
3502  * and
3503  *
3504  * DBUS_DATADIR
3505  *
3506  * @param dirs the directory list we are returning
3507  * @returns #FALSE on OOM 
3508  */
3509
3510 dbus_bool_t 
3511 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3512 {
3513   const char *xdg_data_home;
3514   const char *xdg_data_dirs;
3515   DBusString servicedir_path;
3516
3517   if (!_dbus_string_init (&servicedir_path))
3518     return FALSE;
3519
3520   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3521   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3522
3523   if (xdg_data_dirs != NULL)
3524     {
3525       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3526         goto oom;
3527
3528       if (!_dbus_string_append (&servicedir_path, ":"))
3529         goto oom;
3530     }
3531   else
3532     {
3533       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3534         goto oom;
3535     }
3536
3537   /* 
3538    * add configured datadir to defaults
3539    * this may be the same as an xdg dir
3540    * however the config parser should take 
3541    * care of duplicates 
3542    */
3543   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3544         goto oom;
3545
3546   if (xdg_data_home != NULL)
3547     {
3548       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3549         goto oom;
3550     }
3551   else
3552     {
3553       const DBusString *homedir;
3554       DBusString local_share;
3555
3556       if (!_dbus_homedir_from_current_process (&homedir))
3557         goto oom;
3558        
3559       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3560         goto oom;
3561
3562       _dbus_string_init_const (&local_share, "/.local/share");
3563       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3564         goto oom;
3565     }
3566
3567   if (!_dbus_split_paths_and_append (&servicedir_path, 
3568                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR, 
3569                                      dirs))
3570     goto oom;
3571
3572   _dbus_string_free (&servicedir_path);  
3573   return TRUE;
3574
3575  oom:
3576   _dbus_string_free (&servicedir_path);
3577   return FALSE;
3578 }
3579
3580
3581 /**
3582  * Returns the standard directories for a system bus to look for service 
3583  * activation files 
3584  *
3585  * On UNIX this should be the standard xdg freedesktop.org data directories:
3586  *
3587  * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3588  *
3589  * and
3590  *
3591  * DBUS_DATADIR
3592  *
3593  * On Windows there is no system bus and this function can return nothing.
3594  *
3595  * @param dirs the directory list we are returning
3596  * @returns #FALSE on OOM 
3597  */
3598
3599 dbus_bool_t 
3600 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3601 {
3602   const char *xdg_data_dirs;
3603   DBusString servicedir_path;
3604
3605   if (!_dbus_string_init (&servicedir_path))
3606     return FALSE;
3607
3608   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3609
3610   if (xdg_data_dirs != NULL)
3611     {
3612       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3613         goto oom;
3614
3615       if (!_dbus_string_append (&servicedir_path, ":"))
3616         goto oom;
3617     }
3618   else
3619     {
3620       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3621         goto oom;
3622     }
3623
3624   /* 
3625    * add configured datadir to defaults
3626    * this may be the same as an xdg dir
3627    * however the config parser should take 
3628    * care of duplicates 
3629    */
3630   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3631         goto oom;
3632
3633   if (!_dbus_split_paths_and_append (&servicedir_path, 
3634                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR, 
3635                                      dirs))
3636     goto oom;
3637
3638   _dbus_string_free (&servicedir_path);  
3639   return TRUE;
3640
3641  oom:
3642   _dbus_string_free (&servicedir_path);
3643   return FALSE;
3644 }
3645
3646 /**
3647  * Append the absolute path of the system.conf file
3648  * (there is no system bus on Windows so this can just
3649  * return FALSE and print a warning or something)
3650  * 
3651  * @param str the string to append to
3652  * @returns #FALSE if no memory
3653  */
3654 dbus_bool_t
3655 _dbus_append_system_config_file (DBusString *str)
3656 {
3657   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3658 }
3659
3660 /**
3661  * Append the absolute path of the session.conf file.
3662  * 
3663  * @param str the string to append to
3664  * @returns #FALSE if no memory
3665  */
3666 dbus_bool_t
3667 _dbus_append_session_config_file (DBusString *str)
3668 {
3669   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3670 }
3671
3672 /**
3673  * Called when the bus daemon is signaled to reload its configuration; any
3674  * caches should be nuked. Of course any caches that need explicit reload
3675  * are probably broken, but c'est la vie.
3676  *
3677  * 
3678  */
3679 void
3680 _dbus_flush_caches (void)
3681 {
3682   _dbus_user_database_flush_system ();
3683 }
3684
3685 /**
3686  * Appends the directory in which a keyring for the given credentials
3687  * should be stored.  The credentials should have either a Windows or
3688  * UNIX user in them.  The directory should be an absolute path.
3689  *
3690  * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3691  * be something else, since the dotfile convention is not normal on Windows.
3692  * 
3693  * @param directory string to append directory to
3694  * @param credentials credentials the directory should be for
3695  *  
3696  * @returns #FALSE on no memory
3697  */
3698 dbus_bool_t
3699 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
3700                                                 DBusCredentials *credentials)
3701 {
3702   DBusString homedir;
3703   DBusString dotdir;
3704   dbus_uid_t uid;
3705   
3706   _dbus_assert (credentials != NULL);
3707   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3708   
3709   if (!_dbus_string_init (&homedir))
3710     return FALSE;
3711
3712   uid = _dbus_credentials_get_unix_uid (credentials);
3713   _dbus_assert (uid != DBUS_UID_UNSET);
3714
3715   if (!_dbus_homedir_from_uid (uid, &homedir))
3716     goto failed;
3717   
3718 #ifdef DBUS_BUILD_TESTS
3719   {
3720     const char *override;
3721     
3722     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3723     if (override != NULL && *override != '\0')
3724       {
3725         _dbus_string_set_length (&homedir, 0);
3726         if (!_dbus_string_append (&homedir, override))
3727           goto failed;
3728
3729         _dbus_verbose ("Using fake homedir for testing: %s\n",
3730                        _dbus_string_get_const_data (&homedir));
3731       }
3732     else
3733       {
3734         static dbus_bool_t already_warned = FALSE;
3735         if (!already_warned)
3736           {
3737             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3738             already_warned = TRUE;
3739           }
3740       }
3741   }
3742 #endif
3743
3744   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3745   if (!_dbus_concat_dir_and_file (&homedir,
3746                                   &dotdir))
3747     goto failed;
3748   
3749   if (!_dbus_string_copy (&homedir, 0,
3750                           directory, _dbus_string_get_length (directory))) {
3751     goto failed;
3752   }
3753
3754   _dbus_string_free (&homedir);
3755   return TRUE;
3756   
3757  failed: 
3758   _dbus_string_free (&homedir);
3759   return FALSE;
3760 }
3761
3762
3763 /**
3764  * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3765  * for Winsock so is abstracted)
3766  *
3767  * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3768  */
3769 dbus_bool_t
3770 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3771 {
3772   return errno == EAGAIN || errno == EWOULDBLOCK;
3773 }
3774
3775 /**
3776  *  Checks whether file descriptors may be passed via the socket
3777  *
3778  *  @param fd the socket
3779  *  @return TRUE when fd passing over this socket is supported
3780  *
3781  */
3782 dbus_bool_t
3783 _dbus_socket_can_pass_unix_fd(int fd) {
3784
3785 #ifdef SCM_RIGHTS
3786   union {
3787     struct sockaddr sa;
3788     struct sockaddr_storage storage;
3789     struct sockaddr_un un;
3790   } sa_buf;
3791
3792   socklen_t sa_len = sizeof(sa_buf);
3793
3794   _DBUS_ZERO(sa_buf);
3795
3796   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3797     return FALSE;
3798
3799   return sa_buf.sa.sa_family == AF_UNIX;
3800
3801 #else
3802   return FALSE;
3803
3804 #endif
3805 }
3806
3807 /* tests in dbus-sysdeps-util.c */