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)
4 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
7 * Licensed under the Academic Free License version 2.1
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.
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.
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
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"
39 #include <sys/types.h>
46 #include <sys/socket.h>
55 #include <netinet/in.h>
58 #include <arpa/inet.h>
72 #ifdef HAVE_GETPEERUCRED
80 #include "sd-daemon.h"
87 #define AI_ADDRCONFIG 0
90 #ifndef HAVE_SOCKLEN_T
94 #if defined (__sun) || defined (__sun__)
96 * CMS_SPACE etc. definitions for Solaris < 10, based on
97 * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
99 * http://wiki.opencsw.org/porting-faq#toc10
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.)
107 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
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))
116 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
121 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
127 _dbus_open_socket (int *fd_p,
134 dbus_bool_t cloexec_done;
136 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
137 cloexec_done = *fd_p >= 0;
139 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
140 if (*fd_p < 0 && errno == EINVAL)
143 *fd_p = socket (domain, type, protocol);
152 _dbus_fd_set_close_on_exec(*fd_p);
155 _dbus_verbose ("socket fd %d opened\n", *fd_p);
160 dbus_set_error(error,
161 _dbus_error_from_errno (errno),
162 "Failed to open socket: %s",
163 _dbus_strerror (errno));
169 * Opens a UNIX domain socket (as in the socket() call).
170 * Does not bind the socket.
172 * This will set FD_CLOEXEC for the socket returned
174 * @param fd return location for socket descriptor
175 * @param error return location for an error
176 * @returns #FALSE if error is set
179 _dbus_open_unix_socket (int *fd,
182 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
186 * Closes a socket. Should not be used on non-socket
187 * file descriptors or handles.
189 * @param fd the socket
190 * @param error return location for an error
191 * @returns #FALSE if error is set
194 _dbus_close_socket (int fd,
197 return _dbus_close (fd, error);
201 * Like _dbus_read(), but only works on sockets so is
202 * available on Windows.
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
210 _dbus_read_socket (int fd,
214 return _dbus_read (fd, buffer, count);
218 * Like _dbus_write(), but only supports sockets
219 * and is thus available on Windows.
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
228 _dbus_write_socket (int fd,
229 const DBusString *buffer,
233 #if HAVE_DECL_MSG_NOSIGNAL
237 data = _dbus_string_get_const_data_len (buffer, start, len);
241 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
243 if (bytes_written < 0 && errno == EINTR)
246 return bytes_written;
249 return _dbus_write (fd, buffer, start, len);
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.
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
266 _dbus_read_socket_with_unix_fds (int fd,
271 #ifndef HAVE_UNIX_FD_PASSING
274 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
286 _dbus_assert (count >= 0);
287 _dbus_assert (*n_fds >= 0);
289 start = _dbus_string_get_length (buffer);
291 if (!_dbus_string_lengthen (buffer, count))
298 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
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));
311 /* It's probably safe to assume that systems with SCM_RIGHTS also
313 m.msg_control = alloca(m.msg_controllen);
314 memset(m.msg_control, 0, m.msg_controllen);
318 bytes_read = recvmsg(fd, &m, 0
319 #ifdef MSG_CMSG_CLOEXEC
330 /* put length back (note that this doesn't actually realloc anything) */
331 _dbus_string_set_length (buffer, start);
338 dbus_bool_t found = FALSE;
340 if (m.msg_flags & MSG_CTRUNC)
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
348 _dbus_string_set_length (buffer, start);
352 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
353 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
357 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
358 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
360 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
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]);
375 /* put length back (doesn't actually realloc) */
376 _dbus_string_set_length (buffer, start + bytes_read);
380 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
389 _dbus_write_socket_with_unix_fds(int fd,
390 const DBusString *buffer,
396 #ifndef HAVE_UNIX_FD_PASSING
403 return _dbus_write_socket(fd, buffer, start, len);
405 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
410 _dbus_write_socket_with_unix_fds_two(int fd,
411 const DBusString *buffer1,
414 const DBusString *buffer2,
420 #ifndef HAVE_UNIX_FD_PASSING
427 return _dbus_write_socket_two(fd,
428 buffer1, start1, len1,
429 buffer2, start2, len2);
437 _dbus_assert (len1 >= 0);
438 _dbus_assert (len2 >= 0);
439 _dbus_assert (n_fds >= 0);
442 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
443 iov[0].iov_len = len1;
447 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
448 iov[1].iov_len = len2;
453 m.msg_iovlen = buffer2 ? 2 : 1;
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);
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));
470 bytes_written = sendmsg (fd, &m, 0
471 #if HAVE_DECL_MSG_NOSIGNAL
476 if (bytes_written < 0 && errno == EINTR)
480 if (bytes_written > 0)
481 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
484 return bytes_written;
489 * Like _dbus_write_two() but only works on sockets and is thus
490 * available on Windows.
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
502 _dbus_write_socket_two (int fd,
503 const DBusString *buffer1,
506 const DBusString *buffer2,
510 #if HAVE_DECL_MSG_NOSIGNAL
511 struct iovec vectors[2];
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);
523 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
526 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
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;
541 m.msg_iovlen = data2 ? 2 : 1;
545 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
547 if (bytes_written < 0 && errno == EINTR)
550 return bytes_written;
553 return _dbus_write_two (fd, buffer1, start1, len1,
554 buffer2, start2, len2);
559 _dbus_socket_is_invalid (int fd)
561 return fd < 0 ? TRUE : FALSE;
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.
572 * Unlike _dbus_read_socket(), _dbus_read() is not available
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
589 _dbus_assert (count >= 0);
591 start = _dbus_string_get_length (buffer);
593 if (!_dbus_string_lengthen (buffer, count))
599 data = _dbus_string_get_data_len (buffer, start, count);
603 bytes_read = read (fd, data, count);
611 /* put length back (note that this doesn't actually realloc anything) */
612 _dbus_string_set_length (buffer, start);
618 /* put length back (doesn't actually realloc) */
619 _dbus_string_set_length (buffer, start + bytes_read);
623 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
631 * Thin wrapper around the write() system call that writes a part of a
632 * DBusString and handles EINTR for you.
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
642 const DBusString *buffer,
649 data = _dbus_string_get_const_data_len (buffer, start, len);
653 bytes_written = write (fd, data, len);
655 if (bytes_written < 0 && errno == EINTR)
659 if (bytes_written > 0)
660 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
663 return bytes_written;
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.
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
687 _dbus_write_two (int fd,
688 const DBusString *buffer1,
691 const DBusString *buffer2,
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);
703 struct iovec vectors[2];
708 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
711 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
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;
726 bytes_written = writev (fd,
730 if (bytes_written < 0 && errno == EINTR)
733 return bytes_written;
735 #else /* HAVE_WRITEV */
739 ret1 = _dbus_write (fd, buffer1, start1, len1);
740 if (ret1 == len1 && buffer2 != NULL)
742 ret2 = _dbus_write (fd, buffer2, start2, len2);
744 ret2 = 0; /* we can't report an error as the first write was OK */
751 #endif /* !HAVE_WRITEV */
754 #define _DBUS_MAX_SUN_PATH_LENGTH 99
757 * @def _DBUS_MAX_SUN_PATH_LENGTH
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.
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.
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
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.
778 * This will set FD_CLOEXEC for the socket returned.
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
786 _dbus_connect_unix_socket (const char *path,
787 dbus_bool_t abstract,
792 struct sockaddr_un addr;
794 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
796 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
800 if (!_dbus_open_unix_socket (&fd, error))
802 _DBUS_ASSERT_ERROR_IS_SET(error);
805 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
808 addr.sun_family = AF_UNIX;
809 path_len = strlen (path);
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 */
817 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
819 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
820 "Abstract socket name too long\n");
821 _dbus_close (fd, NULL);
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);
832 #endif /* ! HAVE_ABSTRACT_SOCKETS */
836 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
838 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
839 "Socket name too long\n");
840 _dbus_close (fd, NULL);
844 strncpy (addr.sun_path, path, path_len);
847 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
849 dbus_set_error (error,
850 _dbus_error_from_errno (errno),
851 "Failed to connect to socket %s: %s",
852 path, _dbus_strerror (errno));
854 _dbus_close (fd, NULL);
858 if (!_dbus_set_fd_nonblocking (fd, error))
860 _DBUS_ASSERT_ERROR_IS_SET (error);
862 _dbus_close (fd, NULL);
870 * Creates a UNIX domain socket and connects it to the specified
871 * process to execute.
873 * This will set FD_CLOEXEC for the socket returned.
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
882 _dbus_connect_exec (const char *path,
889 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
891 _dbus_verbose ("connecting to process %s\n", path);
893 if (socketpair (AF_UNIX, SOCK_STREAM
899 dbus_set_error (error,
900 _dbus_error_from_errno (errno),
901 "Failed to create socket pair: %s",
902 _dbus_strerror (errno));
906 _dbus_fd_set_close_on_exec (fds[0]);
907 _dbus_fd_set_close_on_exec (fds[1]);
912 dbus_set_error (error,
913 _dbus_error_from_errno (errno),
914 "Failed to fork() to call %s: %s",
915 path, _dbus_strerror (errno));
926 dup2 (fds[1], STDIN_FILENO);
927 dup2 (fds[1], STDOUT_FILENO);
929 if (fds[1] != STDIN_FILENO &&
930 fds[1] != STDOUT_FILENO)
933 /* Inherit STDERR and the controlling terminal from the
940 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
948 if (!_dbus_set_fd_nonblocking (fds[0], error))
950 _DBUS_ASSERT_ERROR_IS_SET (error);
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.
965 * @param fd socket on which to change the #LOCAL_CREDS flag.
966 * @param on whether to enable or disable the #LOCAL_CREDS flag.
969 _dbus_set_local_creds (int fd, dbus_bool_t on)
971 dbus_bool_t retval = TRUE;
973 #if defined(HAVE_CMSGCRED)
974 /* NOOP just to make sure only one codepath is used
975 * and to prefer CMSGCRED
977 #elif defined(LOCAL_CREDS)
978 int val = on ? 1 : 0;
979 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
981 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
985 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
986 on ? "enabled" : "disabled", fd);
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.
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.
1002 * This will set FD_CLOEXEC for the socket returned
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
1010 _dbus_listen_unix_socket (const char *path,
1011 dbus_bool_t abstract,
1015 struct sockaddr_un addr;
1017 unsigned int reuseaddr;
1019 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1021 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1024 if (!_dbus_open_unix_socket (&listen_fd, error))
1026 _DBUS_ASSERT_ERROR_IS_SET(error);
1029 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1032 addr.sun_family = AF_UNIX;
1033 path_len = strlen (path);
1037 #ifdef HAVE_ABSTRACT_SOCKETS
1038 /* remember that abstract names aren't nul-terminated so we rely
1039 * on sun_path being filled in with zeroes above.
1041 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1042 path_len++; /* Account for the extra nul byte added to the start of sun_path */
1044 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1046 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1047 "Abstract socket name too long\n");
1048 _dbus_close (listen_fd, NULL);
1052 strncpy (&addr.sun_path[1], path, path_len);
1053 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1054 #else /* HAVE_ABSTRACT_SOCKETS */
1055 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
1056 "Operating system does not support abstract socket namespace\n");
1057 _dbus_close (listen_fd, NULL);
1059 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1063 /* Discussed security implications of this with Nalin,
1064 * and we couldn't think of where it would kick our ass, but
1065 * it still seems a bit sucky. It also has non-security suckage;
1066 * really we'd prefer to exit if the socket is already in use.
1067 * But there doesn't seem to be a good way to do this.
1069 * Just to be extra careful, I threw in the stat() - clearly
1070 * the stat() can't *fix* any security issue, but it at least
1071 * avoids inadvertent/accidental data loss.
1076 if (stat (path, &sb) == 0 &&
1077 S_ISSOCK (sb.st_mode))
1081 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1083 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1084 "Abstract socket name too long\n");
1085 _dbus_close (listen_fd, NULL);
1089 strncpy (addr.sun_path, path, path_len);
1093 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1095 _dbus_warn ("Failed to set socket option\"%s\": %s",
1096 path, _dbus_strerror (errno));
1099 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1101 dbus_set_error (error, _dbus_error_from_errno (errno),
1102 "Failed to bind socket \"%s\": %s",
1103 path, _dbus_strerror (errno));
1104 _dbus_close (listen_fd, NULL);
1108 if (listen (listen_fd, 30 /* backlog */) < 0)
1110 dbus_set_error (error, _dbus_error_from_errno (errno),
1111 "Failed to listen on socket \"%s\": %s",
1112 path, _dbus_strerror (errno));
1113 _dbus_close (listen_fd, NULL);
1117 if (!_dbus_set_local_creds (listen_fd, TRUE))
1119 dbus_set_error (error, _dbus_error_from_errno (errno),
1120 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1121 path, _dbus_strerror (errno));
1126 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1128 _DBUS_ASSERT_ERROR_IS_SET (error);
1129 _dbus_close (listen_fd, NULL);
1133 /* Try opening up the permissions, but if we can't, just go ahead
1134 * and continue, maybe it will be good enough.
1136 if (!abstract && chmod (path, 0777) < 0)
1137 _dbus_warn ("Could not set mode 0777 on socket %s\n",
1144 * Acquires one or more sockets passed in from systemd. The sockets
1145 * are set to be nonblocking.
1147 * This will set FD_CLOEXEC for the sockets returned.
1149 * @oaram fds the file descriptors
1150 * @param error return location for errors
1151 * @returns the number of file descriptors
1154 _dbus_listen_systemd_sockets (int **fds,
1161 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1163 n = sd_listen_fds (TRUE);
1166 dbus_set_error (error, _dbus_error_from_errno (-n),
1167 "Failed to acquire systemd socket: %s",
1168 _dbus_strerror (-n));
1174 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1175 "No socket received.");
1179 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1181 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1184 dbus_set_error (error, _dbus_error_from_errno (-r),
1185 "Failed to verify systemd socket type: %s",
1186 _dbus_strerror (-r));
1192 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1193 "Passed socket has wrong type.");
1198 /* OK, the file descriptors are all good, so let's take posession of
1201 new_fds = dbus_new (int, n);
1204 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1205 "Failed to allocate file handle array.");
1209 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1211 if (!_dbus_set_local_creds (fd, TRUE))
1213 dbus_set_error (error, _dbus_error_from_errno (errno),
1214 "Failed to enable LOCAL_CREDS on systemd socket: %s",
1215 _dbus_strerror (errno));
1219 if (!_dbus_set_fd_nonblocking (fd, error))
1221 _DBUS_ASSERT_ERROR_IS_SET (error);
1225 new_fds[fd - SD_LISTEN_FDS_START] = fd;
1233 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1235 _dbus_close (fd, NULL);
1238 dbus_free (new_fds);
1243 * Creates a socket and connects to a socket at the given host
1244 * and port. The connection fd is returned, and is set up as
1247 * This will set FD_CLOEXEC for the socket returned
1249 * @param host the host name to connect to
1250 * @param port the port to connect to
1251 * @param family the address family to listen on, NULL for all
1252 * @param error return location for error code
1253 * @returns connection file descriptor or -1 on error
1256 _dbus_connect_tcp_socket (const char *host,
1261 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1265 _dbus_connect_tcp_socket_with_nonce (const char *host,
1268 const char *noncefile,
1271 int saved_errno = 0;
1273 struct addrinfo hints;
1274 struct addrinfo *ai, *tmp;
1276 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1281 hints.ai_family = AF_UNSPEC;
1282 else if (!strcmp(family, "ipv4"))
1283 hints.ai_family = AF_INET;
1284 else if (!strcmp(family, "ipv6"))
1285 hints.ai_family = AF_INET6;
1288 dbus_set_error (error,
1289 DBUS_ERROR_BAD_ADDRESS,
1290 "Unknown address family %s", family);
1293 hints.ai_protocol = IPPROTO_TCP;
1294 hints.ai_socktype = SOCK_STREAM;
1295 hints.ai_flags = AI_ADDRCONFIG;
1297 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1299 dbus_set_error (error,
1300 _dbus_error_from_errno (errno),
1301 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1302 host, port, gai_strerror(res), res);
1309 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1312 _DBUS_ASSERT_ERROR_IS_SET(error);
1315 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1317 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1319 saved_errno = errno;
1320 _dbus_close(fd, NULL);
1332 dbus_set_error (error,
1333 _dbus_error_from_errno (saved_errno),
1334 "Failed to connect to socket \"%s:%s\" %s",
1335 host, port, _dbus_strerror(saved_errno));
1339 if (noncefile != NULL)
1341 DBusString noncefileStr;
1343 _dbus_string_init_const (&noncefileStr, noncefile);
1344 ret = _dbus_send_nonce (fd, &noncefileStr, error);
1345 _dbus_string_free (&noncefileStr);
1349 _dbus_close (fd, NULL);
1354 if (!_dbus_set_fd_nonblocking (fd, error))
1356 _dbus_close (fd, NULL);
1364 * Creates a socket and binds it to the given path, then listens on
1365 * the socket. The socket is set to be nonblocking. In case of port=0
1366 * a random free port is used and returned in the port parameter.
1367 * If inaddr_any is specified, the hostname is ignored.
1369 * This will set FD_CLOEXEC for the socket returned
1371 * @param host the host name to listen on
1372 * @param port the port to listen on, if zero a free port will be used
1373 * @param family the address family to listen on, NULL for all
1374 * @param retport string to return the actual port listened on
1375 * @param fds_p location to store returned file descriptors
1376 * @param error return location for errors
1377 * @returns the number of listening file descriptors or -1 on error
1380 _dbus_listen_tcp_socket (const char *host,
1383 DBusString *retport,
1388 int nlisten_fd = 0, *listen_fd = NULL, res, i;
1389 struct addrinfo hints;
1390 struct addrinfo *ai, *tmp;
1391 unsigned int reuseaddr;
1394 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1399 hints.ai_family = AF_UNSPEC;
1400 else if (!strcmp(family, "ipv4"))
1401 hints.ai_family = AF_INET;
1402 else if (!strcmp(family, "ipv6"))
1403 hints.ai_family = AF_INET6;
1406 dbus_set_error (error,
1407 DBUS_ERROR_BAD_ADDRESS,
1408 "Unknown address family %s", family);
1412 hints.ai_protocol = IPPROTO_TCP;
1413 hints.ai_socktype = SOCK_STREAM;
1414 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1416 redo_lookup_with_port:
1418 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1420 dbus_set_error (error,
1421 _dbus_error_from_errno (errno),
1422 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1423 host ? host : "*", port, gai_strerror(res), res);
1430 int fd = -1, *newlisten_fd;
1431 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1433 _DBUS_ASSERT_ERROR_IS_SET(error);
1436 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1439 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1441 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1442 host ? host : "*", port, _dbus_strerror (errno));
1445 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1447 saved_errno = errno;
1448 _dbus_close(fd, NULL);
1449 if (saved_errno == EADDRINUSE)
1451 /* Depending on kernel policy, it may or may not
1452 be neccessary to bind to both IPv4 & 6 addresses
1453 so ignore EADDRINUSE here */
1457 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1458 "Failed to bind socket \"%s:%s\": %s",
1459 host ? host : "*", port, _dbus_strerror (saved_errno));
1463 if (listen (fd, 30 /* backlog */) < 0)
1465 saved_errno = errno;
1466 _dbus_close (fd, NULL);
1467 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1468 "Failed to listen on socket \"%s:%s\": %s",
1469 host ? host : "*", port, _dbus_strerror (saved_errno));
1473 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1476 saved_errno = errno;
1477 _dbus_close (fd, NULL);
1478 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1479 "Failed to allocate file handle array: %s",
1480 _dbus_strerror (saved_errno));
1483 listen_fd = newlisten_fd;
1484 listen_fd[nlisten_fd] = fd;
1487 if (!_dbus_string_get_length(retport))
1489 /* If the user didn't specify a port, or used 0, then
1490 the kernel chooses a port. After the first address
1491 is bound to, we need to force all remaining addresses
1492 to use the same port */
1493 if (!port || !strcmp(port, "0"))
1496 struct sockaddr_storage addr;
1500 addrlen = sizeof(addr);
1501 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1504 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1505 portbuf, sizeof(portbuf),
1506 NI_NUMERICHOST)) != 0)
1508 dbus_set_error (error, _dbus_error_from_errno (errno),
1509 "Failed to resolve port \"%s:%s\": %s (%s)",
1510 host ? host : "*", port, gai_strerror(res), res);
1513 if (!_dbus_string_append(retport, portbuf))
1515 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1519 /* Release current address list & redo lookup */
1520 port = _dbus_string_get_const_data(retport);
1522 goto redo_lookup_with_port;
1526 if (!_dbus_string_append(retport, port))
1528 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1542 dbus_set_error (error, _dbus_error_from_errno (errno),
1543 "Failed to bind socket \"%s:%s\": %s",
1544 host ? host : "*", port, _dbus_strerror (errno));
1548 for (i = 0 ; i < nlisten_fd ; i++)
1550 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1563 for (i = 0 ; i < nlisten_fd ; i++)
1564 _dbus_close(listen_fd[i], NULL);
1565 dbus_free(listen_fd);
1570 write_credentials_byte (int server_fd,
1574 char buf[1] = { '\0' };
1575 #if defined(HAVE_CMSGCRED)
1578 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1589 msg.msg_control = (caddr_t) &cmsg;
1590 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1592 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1593 cmsg.hdr.cmsg_level = SOL_SOCKET;
1594 cmsg.hdr.cmsg_type = SCM_CREDS;
1597 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1601 #if defined(HAVE_CMSGCRED)
1602 bytes_written = sendmsg (server_fd, &msg, 0
1603 #if HAVE_DECL_MSG_NOSIGNAL
1608 bytes_written = send (server_fd, buf, 1, 0
1609 #if HAVE_DECL_MSG_NOSIGNAL
1615 if (bytes_written < 0 && errno == EINTR)
1618 if (bytes_written < 0)
1620 dbus_set_error (error, _dbus_error_from_errno (errno),
1621 "Failed to write credentials byte: %s",
1622 _dbus_strerror (errno));
1625 else if (bytes_written == 0)
1627 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1628 "wrote zero bytes writing credentials byte");
1633 _dbus_assert (bytes_written == 1);
1634 _dbus_verbose ("wrote credentials byte\n");
1640 * Reads a single byte which must be nul (an error occurs otherwise),
1641 * and reads unix credentials if available. Clears the credentials
1642 * object, then adds pid/uid if available, so any previous credentials
1643 * stored in the object are lost.
1645 * Return value indicates whether a byte was read, not whether
1646 * we got valid credentials. On some systems, such as Linux,
1647 * reading/writing the byte isn't actually required, but we do it
1648 * anyway just to avoid multiple codepaths.
1650 * Fails if no byte is available, so you must select() first.
1652 * The point of the byte is that on some systems we have to
1653 * use sendmsg()/recvmsg() to transmit credentials.
1655 * @param client_fd the client file descriptor
1656 * @param credentials object to add client credentials to
1657 * @param error location to store error code
1658 * @returns #TRUE on success
1661 _dbus_read_credentials_socket (int client_fd,
1662 DBusCredentials *credentials,
1668 dbus_uid_t uid_read;
1669 dbus_pid_t pid_read;
1672 #ifdef HAVE_CMSGCRED
1675 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1678 #elif defined(LOCAL_CREDS)
1681 struct sockcred cred;
1685 uid_read = DBUS_UID_UNSET;
1686 pid_read = DBUS_PID_UNSET;
1688 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1690 /* The POSIX spec certainly doesn't promise this, but
1691 * we need these assertions to fail as soon as we're wrong about
1692 * it so we can do the porting fixups
1694 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1695 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1696 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1698 _dbus_credentials_clear (credentials);
1700 /* Systems supporting LOCAL_CREDS are configured to have this feature
1701 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1702 * the connection. Therefore, the received message must carry the
1703 * credentials information without doing anything special.
1706 iov.iov_base = &buf;
1713 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1715 msg.msg_control = (caddr_t) &cmsg;
1716 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1720 bytes_read = recvmsg (client_fd, &msg, 0);
1727 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1728 * normally only call read_credentials if the socket was ready
1732 dbus_set_error (error, _dbus_error_from_errno (errno),
1733 "Failed to read credentials byte: %s",
1734 _dbus_strerror (errno));
1737 else if (bytes_read == 0)
1739 /* this should not happen unless we are using recvmsg wrong,
1740 * so is essentially here for paranoia
1742 dbus_set_error (error, DBUS_ERROR_FAILED,
1743 "Failed to read credentials byte (zero-length read)");
1746 else if (buf != '\0')
1748 dbus_set_error (error, DBUS_ERROR_FAILED,
1749 "Credentials byte was not nul");
1753 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1754 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1755 || cmsg.hdr.cmsg_type != SCM_CREDS)
1757 dbus_set_error (error, DBUS_ERROR_FAILED,
1758 "Message from recvmsg() was not SCM_CREDS");
1763 _dbus_verbose ("read credentials byte\n");
1768 struct sockpeercred cr;
1772 int cr_len = sizeof (cr);
1774 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1775 cr_len == sizeof (cr))
1782 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1783 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1785 #elif defined(HAVE_CMSGCRED)
1786 struct cmsgcred *cred;
1788 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1789 pid_read = cred->cmcred_pid;
1790 uid_read = cred->cmcred_euid;
1791 #elif defined(LOCAL_CREDS)
1792 pid_read = DBUS_PID_UNSET;
1793 uid_read = cmsg.cred.sc_uid;
1794 /* Since we have already got the credentials from this socket, we can
1795 * disable its LOCAL_CREDS flag if it was ever set. */
1796 _dbus_set_local_creds (client_fd, FALSE);
1797 #elif defined(HAVE_GETPEEREID)
1800 if (getpeereid (client_fd, &euid, &egid) == 0)
1806 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1808 #elif defined(HAVE_GETPEERUCRED)
1809 ucred_t * ucred = NULL;
1810 if (getpeerucred (client_fd, &ucred) == 0)
1812 pid_read = ucred_getpid (ucred);
1813 uid_read = ucred_geteuid (ucred);
1815 /* generate audit session data based on socket ucred */
1816 adt_session_data_t *adth = NULL;
1817 adt_export_data_t *data = NULL;
1819 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1821 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1825 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1827 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1831 size = adt_export_session_data (adth, &data);
1834 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1838 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1842 (void) adt_end_session (adth);
1844 #endif /* HAVE_ADT */
1848 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1852 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1853 _dbus_verbose ("Socket credentials not supported on this OS\n");
1857 _dbus_verbose ("Credentials:"
1858 " pid "DBUS_PID_FORMAT
1859 " uid "DBUS_UID_FORMAT
1864 if (pid_read != DBUS_PID_UNSET)
1866 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1868 _DBUS_SET_OOM (error);
1873 if (uid_read != DBUS_UID_UNSET)
1875 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1877 _DBUS_SET_OOM (error);
1886 * Sends a single nul byte with our UNIX credentials as ancillary
1887 * data. Returns #TRUE if the data was successfully written. On
1888 * systems that don't support sending credentials, just writes a byte,
1889 * doesn't send any credentials. On some systems, such as Linux,
1890 * reading/writing the byte isn't actually required, but we do it
1891 * anyway just to avoid multiple codepaths.
1893 * Fails if no byte can be written, so you must select() first.
1895 * The point of the byte is that on some systems we have to
1896 * use sendmsg()/recvmsg() to transmit credentials.
1898 * @param server_fd file descriptor for connection to server
1899 * @param error return location for error code
1900 * @returns #TRUE if the byte was sent
1903 _dbus_send_credentials_socket (int server_fd,
1906 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1908 if (write_credentials_byte (server_fd, error))
1915 * Accepts a connection on a listening socket.
1916 * Handles EINTR for you.
1918 * This will enable FD_CLOEXEC for the returned socket.
1920 * @param listen_fd the listen file descriptor
1921 * @returns the connection fd of the client, or -1 on error
1924 _dbus_accept (int listen_fd)
1927 struct sockaddr addr;
1930 dbus_bool_t cloexec_done;
1933 addrlen = sizeof (addr);
1938 /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1939 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1940 cloexec_done = client_fd >= 0;
1942 if (client_fd < 0 && errno == ENOSYS)
1945 client_fd = accept (listen_fd, &addr, &addrlen);
1954 _dbus_verbose ("client fd %d accepted\n", client_fd);
1960 _dbus_fd_set_close_on_exec(client_fd);
1967 * Checks to make sure the given directory is
1968 * private to the user
1970 * @param dir the name of the directory
1971 * @param error error return
1972 * @returns #FALSE on failure
1975 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1977 const char *directory;
1980 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1982 directory = _dbus_string_get_const_data (dir);
1984 if (stat (directory, &sb) < 0)
1986 dbus_set_error (error, _dbus_error_from_errno (errno),
1987 "%s", _dbus_strerror (errno));
1992 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1993 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1995 dbus_set_error (error, DBUS_ERROR_FAILED,
1996 "%s directory is not private to the user", directory);
2004 fill_user_info_from_passwd (struct passwd *p,
2008 _dbus_assert (p->pw_name != NULL);
2009 _dbus_assert (p->pw_dir != NULL);
2011 info->uid = p->pw_uid;
2012 info->primary_gid = p->pw_gid;
2013 info->username = _dbus_strdup (p->pw_name);
2014 info->homedir = _dbus_strdup (p->pw_dir);
2016 if (info->username == NULL ||
2017 info->homedir == NULL)
2019 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2027 fill_user_info (DBusUserInfo *info,
2029 const DBusString *username,
2032 const char *username_c;
2034 /* exactly one of username/uid provided */
2035 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2036 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2038 info->uid = DBUS_UID_UNSET;
2039 info->primary_gid = DBUS_GID_UNSET;
2040 info->group_ids = NULL;
2041 info->n_group_ids = 0;
2042 info->username = NULL;
2043 info->homedir = NULL;
2045 if (username != NULL)
2046 username_c = _dbus_string_get_const_data (username);
2050 /* For now assuming that the getpwnam() and getpwuid() flavors
2051 * are always symmetrical, if not we have to add more configure
2055 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2061 struct passwd p_str;
2063 /* retrieve maximum needed size for buf */
2064 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2066 /* sysconf actually returns a long, but everything else expects size_t,
2067 * so just recast here.
2068 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2070 if ((long) buflen <= 0)
2076 buf = dbus_malloc (buflen);
2079 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2084 #ifdef HAVE_POSIX_GETPWNAM_R
2085 if (uid != DBUS_UID_UNSET)
2086 result = getpwuid_r (uid, &p_str, buf, buflen,
2089 result = getpwnam_r (username_c, &p_str, buf, buflen,
2092 if (uid != DBUS_UID_UNSET)
2093 p = getpwuid_r (uid, &p_str, buf, buflen);
2095 p = getpwnam_r (username_c, &p_str, buf, buflen);
2097 #endif /* !HAVE_POSIX_GETPWNAM_R */
2098 //Try a bigger buffer if ERANGE was returned
2099 if (result == ERANGE && buflen < 512 * 1024)
2109 if (result == 0 && p == &p_str)
2111 if (!fill_user_info_from_passwd (p, info, error))
2120 dbus_set_error (error, _dbus_error_from_errno (errno),
2121 "User \"%s\" unknown or no memory to allocate password entry\n",
2122 username_c ? username_c : "???");
2123 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2128 #else /* ! HAVE_GETPWNAM_R */
2130 /* I guess we're screwed on thread safety here */
2133 if (uid != DBUS_UID_UNSET)
2136 p = getpwnam (username_c);
2140 if (!fill_user_info_from_passwd (p, info, error))
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 : "???");
2154 #endif /* ! HAVE_GETPWNAM_R */
2156 /* Fill this in so we can use it to get groups */
2157 username_c = info->username;
2159 #ifdef HAVE_GETGROUPLIST
2164 int initial_buf_count;
2166 initial_buf_count = 17;
2167 buf_count = initial_buf_count;
2168 buf = dbus_new (gid_t, buf_count);
2171 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2175 if (getgrouplist (username_c,
2177 buf, &buf_count) < 0)
2180 /* Presumed cause of negative return code: buf has insufficient
2181 entries to hold the entire group list. The Linux behavior in this
2182 case is to pass back the actual number of groups in buf_count, but
2183 on Mac OS X 10.5, buf_count is unhelpfully left alone.
2184 So as a hack, try to help out a bit by guessing a larger
2185 number of groups, within reason.. might still fail, of course,
2186 but we can at least print a more informative message. I looked up
2187 the "right way" to do this by downloading Apple's own source code
2188 for the "id" command, and it turns out that they use an
2189 undocumented library function getgrouplist_2 (!) which is not
2190 declared in any header in /usr/include (!!). That did not seem
2191 like the way to go here.
2193 if (buf_count == initial_buf_count)
2195 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2197 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2200 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2208 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2212 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2213 username_c, buf_count, buf_count);
2217 dbus_set_error (error,
2218 _dbus_error_from_errno (errno),
2219 "Failed to get groups for username \"%s\" primary GID "
2220 DBUS_GID_FORMAT ": %s\n",
2221 username_c, info->primary_gid,
2222 _dbus_strerror (errno));
2229 info->group_ids = dbus_new (dbus_gid_t, buf_count);
2230 if (info->group_ids == NULL)
2232 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2237 for (i = 0; i < buf_count; ++i)
2238 info->group_ids[i] = buf[i];
2240 info->n_group_ids = buf_count;
2244 #else /* HAVE_GETGROUPLIST */
2246 /* We just get the one group ID */
2247 info->group_ids = dbus_new (dbus_gid_t, 1);
2248 if (info->group_ids == NULL)
2250 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2254 info->n_group_ids = 1;
2256 (info->group_ids)[0] = info->primary_gid;
2258 #endif /* HAVE_GETGROUPLIST */
2260 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2265 _DBUS_ASSERT_ERROR_IS_SET (error);
2270 * Gets user info for the given username.
2272 * @param info user info object to initialize
2273 * @param username the username
2274 * @param error error return
2275 * @returns #TRUE on success
2278 _dbus_user_info_fill (DBusUserInfo *info,
2279 const DBusString *username,
2282 return fill_user_info (info, DBUS_UID_UNSET,
2287 * Gets user info for the given user ID.
2289 * @param info user info object to initialize
2290 * @param uid the user ID
2291 * @param error error return
2292 * @returns #TRUE on success
2295 _dbus_user_info_fill_uid (DBusUserInfo *info,
2299 return fill_user_info (info, uid,
2304 * Adds the credentials of the current process to the
2305 * passed-in credentials object.
2307 * @param credentials credentials to add to
2308 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2311 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2313 /* The POSIX spec certainly doesn't promise this, but
2314 * we need these assertions to fail as soon as we're wrong about
2315 * it so we can do the porting fixups
2317 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2318 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2319 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2321 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2323 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2330 * Append to the string the identity we would like to have when we
2331 * authenticate, on UNIX this is the current process UID and on
2332 * Windows something else, probably a Windows SID string. No escaping
2333 * is required, that is done in dbus-auth.c. The username here
2334 * need not be anything human-readable, it can be the machine-readable
2335 * form i.e. a user id.
2337 * @param str the string to append to
2338 * @returns #FALSE on no memory
2341 _dbus_append_user_from_current_process (DBusString *str)
2343 return _dbus_string_append_uint (str,
2348 * Gets our process ID
2349 * @returns process ID
2358 * @returns process UID
2366 /** Gets our effective UID
2367 * @returns process effective UID
2370 _dbus_geteuid (void)
2376 * The only reason this is separate from _dbus_getpid() is to allow it
2377 * on Windows for logging but not for other purposes.
2379 * @returns process ID to put in log messages
2382 _dbus_pid_for_log (void)
2388 * Gets a UID from a UID string.
2390 * @param uid_str the UID in string form
2391 * @param uid UID to fill in
2392 * @returns #TRUE if successfully filled in UID
2395 _dbus_parse_uid (const DBusString *uid_str,
2401 if (_dbus_string_get_length (uid_str) == 0)
2403 _dbus_verbose ("UID string was zero length\n");
2409 if (!_dbus_string_parse_int (uid_str, 0, &val,
2412 _dbus_verbose ("could not parse string as a UID\n");
2416 if (end != _dbus_string_get_length (uid_str))
2418 _dbus_verbose ("string contained trailing stuff after UID\n");
2428 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2432 * Atomically increments an integer
2434 * @param atomic pointer to the integer to increment
2435 * @returns the value before incrementing
2438 _dbus_atomic_inc (DBusAtomic *atomic)
2441 return __sync_add_and_fetch(&atomic->value, 1)-1;
2444 _DBUS_LOCK (atomic);
2445 res = atomic->value;
2447 _DBUS_UNLOCK (atomic);
2453 * Atomically decrement an integer
2455 * @param atomic pointer to the integer to decrement
2456 * @returns the value before decrementing
2459 _dbus_atomic_dec (DBusAtomic *atomic)
2462 return __sync_sub_and_fetch(&atomic->value, 1)+1;
2466 _DBUS_LOCK (atomic);
2467 res = atomic->value;
2469 _DBUS_UNLOCK (atomic);
2475 * Atomically get the value of an integer. It may change at any time
2476 * thereafter, so this is mostly only useful for assertions.
2478 * @param atomic pointer to the integer to get
2479 * @returns the value at this moment
2482 _dbus_atomic_get (DBusAtomic *atomic)
2485 __sync_synchronize ();
2486 return atomic->value;
2490 _DBUS_LOCK (atomic);
2491 res = atomic->value;
2492 _DBUS_UNLOCK (atomic);
2498 * Wrapper for poll().
2500 * @param fds the file descriptors to poll
2501 * @param n_fds number of descriptors in the array
2502 * @param timeout_milliseconds timeout or -1 for infinite
2503 * @returns numbers of fds with revents, or <0 on error
2506 _dbus_poll (DBusPollFD *fds,
2508 int timeout_milliseconds)
2510 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2511 /* This big thing is a constant expression and should get optimized
2512 * out of existence. So it's more robust than a configure check at
2515 if (_DBUS_POLLIN == POLLIN &&
2516 _DBUS_POLLPRI == POLLPRI &&
2517 _DBUS_POLLOUT == POLLOUT &&
2518 _DBUS_POLLERR == POLLERR &&
2519 _DBUS_POLLHUP == POLLHUP &&
2520 _DBUS_POLLNVAL == POLLNVAL &&
2521 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2522 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2523 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2524 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2525 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2526 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2527 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2529 return poll ((struct pollfd*) fds,
2531 timeout_milliseconds);
2535 /* We have to convert the DBusPollFD to an array of
2536 * struct pollfd, poll, and convert back.
2538 _dbus_warn ("didn't implement poll() properly for this system yet\n");
2541 #else /* ! HAVE_POLL */
2543 fd_set read_set, write_set, err_set;
2549 FD_ZERO (&read_set);
2550 FD_ZERO (&write_set);
2553 for (i = 0; i < n_fds; i++)
2555 DBusPollFD *fdp = &fds[i];
2557 if (fdp->events & _DBUS_POLLIN)
2558 FD_SET (fdp->fd, &read_set);
2560 if (fdp->events & _DBUS_POLLOUT)
2561 FD_SET (fdp->fd, &write_set);
2563 FD_SET (fdp->fd, &err_set);
2565 max_fd = MAX (max_fd, fdp->fd);
2568 tv.tv_sec = timeout_milliseconds / 1000;
2569 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2571 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2572 timeout_milliseconds < 0 ? NULL : &tv);
2576 for (i = 0; i < n_fds; i++)
2578 DBusPollFD *fdp = &fds[i];
2582 if (FD_ISSET (fdp->fd, &read_set))
2583 fdp->revents |= _DBUS_POLLIN;
2585 if (FD_ISSET (fdp->fd, &write_set))
2586 fdp->revents |= _DBUS_POLLOUT;
2588 if (FD_ISSET (fdp->fd, &err_set))
2589 fdp->revents |= _DBUS_POLLERR;
2598 * Get current time, as in gettimeofday(). Use the monotonic clock if
2599 * available, to avoid problems when the system time changes.
2601 * @param tv_sec return location for number of seconds
2602 * @param tv_usec return location for number of microseconds
2605 _dbus_get_monotonic_time (long *tv_sec,
2608 #ifdef HAVE_MONOTONIC_CLOCK
2610 clock_gettime (CLOCK_MONOTONIC, &ts);
2613 *tv_sec = ts.tv_sec;
2615 *tv_usec = ts.tv_nsec / 1000;
2619 gettimeofday (&t, NULL);
2624 *tv_usec = t.tv_usec;
2629 * Get current time, as in gettimeofday(). Never uses the monotonic
2632 * @param tv_sec return location for number of seconds
2633 * @param tv_usec return location for number of microseconds
2636 _dbus_get_real_time (long *tv_sec,
2641 gettimeofday (&t, NULL);
2646 *tv_usec = t.tv_usec;
2650 * Creates a directory; succeeds if the directory
2651 * is created or already existed.
2653 * @param filename directory filename
2654 * @param error initialized error object
2655 * @returns #TRUE on success
2658 _dbus_create_directory (const DBusString *filename,
2661 const char *filename_c;
2663 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2665 filename_c = _dbus_string_get_const_data (filename);
2667 if (mkdir (filename_c, 0700) < 0)
2669 if (errno == EEXIST)
2672 dbus_set_error (error, DBUS_ERROR_FAILED,
2673 "Failed to create directory %s: %s\n",
2674 filename_c, _dbus_strerror (errno));
2682 * Appends the given filename to the given directory.
2684 * @todo it might be cute to collapse multiple '/' such as "foo//"
2687 * @param dir the directory name
2688 * @param next_component the filename
2689 * @returns #TRUE on success
2692 _dbus_concat_dir_and_file (DBusString *dir,
2693 const DBusString *next_component)
2695 dbus_bool_t dir_ends_in_slash;
2696 dbus_bool_t file_starts_with_slash;
2698 if (_dbus_string_get_length (dir) == 0 ||
2699 _dbus_string_get_length (next_component) == 0)
2702 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2703 _dbus_string_get_length (dir) - 1);
2705 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2707 if (dir_ends_in_slash && file_starts_with_slash)
2709 _dbus_string_shorten (dir, 1);
2711 else if (!(dir_ends_in_slash || file_starts_with_slash))
2713 if (!_dbus_string_append_byte (dir, '/'))
2717 return _dbus_string_copy (next_component, 0, dir,
2718 _dbus_string_get_length (dir));
2721 /** nanoseconds in a second */
2722 #define NANOSECONDS_PER_SECOND 1000000000
2723 /** microseconds in a second */
2724 #define MICROSECONDS_PER_SECOND 1000000
2725 /** milliseconds in a second */
2726 #define MILLISECONDS_PER_SECOND 1000
2727 /** nanoseconds in a millisecond */
2728 #define NANOSECONDS_PER_MILLISECOND 1000000
2729 /** microseconds in a millisecond */
2730 #define MICROSECONDS_PER_MILLISECOND 1000
2733 * Sleeps the given number of milliseconds.
2734 * @param milliseconds number of milliseconds
2737 _dbus_sleep_milliseconds (int milliseconds)
2739 #ifdef HAVE_NANOSLEEP
2740 struct timespec req;
2741 struct timespec rem;
2743 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2744 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2748 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2750 #elif defined (HAVE_USLEEP)
2751 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2752 #else /* ! HAVE_USLEEP */
2753 sleep (MAX (milliseconds / 1000, 1));
2758 _dbus_generate_pseudorandom_bytes (DBusString *str,
2764 old_len = _dbus_string_get_length (str);
2766 if (!_dbus_string_lengthen (str, n_bytes))
2769 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2771 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2777 * Generates the given number of random bytes,
2778 * using the best mechanism we can come up with.
2780 * @param str the string
2781 * @param n_bytes the number of random bytes to append to string
2782 * @returns #TRUE on success, #FALSE if no memory
2785 _dbus_generate_random_bytes (DBusString *str,
2791 /* FALSE return means "no memory", if it could
2792 * mean something else then we'd need to return
2793 * a DBusError. So we always fall back to pseudorandom
2797 old_len = _dbus_string_get_length (str);
2800 /* note, urandom on linux will fall back to pseudorandom */
2801 fd = open ("/dev/urandom", O_RDONLY);
2803 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2805 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2807 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2809 _dbus_close (fd, NULL);
2810 _dbus_string_set_length (str, old_len);
2811 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2814 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2817 _dbus_close (fd, NULL);
2823 * Exit the process, returning the given value.
2825 * @param code the exit code
2828 _dbus_exit (int code)
2834 * A wrapper around strerror() because some platforms
2835 * may be lame and not have strerror(). Also, never
2838 * @param error_number errno.
2839 * @returns error description.
2842 _dbus_strerror (int error_number)
2846 msg = strerror (error_number);
2854 * signal (SIGPIPE, SIG_IGN);
2857 _dbus_disable_sigpipe (void)
2859 signal (SIGPIPE, SIG_IGN);
2863 * Sets the file descriptor to be close
2864 * on exec. Should be called for all file
2865 * descriptors in D-Bus code.
2867 * @param fd the file descriptor
2870 _dbus_fd_set_close_on_exec (intptr_t fd)
2874 val = fcntl (fd, F_GETFD, 0);
2881 fcntl (fd, F_SETFD, val);
2885 * Closes a file descriptor.
2887 * @param fd the file descriptor
2888 * @param error error object
2889 * @returns #FALSE if error set
2892 _dbus_close (int fd,
2895 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2903 dbus_set_error (error, _dbus_error_from_errno (errno),
2904 "Could not close fd %d", fd);
2912 * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2913 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2915 * @param fd the file descriptor to duplicate
2916 * @returns duplicated file descriptor
2924 #ifdef F_DUPFD_CLOEXEC
2925 dbus_bool_t cloexec_done;
2927 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2928 cloexec_done = new_fd >= 0;
2930 if (new_fd < 0 && errno == EINVAL)
2933 new_fd = fcntl(fd, F_DUPFD, 3);
2938 dbus_set_error (error, _dbus_error_from_errno (errno),
2939 "Could not duplicate fd %d", fd);
2943 #ifdef F_DUPFD_CLOEXEC
2947 _dbus_fd_set_close_on_exec(new_fd);
2954 * Sets a file descriptor to be nonblocking.
2956 * @param fd the file descriptor.
2957 * @param error address of error location.
2958 * @returns #TRUE on success.
2961 _dbus_set_fd_nonblocking (int fd,
2966 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2968 val = fcntl (fd, F_GETFL, 0);
2971 dbus_set_error (error, _dbus_error_from_errno (errno),
2972 "Failed to get flags from file descriptor %d: %s",
2973 fd, _dbus_strerror (errno));
2974 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2975 _dbus_strerror (errno));
2979 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2981 dbus_set_error (error, _dbus_error_from_errno (errno),
2982 "Failed to set nonblocking flag of file descriptor %d: %s",
2983 fd, _dbus_strerror (errno));
2984 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2985 fd, _dbus_strerror (errno));
2994 * On GNU libc systems, print a crude backtrace to stderr. On other
2995 * systems, print "no backtrace support" and block for possible gdb
2996 * attachment if an appropriate environment variable is set.
2999 _dbus_print_backtrace (void)
3001 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3007 bt_size = backtrace (bt, 500);
3009 syms = backtrace_symbols (bt, bt_size);
3014 /* don't use dbus_warn since it can _dbus_abort() */
3015 fprintf (stderr, " %s\n", syms[i]);
3021 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3022 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3024 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3029 * Creates a full-duplex pipe (as in socketpair()).
3030 * Sets both ends of the pipe nonblocking.
3032 * Marks both file descriptors as close-on-exec
3034 * @param fd1 return location for one end
3035 * @param fd2 return location for the other end
3036 * @param blocking #TRUE if pipe should be blocking
3037 * @param error error return
3038 * @returns #FALSE on failure (if error is set)
3041 _dbus_full_duplex_pipe (int *fd1,
3043 dbus_bool_t blocking,
3046 #ifdef HAVE_SOCKETPAIR
3051 dbus_bool_t cloexec_done;
3053 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3054 cloexec_done = retval >= 0;
3056 if (retval < 0 && errno == EINVAL)
3059 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3064 dbus_set_error (error, _dbus_error_from_errno (errno),
3065 "Could not create full-duplex pipe");
3069 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3075 _dbus_fd_set_close_on_exec (fds[0]);
3076 _dbus_fd_set_close_on_exec (fds[1]);
3080 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3081 !_dbus_set_fd_nonblocking (fds[1], NULL)))
3083 dbus_set_error (error, _dbus_error_from_errno (errno),
3084 "Could not set full-duplex pipe nonblocking");
3086 _dbus_close (fds[0], NULL);
3087 _dbus_close (fds[1], NULL);
3095 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3100 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3101 dbus_set_error (error, DBUS_ERROR_FAILED,
3102 "_dbus_full_duplex_pipe() not implemented on this OS");
3108 * Measure the length of the given format string and arguments,
3109 * not including the terminating nul.
3111 * @param format a printf-style format string
3112 * @param args arguments for the format string
3113 * @returns length of the given format string and args, or -1 if no memory
3116 _dbus_printf_string_upper_bound (const char *format,
3119 char static_buf[1024];
3120 int bufsize = sizeof (static_buf);
3123 len = vsnprintf (static_buf, bufsize, format, args);
3125 /* If vsnprintf() returned non-negative, then either the string fits in
3126 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3127 * returns the number of characters that were needed, or this OS returns the
3130 * We ignore the possibility that snprintf might just ignore the length and
3131 * overrun the buffer (64-bit Solaris 7), because that's pathological.
3132 * If your libc is really that bad, come back when you have a better one. */
3135 /* This could be the truncated length (Tru64 and IRIX have this bug),
3136 * or the real length could be coincidentally the same. Which is it?
3137 * If vsnprintf returns the truncated length, we'll go to the slow
3139 if (vsnprintf (static_buf, 1, format, args) == 1)
3143 /* If vsnprintf() returned negative, we have to do more work.
3144 * HP-UX returns negative. */
3151 buf = dbus_malloc (bufsize);
3156 len = vsnprintf (buf, bufsize, format, args);
3159 /* If the reported length is exactly the buffer size, round up to the
3160 * next size, in case vsnprintf has been returning the truncated
3170 * Gets the temporary files directory by inspecting the environment variables
3171 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3173 * @returns location of temp directory
3176 _dbus_get_tmpdir(void)
3178 static const char* tmpdir = NULL;
3182 /* TMPDIR is what glibc uses, then
3183 * glibc falls back to the P_tmpdir macro which
3184 * just expands to "/tmp"
3187 tmpdir = getenv("TMPDIR");
3189 /* These two env variables are probably
3190 * broken, but maybe some OS uses them?
3193 tmpdir = getenv("TMP");
3195 tmpdir = getenv("TEMP");
3197 /* And this is the sane fallback. */
3202 _dbus_assert(tmpdir != NULL);
3208 * Execute a subprocess, returning up to 1024 bytes of output
3211 * If successful, returns #TRUE and appends the output to @p
3212 * result. If a failure happens, returns #FALSE and
3213 * sets an error in @p error.
3215 * @note It's not an error if the subprocess terminates normally
3216 * without writing any data to stdout. Verify the @p result length
3217 * before and after this function call to cover this case.
3219 * @param progname initial path to exec (may or may not be absolute)
3220 * @param path_fallback if %TRUE, search PATH for executable
3221 * @param argv NULL-terminated list of arguments
3222 * @param result a DBusString where the output can be append
3223 * @param error a DBusError to store the error in case of failure
3224 * @returns #TRUE on success, #FALSE if an error happened
3227 _read_subprocess_line_argv (const char *progpath,
3228 dbus_bool_t path_fallback,
3233 int result_pipe[2] = { -1, -1 };
3234 int errors_pipe[2] = { -1, -1 };
3241 sigset_t new_set, old_set;
3243 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3246 /* We need to block any existing handlers for SIGCHLD temporarily; they
3247 * will cause waitpid() below to fail.
3248 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3250 sigemptyset (&new_set);
3251 sigaddset (&new_set, SIGCHLD);
3252 sigprocmask (SIG_BLOCK, &new_set, &old_set);
3254 orig_len = _dbus_string_get_length (result);
3258 if (pipe (result_pipe) < 0)
3260 dbus_set_error (error, _dbus_error_from_errno (errno),
3261 "Failed to create a pipe to call %s: %s",
3262 progpath, _dbus_strerror (errno));
3263 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3264 progpath, _dbus_strerror (errno));
3267 if (pipe (errors_pipe) < 0)
3269 dbus_set_error (error, _dbus_error_from_errno (errno),
3270 "Failed to create a pipe to call %s: %s",
3271 progpath, _dbus_strerror (errno));
3272 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3273 progpath, _dbus_strerror (errno));
3280 dbus_set_error (error, _dbus_error_from_errno (errno),
3281 "Failed to fork() to call %s: %s",
3282 progpath, _dbus_strerror (errno));
3283 _dbus_verbose ("Failed to fork() to call %s: %s\n",
3284 progpath, _dbus_strerror (errno));
3293 fd = open ("/dev/null", O_RDWR);
3295 /* huh?! can't open /dev/null? */
3298 _dbus_verbose ("/dev/null fd %d opened\n", fd);
3301 close (result_pipe[READ_END]);
3302 close (errors_pipe[READ_END]);
3303 close (0); /* close stdin */
3304 close (1); /* close stdout */
3305 close (2); /* close stderr */
3307 if (dup2 (fd, 0) == -1)
3309 if (dup2 (result_pipe[WRITE_END], 1) == -1)
3311 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3316 sigprocmask (SIG_SETMASK, &old_set, NULL);
3318 /* If it looks fully-qualified, try execv first */
3319 if (progpath[0] == '/')
3321 execv (progpath, argv);
3322 /* Ok, that failed. Now if path_fallback is given, let's
3323 * try unqualified. This is mostly a hack to work
3324 * around systems which ship dbus-launch in /usr/bin
3325 * but everything else in /bin (because dbus-launch
3329 /* We must have a slash, because we checked above */
3330 execvp (strrchr (progpath, '/')+1, argv);
3333 execvp (progpath, argv);
3335 /* still nothing, we failed */
3339 /* parent process */
3340 close (result_pipe[WRITE_END]);
3341 close (errors_pipe[WRITE_END]);
3342 result_pipe[WRITE_END] = -1;
3343 errors_pipe[WRITE_END] = -1;
3348 ret = _dbus_read (result_pipe[READ_END], result, 1024);
3352 /* reap the child process to avoid it lingering as zombie */
3355 ret = waitpid (pid, &status, 0);
3357 while (ret == -1 && errno == EINTR);
3359 /* We succeeded if the process exited with status 0 and
3360 anything was read */
3361 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3363 /* The process ended with error */
3364 DBusString error_message;
3365 if (!_dbus_string_init (&error_message))
3367 _DBUS_SET_OOM (error);
3374 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3378 _dbus_string_set_length (result, orig_len);
3379 if (_dbus_string_get_length (&error_message) > 0)
3380 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3381 "%s terminated abnormally with the following error: %s",
3382 progpath, _dbus_string_get_data (&error_message));
3384 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3385 "%s terminated abnormally without any error message",
3393 sigprocmask (SIG_SETMASK, &old_set, NULL);
3396 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3398 _DBUS_ASSERT_ERROR_IS_SET (error);
3400 if (result_pipe[0] != -1)
3401 close (result_pipe[0]);
3402 if (result_pipe[1] != -1)
3403 close (result_pipe[1]);
3404 if (errors_pipe[0] != -1)
3405 close (errors_pipe[0]);
3406 if (errors_pipe[1] != -1)
3407 close (errors_pipe[1]);
3413 * Returns the address of a new session bus.
3415 * If successful, returns #TRUE and appends the address to @p
3416 * address. If a failure happens, returns #FALSE and
3417 * sets an error in @p error.
3419 * @param address a DBusString where the address can be stored
3420 * @param error a DBusError to store the error in case of failure
3421 * @returns #TRUE on success, #FALSE if an error happened
3424 _dbus_get_autolaunch_address (const char *scope,
3425 DBusString *address,
3428 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3429 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3430 * but that's done elsewhere, and if it worked, this function wouldn't
3432 const char *display;
3433 static char *argv[6];
3438 if (_dbus_check_setuid ())
3440 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3441 "Unable to autolaunch when setuid");
3445 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3448 /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3449 * dbus-launch-x11 is just going to fail. Rather than trying to
3450 * run it, we might as well bail out early with a nice error. */
3451 display = _dbus_getenv ("DISPLAY");
3453 if (display == NULL || display[0] == '\0')
3455 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3456 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3460 if (!_dbus_string_init (&uuid))
3462 _DBUS_SET_OOM (error);
3466 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3468 _DBUS_SET_OOM (error);
3473 argv[i] = "dbus-launch";
3475 argv[i] = "--autolaunch";
3477 argv[i] = _dbus_string_get_data (&uuid);
3479 argv[i] = "--binary-syntax";
3481 argv[i] = "--close-stderr";
3486 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3488 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3490 argv, address, error);
3493 _dbus_string_free (&uuid);
3496 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3497 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3498 "set your DBUS_SESSION_BUS_ADDRESS instead");
3504 * Reads the uuid of the machine we're running on from
3505 * the dbus configuration. Optionally try to create it
3506 * (only root can do this usually).
3508 * On UNIX, reads a file that gets created by dbus-uuidgen
3509 * in a post-install script. On Windows, if there's a standard
3510 * machine uuid we could just use that, but I can't find one
3511 * with the right properties (the hardware profile guid can change
3512 * without rebooting I believe). If there's no standard one
3513 * we might want to use the registry instead of a file for
3514 * this, and I'm not sure how we'd ensure the uuid gets created.
3516 * @param machine_id guid to init with the machine's uuid
3517 * @param create_if_not_found try to create the uuid if it doesn't exist
3518 * @param error the error return
3519 * @returns #FALSE if the error is set
3522 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3523 dbus_bool_t create_if_not_found,
3526 DBusString filename;
3529 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3531 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3535 dbus_error_free (error);
3537 /* Fallback to the system machine ID */
3538 _dbus_string_init_const (&filename, "/etc/machine-id");
3539 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3542 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3543 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3546 * quries launchd for a specific env var which holds the socket path.
3547 * @param launchd_env_var the env var to look up
3548 * @param error a DBusError to store the error in case of failure
3549 * @return the value of the env var
3552 _dbus_lookup_launchd_socket (DBusString *socket_path,
3553 const char *launchd_env_var,
3556 #ifdef DBUS_ENABLE_LAUNCHD
3560 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3562 if (_dbus_check_setuid ())
3564 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3565 "Unable to find launchd socket when setuid");
3570 argv[i] = "launchctl";
3574 argv[i] = (char*)launchd_env_var;
3579 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3581 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3586 /* no error, but no result either */
3587 if (_dbus_string_get_length(socket_path) == 0)
3592 /* strip the carriage-return */
3593 _dbus_string_shorten(socket_path, 1);
3595 #else /* DBUS_ENABLE_LAUNCHD */
3596 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3597 "can't lookup socket from launchd; launchd support not compiled in");
3602 #ifdef DBUS_ENABLE_LAUNCHD
3604 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3606 dbus_bool_t valid_socket;
3607 DBusString socket_path;
3609 if (_dbus_check_setuid ())
3611 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3612 "Unable to find launchd socket when setuid");
3616 if (!_dbus_string_init (&socket_path))
3618 _DBUS_SET_OOM (error);
3622 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3624 if (dbus_error_is_set(error))
3626 _dbus_string_free(&socket_path);
3632 dbus_set_error(error, "no socket path",
3633 "launchd did not provide a socket path, "
3634 "verify that org.freedesktop.dbus-session.plist is loaded!");
3635 _dbus_string_free(&socket_path);
3638 if (!_dbus_string_append (address, "unix:path="))
3640 _DBUS_SET_OOM (error);
3641 _dbus_string_free(&socket_path);
3644 if (!_dbus_string_copy (&socket_path, 0, address,
3645 _dbus_string_get_length (address)))
3647 _DBUS_SET_OOM (error);
3648 _dbus_string_free(&socket_path);
3652 _dbus_string_free(&socket_path);
3658 * Determines the address of the session bus by querying a
3659 * platform-specific method.
3661 * The first parameter will be a boolean specifying whether
3662 * or not a dynamic session lookup is supported on this platform.
3664 * If supported is TRUE and the return value is #TRUE, the
3665 * address will be appended to @p address.
3666 * If a failure happens, returns #FALSE and sets an error in
3669 * If supported is FALSE, ignore the return value.
3671 * @param supported returns whether this method is supported
3672 * @param address a DBusString where the address can be stored
3673 * @param error a DBusError to store the error in case of failure
3674 * @returns #TRUE on success, #FALSE if an error happened
3677 _dbus_lookup_session_address (dbus_bool_t *supported,
3678 DBusString *address,
3681 #ifdef DBUS_ENABLE_LAUNCHD
3683 return _dbus_lookup_session_address_launchd (address, error);
3685 /* On non-Mac Unix platforms, if the session address isn't already
3686 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3687 * fall back to the autolaunch: global default; see
3688 * init_session_address in dbus/dbus-bus.c. */
3695 * Returns the standard directories for a session bus to look for service
3698 * On UNIX this should be the standard xdg freedesktop.org data directories:
3700 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3701 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3707 * @param dirs the directory list we are returning
3708 * @returns #FALSE on OOM
3712 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3714 const char *xdg_data_home;
3715 const char *xdg_data_dirs;
3716 DBusString servicedir_path;
3718 if (!_dbus_string_init (&servicedir_path))
3721 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3722 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3724 if (xdg_data_home != NULL)
3726 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3731 const DBusString *homedir;
3732 DBusString local_share;
3734 if (!_dbus_homedir_from_current_process (&homedir))
3737 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3740 _dbus_string_init_const (&local_share, "/.local/share");
3741 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3745 if (!_dbus_string_append (&servicedir_path, ":"))
3748 if (xdg_data_dirs != NULL)
3750 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3753 if (!_dbus_string_append (&servicedir_path, ":"))
3758 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3763 * add configured datadir to defaults
3764 * this may be the same as an xdg dir
3765 * however the config parser should take
3766 * care of duplicates
3768 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3771 if (!_dbus_split_paths_and_append (&servicedir_path,
3772 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3776 _dbus_string_free (&servicedir_path);
3780 _dbus_string_free (&servicedir_path);
3786 * Returns the standard directories for a system bus to look for service
3789 * On UNIX this should be the standard xdg freedesktop.org data directories:
3791 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3797 * On Windows there is no system bus and this function can return nothing.
3799 * @param dirs the directory list we are returning
3800 * @returns #FALSE on OOM
3804 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3807 * DBUS_DATADIR may be the same as one of the standard directories. However,
3808 * the config parser should take care of the duplicates.
3810 * Also, append /lib as counterpart of /usr/share on the root
3811 * directory (the root directory does not know /share), in order to
3812 * facilitate early boot system bus activation where /usr might not
3815 static const char standard_search_path[] =
3820 DBusString servicedir_path;
3822 _dbus_string_init_const (&servicedir_path, standard_search_path);
3824 return _dbus_split_paths_and_append (&servicedir_path,
3825 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3830 * Append the absolute path of the system.conf file
3831 * (there is no system bus on Windows so this can just
3832 * return FALSE and print a warning or something)
3834 * @param str the string to append to
3835 * @returns #FALSE if no memory
3838 _dbus_append_system_config_file (DBusString *str)
3840 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3844 * Append the absolute path of the session.conf file.
3846 * @param str the string to append to
3847 * @returns #FALSE if no memory
3850 _dbus_append_session_config_file (DBusString *str)
3852 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3856 * Called when the bus daemon is signaled to reload its configuration; any
3857 * caches should be nuked. Of course any caches that need explicit reload
3858 * are probably broken, but c'est la vie.
3863 _dbus_flush_caches (void)
3865 _dbus_user_database_flush_system ();
3869 * Appends the directory in which a keyring for the given credentials
3870 * should be stored. The credentials should have either a Windows or
3871 * UNIX user in them. The directory should be an absolute path.
3873 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3874 * be something else, since the dotfile convention is not normal on Windows.
3876 * @param directory string to append directory to
3877 * @param credentials credentials the directory should be for
3879 * @returns #FALSE on no memory
3882 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3883 DBusCredentials *credentials)
3889 _dbus_assert (credentials != NULL);
3890 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3892 if (!_dbus_string_init (&homedir))
3895 uid = _dbus_credentials_get_unix_uid (credentials);
3896 _dbus_assert (uid != DBUS_UID_UNSET);
3898 if (!_dbus_homedir_from_uid (uid, &homedir))
3901 #ifdef DBUS_BUILD_TESTS
3903 const char *override;
3905 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3906 if (override != NULL && *override != '\0')
3908 _dbus_string_set_length (&homedir, 0);
3909 if (!_dbus_string_append (&homedir, override))
3912 _dbus_verbose ("Using fake homedir for testing: %s\n",
3913 _dbus_string_get_const_data (&homedir));
3917 static dbus_bool_t already_warned = FALSE;
3918 if (!already_warned)
3920 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3921 already_warned = TRUE;
3927 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3928 if (!_dbus_concat_dir_and_file (&homedir,
3932 if (!_dbus_string_copy (&homedir, 0,
3933 directory, _dbus_string_get_length (directory))) {
3937 _dbus_string_free (&homedir);
3941 _dbus_string_free (&homedir);
3945 //PENDING(kdab) docs
3947 _dbus_daemon_publish_session_bus_address (const char* addr,
3953 //PENDING(kdab) docs
3955 _dbus_daemon_unpublish_session_bus_address (void)
3961 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3962 * for Winsock so is abstracted)
3964 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3967 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3969 return errno == EAGAIN || errno == EWOULDBLOCK;
3973 * Removes a directory; Directory must be empty
3975 * @param filename directory filename
3976 * @param error initialized error object
3977 * @returns #TRUE on success
3980 _dbus_delete_directory (const DBusString *filename,
3983 const char *filename_c;
3985 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3987 filename_c = _dbus_string_get_const_data (filename);
3989 if (rmdir (filename_c) != 0)
3991 dbus_set_error (error, DBUS_ERROR_FAILED,
3992 "Failed to remove directory %s: %s\n",
3993 filename_c, _dbus_strerror (errno));
4001 * Checks whether file descriptors may be passed via the socket
4003 * @param fd the socket
4004 * @return TRUE when fd passing over this socket is supported
4008 _dbus_socket_can_pass_unix_fd(int fd) {
4013 struct sockaddr_storage storage;
4014 struct sockaddr_un un;
4017 socklen_t sa_len = sizeof(sa_buf);
4021 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4024 return sa_buf.sa.sa_family == AF_UNIX;
4034 * replaces the term DBUS_PREFIX in configure_time_path by the
4035 * current dbus installation directory. On unix this function is a noop
4037 * @param configure_time_path
4041 _dbus_replace_install_prefix (const char *configure_time_path)
4043 return configure_time_path;
4047 * Closes all file descriptors except the first three (i.e. stdin,
4051 _dbus_close_all (void)
4058 /* On Linux we can optimize this a bit if /proc is available. If it
4059 isn't available, fall back to the brute force way. */
4061 d = opendir ("/proc/self/fd");
4066 struct dirent buf, *de;
4071 k = readdir_r (d, &buf, &de);
4075 if (de->d_name[0] == '.')
4079 l = strtol (de->d_name, &e, 10);
4080 if (errno != 0 || e == NULL || *e != '\0')
4087 if (fd == dirfd (d))
4098 maxfds = sysconf (_SC_OPEN_MAX);
4100 /* Pick something reasonable if for some reason sysconf says
4106 /* close all inherited fds */
4107 for (i = 3; i < maxfds; i++)
4112 * **NOTE**: If you modify this function, please also consider making
4113 * the corresponding change in GLib. See
4114 * glib/gutils.c:g_check_setuid().
4116 * Returns TRUE if the current process was executed as setuid (or an
4117 * equivalent __libc_enable_secure is available). See:
4118 * http://osdir.com/ml/linux.lfs.hardened/2007-04/msg00032.html
4121 _dbus_check_setuid (void)
4123 /* TODO: get __libc_enable_secure exported from glibc.
4124 * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4126 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4128 /* See glibc/include/unistd.h */
4129 extern int __libc_enable_secure;
4130 return __libc_enable_secure;
4132 #elif defined(HAVE_ISSETUGID)
4133 /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4134 return issetugid ();
4136 uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4137 gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4139 static dbus_bool_t check_setuid_initialised;
4140 static dbus_bool_t is_setuid;
4142 if (_DBUS_UNLIKELY (!check_setuid_initialised))
4144 #ifdef HAVE_GETRESUID
4145 if (getresuid (&ruid, &euid, &suid) != 0 ||
4146 getresgid (&rgid, &egid, &sgid) != 0)
4147 #endif /* HAVE_GETRESUID */
4149 suid = ruid = getuid ();
4150 sgid = rgid = getgid ();
4155 check_setuid_initialised = TRUE;
4156 is_setuid = (ruid != euid || ruid != suid ||
4157 rgid != egid || rgid != sgid);
4165 * Read the address from the socket and append it to the string
4167 * @param fd the socket
4169 * @param error return location for error code
4172 _dbus_append_address_from_socket (int fd,
4173 DBusString *address,
4178 struct sockaddr_storage storage;
4179 struct sockaddr_un un;
4180 struct sockaddr_in ipv4;
4181 struct sockaddr_in6 ipv6;
4183 char hostip[INET6_ADDRSTRLEN];
4184 int size = sizeof (socket);
4186 if (getsockname (fd, &socket.sa, &size))
4189 switch (socket.sa.sa_family)
4192 if (socket.un.sun_path[0]=='\0')
4194 if (_dbus_string_append_printf (address, "unix:abstract=%s", &(socket.un.sun_path[1])))
4199 if (_dbus_string_append_printf (address, "unix:path=%s", socket.un.sun_path))
4204 if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4205 if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4206 hostip, ntohs (socket.ipv4.sin_port)))
4211 if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4212 if (_dbus_string_append_printf (address, "tcp:family=ipv6,host=%s,port=%u",
4213 hostip, ntohs (socket.ipv6.sin6_port)))
4218 dbus_set_error (error,
4219 _dbus_error_from_errno (EINVAL),
4220 "Failed to read address from socket: Unknown socket type.");
4224 dbus_set_error (error,
4225 _dbus_error_from_errno (errno),
4226 "Failed to open socket: %s",
4227 _dbus_strerror (errno));
4231 /* tests in dbus-sysdeps-util.c */