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