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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"
38 #include <sys/types.h>
45 #include <sys/socket.h>
54 #include <netinet/in.h>
70 #ifdef HAVE_GETPEERUCRED
83 #define AI_ADDRCONFIG 0
86 #ifndef HAVE_SOCKLEN_T
91 _dbus_open_socket (int *fd_p,
98 dbus_bool_t cloexec_done;
100 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
101 cloexec_done = *fd_p >= 0;
103 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
104 if (*fd_p < 0 && errno == EINVAL)
107 *fd_p = socket (domain, type, protocol);
116 _dbus_fd_set_close_on_exec(*fd_p);
119 _dbus_verbose ("socket fd %d opened\n", *fd_p);
124 dbus_set_error(error,
125 _dbus_error_from_errno (errno),
126 "Failed to open socket: %s",
127 _dbus_strerror (errno));
133 _dbus_open_tcp_socket (int *fd,
136 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
140 * Opens a UNIX domain socket (as in the socket() call).
141 * Does not bind the socket.
143 * This will set FD_CLOEXEC for the socket returned
145 * @param fd return location for socket descriptor
146 * @param error return location for an error
147 * @returns #FALSE if error is set
150 _dbus_open_unix_socket (int *fd,
153 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
157 * Closes a socket. Should not be used on non-socket
158 * file descriptors or handles.
160 * @param fd the socket
161 * @param error return location for an error
162 * @returns #FALSE if error is set
165 _dbus_close_socket (int fd,
168 return _dbus_close (fd, error);
172 * Like _dbus_read(), but only works on sockets so is
173 * available on Windows.
175 * @param fd the socket
176 * @param buffer string to append data to
177 * @param count max amount of data to read
178 * @returns number of bytes appended to the string
181 _dbus_read_socket (int fd,
185 return _dbus_read (fd, buffer, count);
189 * Like _dbus_write(), but only supports sockets
190 * and is thus available on Windows.
192 * @param fd the file descriptor to write
193 * @param buffer the buffer to write data from
194 * @param start the first byte in the buffer to write
195 * @param len the number of bytes to try to write
196 * @returns the number of bytes written or -1 on error
199 _dbus_write_socket (int fd,
200 const DBusString *buffer,
208 data = _dbus_string_get_const_data_len (buffer, start, len);
212 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
214 if (bytes_written < 0 && errno == EINTR)
217 return bytes_written;
220 return _dbus_write (fd, buffer, start, len);
225 * Like _dbus_read_socket() but also tries to read unix fds from the
226 * socket. When there are more fds to read than space in the array
227 * passed this function will fail with ENOSPC.
229 * @param fd the socket
230 * @param buffer string to append data to
231 * @param count max amount of data to read
232 * @param fds array to place read file descriptors in
233 * @param n_fds on input space in fds array, on output how many fds actually got read
234 * @returns number of bytes appended to string
237 _dbus_read_socket_with_unix_fds (int fd,
242 #ifndef HAVE_UNIX_FD_PASSING
245 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
257 _dbus_assert (count >= 0);
258 _dbus_assert (*n_fds >= 0);
260 start = _dbus_string_get_length (buffer);
262 if (!_dbus_string_lengthen (buffer, count))
269 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
276 /* Hmm, we have no clue how long the control data will actually be
277 that is queued for us. The least we can do is assume that the
278 caller knows. Hence let's make space for the number of fds that
279 we shall read at max plus the cmsg header. */
280 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
282 /* It's probably safe to assume that systems with SCM_RIGHTS also
284 m.msg_control = alloca(m.msg_controllen);
285 memset(m.msg_control, 0, m.msg_controllen);
289 bytes_read = recvmsg(fd, &m, 0
290 #ifdef MSG_CMSG_CLOEXEC
301 /* put length back (note that this doesn't actually realloc anything) */
302 _dbus_string_set_length (buffer, start);
309 dbus_bool_t found = FALSE;
311 if (m.msg_flags & MSG_CTRUNC)
313 /* Hmm, apparently the control data was truncated. The bad
314 thing is that we might have completely lost a couple of fds
315 without chance to recover them. Hence let's treat this as a
319 _dbus_string_set_length (buffer, start);
323 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
324 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
328 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
329 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
331 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
334 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
335 worked, hence we need to go through this list and set
336 CLOEXEC everywhere in any case */
337 for (i = 0; i < *n_fds; i++)
338 _dbus_fd_set_close_on_exec(fds[i]);
346 /* put length back (doesn't actually realloc) */
347 _dbus_string_set_length (buffer, start + bytes_read);
351 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
360 _dbus_write_socket_with_unix_fds(int fd,
361 const DBusString *buffer,
367 #ifndef HAVE_UNIX_FD_PASSING
374 return _dbus_write_socket(fd, buffer, start, len);
376 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
381 _dbus_write_socket_with_unix_fds_two(int fd,
382 const DBusString *buffer1,
385 const DBusString *buffer2,
391 #ifndef HAVE_UNIX_FD_PASSING
398 return _dbus_write_socket_two(fd,
399 buffer1, start1, len1,
400 buffer2, start2, len2);
408 _dbus_assert (len1 >= 0);
409 _dbus_assert (len2 >= 0);
410 _dbus_assert (n_fds >= 0);
413 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
414 iov[0].iov_len = len1;
418 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
419 iov[1].iov_len = len2;
424 m.msg_iovlen = buffer2 ? 2 : 1;
428 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
429 m.msg_control = alloca(m.msg_controllen);
430 memset(m.msg_control, 0, m.msg_controllen);
432 cm = CMSG_FIRSTHDR(&m);
433 cm->cmsg_level = SOL_SOCKET;
434 cm->cmsg_type = SCM_RIGHTS;
435 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
436 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
441 bytes_written = sendmsg (fd, &m, 0
447 if (bytes_written < 0 && errno == EINTR)
451 if (bytes_written > 0)
452 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
455 return bytes_written;
460 * write data to a pipe.
462 * @param pipe the pipe instance
463 * @param buffer the buffer to write data from
464 * @param start the first byte in the buffer to write
465 * @param len the number of bytes to try to write
466 * @param error error return
467 * @returns the number of bytes written or -1 on error
470 _dbus_pipe_write (DBusPipe *pipe,
471 const DBusString *buffer,
478 written = _dbus_write (pipe->fd_or_handle, buffer, start, len);
481 dbus_set_error (error, DBUS_ERROR_FAILED,
482 "Writing to pipe: %s\n",
483 _dbus_strerror (errno));
491 * @param pipe the pipe instance
492 * @param error return location for an error
493 * @returns #FALSE if error is set
496 _dbus_pipe_close (DBusPipe *pipe,
499 if (_dbus_close (pipe->fd_or_handle, error) < 0)
505 _dbus_pipe_invalidate (pipe);
511 * Like _dbus_write_two() but only works on sockets and is thus
512 * available on Windows.
514 * @param fd the file descriptor
515 * @param buffer1 first buffer
516 * @param start1 first byte to write in first buffer
517 * @param len1 number of bytes to write from first buffer
518 * @param buffer2 second buffer, or #NULL
519 * @param start2 first byte to write in second buffer
520 * @param len2 number of bytes to write in second buffer
521 * @returns total bytes written from both buffers, or -1 on error
524 _dbus_write_socket_two (int fd,
525 const DBusString *buffer1,
528 const DBusString *buffer2,
533 struct iovec vectors[2];
539 _dbus_assert (buffer1 != NULL);
540 _dbus_assert (start1 >= 0);
541 _dbus_assert (start2 >= 0);
542 _dbus_assert (len1 >= 0);
543 _dbus_assert (len2 >= 0);
545 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
548 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
556 vectors[0].iov_base = (char*) data1;
557 vectors[0].iov_len = len1;
558 vectors[1].iov_base = (char*) data2;
559 vectors[1].iov_len = len2;
563 m.msg_iovlen = data2 ? 2 : 1;
567 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
569 if (bytes_written < 0 && errno == EINTR)
572 return bytes_written;
575 return _dbus_write_two (fd, buffer1, start1, len1,
576 buffer2, start2, len2);
582 * Thin wrapper around the read() system call that appends
583 * the data it reads to the DBusString buffer. It appends
584 * up to the given count, and returns the same value
585 * and same errno as read(). The only exception is that
586 * _dbus_read() handles EINTR for you. Also, _dbus_read() can
587 * return ENOMEM, even though regular UNIX read doesn't.
589 * Unlike _dbus_read_socket(), _dbus_read() is not available
592 * @param fd the file descriptor to read from
593 * @param buffer the buffer to append data to
594 * @param count the amount of data to read
595 * @returns the number of bytes read or -1
606 _dbus_assert (count >= 0);
608 start = _dbus_string_get_length (buffer);
610 if (!_dbus_string_lengthen (buffer, count))
616 data = _dbus_string_get_data_len (buffer, start, count);
620 bytes_read = read (fd, data, count);
628 /* put length back (note that this doesn't actually realloc anything) */
629 _dbus_string_set_length (buffer, start);
635 /* put length back (doesn't actually realloc) */
636 _dbus_string_set_length (buffer, start + bytes_read);
640 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
648 * Thin wrapper around the write() system call that writes a part of a
649 * DBusString and handles EINTR for you.
651 * @param fd the file descriptor to write
652 * @param buffer the buffer to write data from
653 * @param start the first byte in the buffer to write
654 * @param len the number of bytes to try to write
655 * @returns the number of bytes written or -1 on error
659 const DBusString *buffer,
666 data = _dbus_string_get_const_data_len (buffer, start, len);
670 bytes_written = write (fd, data, len);
672 if (bytes_written < 0 && errno == EINTR)
676 if (bytes_written > 0)
677 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
680 return bytes_written;
684 * Like _dbus_write() but will use writev() if possible
685 * to write both buffers in sequence. The return value
686 * is the number of bytes written in the first buffer,
687 * plus the number written in the second. If the first
688 * buffer is written successfully and an error occurs
689 * writing the second, the number of bytes in the first
690 * is returned (i.e. the error is ignored), on systems that
691 * don't have writev. Handles EINTR for you.
692 * The second buffer may be #NULL.
694 * @param fd the file descriptor
695 * @param buffer1 first buffer
696 * @param start1 first byte to write in first buffer
697 * @param len1 number of bytes to write from first buffer
698 * @param buffer2 second buffer, or #NULL
699 * @param start2 first byte to write in second buffer
700 * @param len2 number of bytes to write in second buffer
701 * @returns total bytes written from both buffers, or -1 on error
704 _dbus_write_two (int fd,
705 const DBusString *buffer1,
708 const DBusString *buffer2,
712 _dbus_assert (buffer1 != NULL);
713 _dbus_assert (start1 >= 0);
714 _dbus_assert (start2 >= 0);
715 _dbus_assert (len1 >= 0);
716 _dbus_assert (len2 >= 0);
720 struct iovec vectors[2];
725 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
728 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
736 vectors[0].iov_base = (char*) data1;
737 vectors[0].iov_len = len1;
738 vectors[1].iov_base = (char*) data2;
739 vectors[1].iov_len = len2;
743 bytes_written = writev (fd,
747 if (bytes_written < 0 && errno == EINTR)
750 return bytes_written;
752 #else /* HAVE_WRITEV */
756 ret1 = _dbus_write (fd, buffer1, start1, len1);
757 if (ret1 == len1 && buffer2 != NULL)
759 ret2 = _dbus_write (fd, buffer2, start2, len2);
761 ret2 = 0; /* we can't report an error as the first write was OK */
768 #endif /* !HAVE_WRITEV */
771 #define _DBUS_MAX_SUN_PATH_LENGTH 99
774 * @def _DBUS_MAX_SUN_PATH_LENGTH
776 * Maximum length of the path to a UNIX domain socket,
777 * sockaddr_un::sun_path member. POSIX requires that all systems
778 * support at least 100 bytes here, including the nul termination.
779 * We use 99 for the max value to allow for the nul.
781 * We could probably also do sizeof (addr.sun_path)
782 * but this way we are the same on all platforms
783 * which is probably a good idea.
787 * Creates a socket and connects it to the UNIX domain socket at the
788 * given path. The connection fd is returned, and is set up as
791 * Uses abstract sockets instead of filesystem-linked sockets if
792 * requested (it's possible only on Linux; see "man 7 unix" on Linux).
793 * On non-Linux abstract socket usage always fails.
795 * This will set FD_CLOEXEC for the socket returned.
797 * @param path the path to UNIX domain socket
798 * @param abstract #TRUE to use abstract namespace
799 * @param error return location for error code
800 * @returns connection file descriptor or -1 on error
803 _dbus_connect_unix_socket (const char *path,
804 dbus_bool_t abstract,
809 struct sockaddr_un addr;
811 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
813 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
817 if (!_dbus_open_unix_socket (&fd, error))
819 _DBUS_ASSERT_ERROR_IS_SET(error);
822 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
825 addr.sun_family = AF_UNIX;
826 path_len = strlen (path);
830 #ifdef HAVE_ABSTRACT_SOCKETS
831 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
832 path_len++; /* Account for the extra nul byte added to the start of sun_path */
834 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
836 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
837 "Abstract socket name too long\n");
838 _dbus_close (fd, NULL);
842 strncpy (&addr.sun_path[1], path, path_len);
843 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
844 #else /* HAVE_ABSTRACT_SOCKETS */
845 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
846 "Operating system does not support abstract socket namespace\n");
847 _dbus_close (fd, NULL);
849 #endif /* ! HAVE_ABSTRACT_SOCKETS */
853 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
855 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
856 "Socket name too long\n");
857 _dbus_close (fd, NULL);
861 strncpy (addr.sun_path, path, path_len);
864 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
866 dbus_set_error (error,
867 _dbus_error_from_errno (errno),
868 "Failed to connect to socket %s: %s",
869 path, _dbus_strerror (errno));
871 _dbus_close (fd, NULL);
877 if (!_dbus_set_fd_nonblocking (fd, error))
879 _DBUS_ASSERT_ERROR_IS_SET (error);
881 _dbus_close (fd, NULL);
891 * Enables or disables the reception of credentials on the given socket during
892 * the next message transmission. This is only effective if the #LOCAL_CREDS
893 * system feature exists, in which case the other side of the connection does
894 * not have to do anything special to send the credentials.
896 * @param fd socket on which to change the #LOCAL_CREDS flag.
897 * @param on whether to enable or disable the #LOCAL_CREDS flag.
900 _dbus_set_local_creds (int fd, dbus_bool_t on)
902 dbus_bool_t retval = TRUE;
904 #if defined(HAVE_CMSGCRED)
905 /* NOOP just to make sure only one codepath is used
906 * and to prefer CMSGCRED
908 #elif defined(LOCAL_CREDS)
909 int val = on ? 1 : 0;
910 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
912 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
916 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
917 on ? "enabled" : "disabled", fd);
924 * Creates a socket and binds it to the given path,
925 * then listens on the socket. The socket is
926 * set to be nonblocking.
928 * Uses abstract sockets instead of filesystem-linked
929 * sockets if requested (it's possible only on Linux;
930 * see "man 7 unix" on Linux).
931 * On non-Linux abstract socket usage always fails.
933 * This will set FD_CLOEXEC for the socket returned
935 * @param path the socket name
936 * @param abstract #TRUE to use abstract namespace
937 * @param error return location for errors
938 * @returns the listening file descriptor or -1 on error
941 _dbus_listen_unix_socket (const char *path,
942 dbus_bool_t abstract,
946 struct sockaddr_un addr;
949 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
951 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
954 if (!_dbus_open_unix_socket (&listen_fd, error))
956 _DBUS_ASSERT_ERROR_IS_SET(error);
959 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
962 addr.sun_family = AF_UNIX;
963 path_len = strlen (path);
967 #ifdef HAVE_ABSTRACT_SOCKETS
968 /* remember that abstract names aren't nul-terminated so we rely
969 * on sun_path being filled in with zeroes above.
971 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
972 path_len++; /* Account for the extra nul byte added to the start of sun_path */
974 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
976 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
977 "Abstract socket name too long\n");
978 _dbus_close (listen_fd, NULL);
982 strncpy (&addr.sun_path[1], path, path_len);
983 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
984 #else /* HAVE_ABSTRACT_SOCKETS */
985 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
986 "Operating system does not support abstract socket namespace\n");
987 _dbus_close (listen_fd, NULL);
989 #endif /* ! HAVE_ABSTRACT_SOCKETS */
993 /* Discussed security implications of this with Nalin,
994 * and we couldn't think of where it would kick our ass, but
995 * it still seems a bit sucky. It also has non-security suckage;
996 * really we'd prefer to exit if the socket is already in use.
997 * But there doesn't seem to be a good way to do this.
999 * Just to be extra careful, I threw in the stat() - clearly
1000 * the stat() can't *fix* any security issue, but it at least
1001 * avoids inadvertent/accidental data loss.
1006 if (stat (path, &sb) == 0 &&
1007 S_ISSOCK (sb.st_mode))
1011 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1013 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1014 "Abstract socket name too long\n");
1015 _dbus_close (listen_fd, NULL);
1019 strncpy (addr.sun_path, path, path_len);
1022 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1024 dbus_set_error (error, _dbus_error_from_errno (errno),
1025 "Failed to bind socket \"%s\": %s",
1026 path, _dbus_strerror (errno));
1027 _dbus_close (listen_fd, NULL);
1031 if (listen (listen_fd, 30 /* backlog */) < 0)
1033 dbus_set_error (error, _dbus_error_from_errno (errno),
1034 "Failed to listen on socket \"%s\": %s",
1035 path, _dbus_strerror (errno));
1036 _dbus_close (listen_fd, NULL);
1040 if (!_dbus_set_local_creds (listen_fd, TRUE))
1042 dbus_set_error (error, _dbus_error_from_errno (errno),
1043 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1044 path, _dbus_strerror (errno));
1049 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1051 _DBUS_ASSERT_ERROR_IS_SET (error);
1052 _dbus_close (listen_fd, NULL);
1056 /* Try opening up the permissions, but if we can't, just go ahead
1057 * and continue, maybe it will be good enough.
1059 if (!abstract && chmod (path, 0777) < 0)
1060 _dbus_warn ("Could not set mode 0777 on socket %s\n",
1067 * Creates a socket and connects to a socket at the given host
1068 * and port. The connection fd is returned, and is set up as
1071 * This will set FD_CLOEXEC for the socket returned
1073 * @param host the host name to connect to
1074 * @param port the port to connect to
1075 * @param family the address family to listen on, NULL for all
1076 * @param error return location for error code
1077 * @returns connection file descriptor or -1 on error
1080 _dbus_connect_tcp_socket (const char *host,
1085 int saved_errno = 0;
1087 struct addrinfo hints;
1088 struct addrinfo *ai, *tmp;
1090 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1092 if (!_dbus_open_tcp_socket (&fd, error))
1094 _DBUS_ASSERT_ERROR_IS_SET(error);
1098 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1103 hints.ai_family = AF_UNSPEC;
1104 else if (!strcmp(family, "ipv4"))
1105 hints.ai_family = AF_INET;
1106 else if (!strcmp(family, "ipv6"))
1107 hints.ai_family = AF_INET6;
1110 dbus_set_error (error,
1111 DBUS_ERROR_BAD_ADDRESS,
1112 "Unknown address family %s", family);
1115 hints.ai_protocol = IPPROTO_TCP;
1116 hints.ai_socktype = SOCK_STREAM;
1117 hints.ai_flags = AI_ADDRCONFIG;
1119 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1121 dbus_set_error (error,
1122 _dbus_error_from_errno (errno),
1123 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1124 host, port, gai_strerror(res), res);
1125 _dbus_close (fd, NULL);
1132 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1135 _DBUS_ASSERT_ERROR_IS_SET(error);
1138 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1140 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1142 saved_errno = errno;
1143 _dbus_close(fd, NULL);
1155 dbus_set_error (error,
1156 _dbus_error_from_errno (saved_errno),
1157 "Failed to connect to socket \"%s:%s\" %s",
1158 host, port, _dbus_strerror(saved_errno));
1163 if (!_dbus_set_fd_nonblocking (fd, error))
1165 _dbus_close (fd, NULL);
1175 * Creates a socket and binds it to the given path, then listens on
1176 * the socket. The socket is set to be nonblocking. In case of port=0
1177 * a random free port is used and returned in the port parameter.
1178 * If inaddr_any is specified, the hostname is ignored.
1180 * This will set FD_CLOEXEC for the socket returned
1182 * @param host the host name to listen on
1183 * @param port the port to listen on, if zero a free port will be used
1184 * @param family the address family to listen on, NULL for all
1185 * @param retport string to return the actual port listened on
1186 * @param fds_p location to store returned file descriptors
1187 * @param error return location for errors
1188 * @returns the number of listening file descriptors or -1 on error
1191 _dbus_listen_tcp_socket (const char *host,
1194 DBusString *retport,
1199 int nlisten_fd = 0, *listen_fd = NULL, res, i;
1200 struct addrinfo hints;
1201 struct addrinfo *ai, *tmp;
1204 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1209 hints.ai_family = AF_UNSPEC;
1210 else if (!strcmp(family, "ipv4"))
1211 hints.ai_family = AF_INET;
1212 else if (!strcmp(family, "ipv6"))
1213 hints.ai_family = AF_INET6;
1216 dbus_set_error (error,
1217 DBUS_ERROR_BAD_ADDRESS,
1218 "Unknown address family %s", family);
1222 hints.ai_protocol = IPPROTO_TCP;
1223 hints.ai_socktype = SOCK_STREAM;
1224 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1226 redo_lookup_with_port:
1227 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1229 dbus_set_error (error,
1230 _dbus_error_from_errno (errno),
1231 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1232 host ? host : "*", port, gai_strerror(res), res);
1239 int fd = -1, *newlisten_fd;
1240 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1242 _DBUS_ASSERT_ERROR_IS_SET(error);
1245 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1247 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1249 saved_errno = errno;
1250 _dbus_close(fd, NULL);
1251 if (saved_errno == EADDRINUSE)
1253 /* Depending on kernel policy, it may or may not
1254 be neccessary to bind to both IPv4 & 6 addresses
1255 so ignore EADDRINUSE here */
1259 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1260 "Failed to bind socket \"%s:%s\": %s",
1261 host ? host : "*", port, _dbus_strerror (saved_errno));
1265 if (listen (fd, 30 /* backlog */) < 0)
1267 saved_errno = errno;
1268 _dbus_close (fd, NULL);
1269 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1270 "Failed to listen on socket \"%s:%s\": %s",
1271 host ? host : "*", port, _dbus_strerror (saved_errno));
1275 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1278 saved_errno = errno;
1279 _dbus_close (fd, NULL);
1280 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1281 "Failed to allocate file handle array: %s",
1282 _dbus_strerror (saved_errno));
1285 listen_fd = newlisten_fd;
1286 listen_fd[nlisten_fd] = fd;
1289 if (!_dbus_string_get_length(retport))
1291 /* If the user didn't specify a port, or used 0, then
1292 the kernel chooses a port. After the first address
1293 is bound to, we need to force all remaining addresses
1294 to use the same port */
1295 if (!port || !strcmp(port, "0"))
1297 struct sockaddr_storage addr;
1301 addrlen = sizeof(addr);
1302 getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1304 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
1305 portbuf, sizeof(portbuf),
1306 NI_NUMERICHOST)) != 0)
1308 dbus_set_error (error, _dbus_error_from_errno (errno),
1309 "Failed to resolve port \"%s:%s\": %s (%s)",
1310 host ? host : "*", port, gai_strerror(res), res);
1313 if (!_dbus_string_append(retport, portbuf))
1315 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1319 /* Release current address list & redo lookup */
1320 port = _dbus_string_get_const_data(retport);
1322 goto redo_lookup_with_port;
1326 if (!_dbus_string_append(retport, port))
1328 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1342 dbus_set_error (error, _dbus_error_from_errno (errno),
1343 "Failed to bind socket \"%s:%s\": %s",
1344 host ? host : "*", port, _dbus_strerror (errno));
1348 for (i = 0 ; i < nlisten_fd ; i++)
1350 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1363 for (i = 0 ; i < nlisten_fd ; i++)
1364 _dbus_close(listen_fd[i], NULL);
1365 dbus_free(listen_fd);
1370 write_credentials_byte (int server_fd,
1374 char buf[1] = { '\0' };
1375 #if defined(HAVE_CMSGCRED)
1378 struct cmsgcred cred;
1389 msg.msg_control = &cmsg;
1390 msg.msg_controllen = sizeof (cmsg);
1392 cmsg.hdr.cmsg_len = sizeof (cmsg);
1393 cmsg.hdr.cmsg_level = SOL_SOCKET;
1394 cmsg.hdr.cmsg_type = SCM_CREDS;
1397 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1401 #if defined(HAVE_CMSGCRED)
1402 bytes_written = sendmsg (server_fd, &msg, 0);
1404 bytes_written = write (server_fd, buf, 1);
1407 if (bytes_written < 0 && errno == EINTR)
1410 if (bytes_written < 0)
1412 dbus_set_error (error, _dbus_error_from_errno (errno),
1413 "Failed to write credentials byte: %s",
1414 _dbus_strerror (errno));
1417 else if (bytes_written == 0)
1419 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1420 "wrote zero bytes writing credentials byte");
1425 _dbus_assert (bytes_written == 1);
1426 _dbus_verbose ("wrote credentials byte\n");
1432 * Reads a single byte which must be nul (an error occurs otherwise),
1433 * and reads unix credentials if available. Clears the credentials
1434 * object, then adds pid/uid if available, so any previous credentials
1435 * stored in the object are lost.
1437 * Return value indicates whether a byte was read, not whether
1438 * we got valid credentials. On some systems, such as Linux,
1439 * reading/writing the byte isn't actually required, but we do it
1440 * anyway just to avoid multiple codepaths.
1442 * Fails if no byte is available, so you must select() first.
1444 * The point of the byte is that on some systems we have to
1445 * use sendmsg()/recvmsg() to transmit credentials.
1447 * @param client_fd the client file descriptor
1448 * @param credentials object to add client credentials to
1449 * @param error location to store error code
1450 * @returns #TRUE on success
1453 _dbus_read_credentials_socket (int client_fd,
1454 DBusCredentials *credentials,
1460 dbus_uid_t uid_read;
1461 dbus_pid_t pid_read;
1464 uid_read = DBUS_UID_UNSET;
1465 pid_read = DBUS_PID_UNSET;
1467 #ifdef HAVE_CMSGCRED
1470 struct cmsgcred cred;
1473 #elif defined(LOCAL_CREDS)
1476 struct sockcred cred;
1480 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1482 /* The POSIX spec certainly doesn't promise this, but
1483 * we need these assertions to fail as soon as we're wrong about
1484 * it so we can do the porting fixups
1486 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1487 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1488 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1490 _dbus_credentials_clear (credentials);
1492 /* Systems supporting LOCAL_CREDS are configured to have this feature
1493 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1494 * the connection. Therefore, the received message must carry the
1495 * credentials information without doing anything special.
1498 iov.iov_base = &buf;
1505 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1507 msg.msg_control = &cmsg;
1508 msg.msg_controllen = sizeof (cmsg);
1512 bytes_read = recvmsg (client_fd, &msg, 0);
1519 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1520 * normally only call read_credentials if the socket was ready
1524 dbus_set_error (error, _dbus_error_from_errno (errno),
1525 "Failed to read credentials byte: %s",
1526 _dbus_strerror (errno));
1529 else if (bytes_read == 0)
1531 /* this should not happen unless we are using recvmsg wrong,
1532 * so is essentially here for paranoia
1534 dbus_set_error (error, DBUS_ERROR_FAILED,
1535 "Failed to read credentials byte (zero-length read)");
1538 else if (buf != '\0')
1540 dbus_set_error (error, DBUS_ERROR_FAILED,
1541 "Credentials byte was not nul");
1545 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1546 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
1548 dbus_set_error (error, DBUS_ERROR_FAILED,
1549 "Message from recvmsg() was not SCM_CREDS");
1554 _dbus_verbose ("read credentials byte\n");
1559 int cr_len = sizeof (cr);
1561 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1562 cr_len == sizeof (cr))
1569 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1570 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1572 #elif defined(HAVE_CMSGCRED)
1573 pid_read = cmsg.cred.cmcred_pid;
1574 uid_read = cmsg.cred.cmcred_euid;
1575 #elif defined(LOCAL_CREDS)
1576 pid_read = DBUS_PID_UNSET;
1577 uid_read = cmsg.cred.sc_uid;
1578 /* Since we have already got the credentials from this socket, we can
1579 * disable its LOCAL_CREDS flag if it was ever set. */
1580 _dbus_set_local_creds (client_fd, FALSE);
1581 #elif defined(HAVE_GETPEEREID)
1584 if (getpeereid (client_fd, &euid, &egid) == 0)
1590 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1592 #elif defined(HAVE_GETPEERUCRED)
1593 ucred_t * ucred = NULL;
1594 if (getpeerucred (client_fd, &ucred) == 0)
1596 pid_read = ucred_getpid (ucred);
1597 uid_read = ucred_geteuid (ucred);
1599 /* generate audit session data based on socket ucred */
1600 adt_session_data_t *adth = NULL;
1601 adt_export_data_t *data = NULL;
1603 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1605 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1609 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1611 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1615 size = adt_export_session_data (adth, &data);
1618 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1622 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1626 (void) adt_end_session (adth);
1628 #endif /* HAVE_ADT */
1632 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1636 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1637 _dbus_verbose ("Socket credentials not supported on this OS\n");
1641 _dbus_verbose ("Credentials:"
1642 " pid "DBUS_PID_FORMAT
1643 " uid "DBUS_UID_FORMAT
1648 if (pid_read != DBUS_PID_UNSET)
1650 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1652 _DBUS_SET_OOM (error);
1657 if (uid_read != DBUS_UID_UNSET)
1659 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1661 _DBUS_SET_OOM (error);
1670 * Sends a single nul byte with our UNIX credentials as ancillary
1671 * data. Returns #TRUE if the data was successfully written. On
1672 * systems that don't support sending credentials, just writes a byte,
1673 * doesn't send any credentials. On some systems, such as Linux,
1674 * reading/writing the byte isn't actually required, but we do it
1675 * anyway just to avoid multiple codepaths.
1677 * Fails if no byte can be written, so you must select() first.
1679 * The point of the byte is that on some systems we have to
1680 * use sendmsg()/recvmsg() to transmit credentials.
1682 * @param server_fd file descriptor for connection to server
1683 * @param error return location for error code
1684 * @returns #TRUE if the byte was sent
1687 _dbus_send_credentials_socket (int server_fd,
1690 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1692 if (write_credentials_byte (server_fd, error))
1699 * Accepts a connection on a listening socket.
1700 * Handles EINTR for you.
1702 * This will enable FD_CLOEXEC for the returned socket.
1704 * @param listen_fd the listen file descriptor
1705 * @returns the connection fd of the client, or -1 on error
1708 _dbus_accept (int listen_fd)
1711 struct sockaddr addr;
1714 dbus_bool_t cloexec_done;
1717 addrlen = sizeof (addr);
1722 /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1723 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1724 cloexec_done = client_fd >= 0;
1726 if (client_fd < 0 && errno == ENOSYS)
1729 client_fd = accept (listen_fd, &addr, &addrlen);
1738 _dbus_verbose ("client fd %d accepted\n", client_fd);
1744 _dbus_fd_set_close_on_exec(client_fd);
1751 * Checks to make sure the given directory is
1752 * private to the user
1754 * @param dir the name of the directory
1755 * @param error error return
1756 * @returns #FALSE on failure
1759 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1761 const char *directory;
1764 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1766 directory = _dbus_string_get_const_data (dir);
1768 if (stat (directory, &sb) < 0)
1770 dbus_set_error (error, _dbus_error_from_errno (errno),
1771 "%s", _dbus_strerror (errno));
1776 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1777 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1779 dbus_set_error (error, DBUS_ERROR_FAILED,
1780 "%s directory is not private to the user", directory);
1788 fill_user_info_from_passwd (struct passwd *p,
1792 _dbus_assert (p->pw_name != NULL);
1793 _dbus_assert (p->pw_dir != NULL);
1795 info->uid = p->pw_uid;
1796 info->primary_gid = p->pw_gid;
1797 info->username = _dbus_strdup (p->pw_name);
1798 info->homedir = _dbus_strdup (p->pw_dir);
1800 if (info->username == NULL ||
1801 info->homedir == NULL)
1803 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1811 fill_user_info (DBusUserInfo *info,
1813 const DBusString *username,
1816 const char *username_c;
1818 /* exactly one of username/uid provided */
1819 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1820 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1822 info->uid = DBUS_UID_UNSET;
1823 info->primary_gid = DBUS_GID_UNSET;
1824 info->group_ids = NULL;
1825 info->n_group_ids = 0;
1826 info->username = NULL;
1827 info->homedir = NULL;
1829 if (username != NULL)
1830 username_c = _dbus_string_get_const_data (username);
1834 /* For now assuming that the getpwnam() and getpwuid() flavors
1835 * are always symmetrical, if not we have to add more configure
1839 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1845 struct passwd p_str;
1847 /* retrieve maximum needed size for buf */
1848 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1850 /* sysconf actually returns a long, but everything else expects size_t,
1851 * so just recast here.
1852 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1854 if ((long) buflen <= 0)
1860 buf = dbus_malloc (buflen);
1863 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1868 #ifdef HAVE_POSIX_GETPWNAM_R
1869 if (uid != DBUS_UID_UNSET)
1870 result = getpwuid_r (uid, &p_str, buf, buflen,
1873 result = getpwnam_r (username_c, &p_str, buf, buflen,
1876 if (uid != DBUS_UID_UNSET)
1877 p = getpwuid_r (uid, &p_str, buf, buflen);
1879 p = getpwnam_r (username_c, &p_str, buf, buflen);
1881 #endif /* !HAVE_POSIX_GETPWNAM_R */
1882 //Try a bigger buffer if ERANGE was returned
1883 if (result == ERANGE && buflen < 512 * 1024)
1893 if (result == 0 && p == &p_str)
1895 if (!fill_user_info_from_passwd (p, info, error))
1904 dbus_set_error (error, _dbus_error_from_errno (errno),
1905 "User \"%s\" unknown or no memory to allocate password entry\n",
1906 username_c ? username_c : "???");
1907 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1912 #else /* ! HAVE_GETPWNAM_R */
1914 /* I guess we're screwed on thread safety here */
1917 if (uid != DBUS_UID_UNSET)
1920 p = getpwnam (username_c);
1924 if (!fill_user_info_from_passwd (p, info, error))
1931 dbus_set_error (error, _dbus_error_from_errno (errno),
1932 "User \"%s\" unknown or no memory to allocate password entry\n",
1933 username_c ? username_c : "???");
1934 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1938 #endif /* ! HAVE_GETPWNAM_R */
1940 /* Fill this in so we can use it to get groups */
1941 username_c = info->username;
1943 #ifdef HAVE_GETGROUPLIST
1950 buf = dbus_new (gid_t, buf_count);
1953 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1957 if (getgrouplist (username_c,
1959 buf, &buf_count) < 0)
1961 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1964 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1972 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
1974 dbus_set_error (error,
1975 _dbus_error_from_errno (errno),
1976 "Failed to get groups for username \"%s\" primary GID "
1977 DBUS_GID_FORMAT ": %s\n",
1978 username_c, info->primary_gid,
1979 _dbus_strerror (errno));
1985 info->group_ids = dbus_new (dbus_gid_t, buf_count);
1986 if (info->group_ids == NULL)
1988 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1993 for (i = 0; i < buf_count; ++i)
1994 info->group_ids[i] = buf[i];
1996 info->n_group_ids = buf_count;
2000 #else /* HAVE_GETGROUPLIST */
2002 /* We just get the one group ID */
2003 info->group_ids = dbus_new (dbus_gid_t, 1);
2004 if (info->group_ids == NULL)
2006 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2010 info->n_group_ids = 1;
2012 (info->group_ids)[0] = info->primary_gid;
2014 #endif /* HAVE_GETGROUPLIST */
2016 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2021 _DBUS_ASSERT_ERROR_IS_SET (error);
2026 * Gets user info for the given username.
2028 * @param info user info object to initialize
2029 * @param username the username
2030 * @param error error return
2031 * @returns #TRUE on success
2034 _dbus_user_info_fill (DBusUserInfo *info,
2035 const DBusString *username,
2038 return fill_user_info (info, DBUS_UID_UNSET,
2043 * Gets user info for the given user ID.
2045 * @param info user info object to initialize
2046 * @param uid the user ID
2047 * @param error error return
2048 * @returns #TRUE on success
2051 _dbus_user_info_fill_uid (DBusUserInfo *info,
2055 return fill_user_info (info, uid,
2060 * Adds the credentials of the current process to the
2061 * passed-in credentials object.
2063 * @param credentials credentials to add to
2064 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2067 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2069 /* The POSIX spec certainly doesn't promise this, but
2070 * we need these assertions to fail as soon as we're wrong about
2071 * it so we can do the porting fixups
2073 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2074 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2075 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2077 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2079 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2086 * Append to the string the identity we would like to have when we
2087 * authenticate, on UNIX this is the current process UID and on
2088 * Windows something else, probably a Windows SID string. No escaping
2089 * is required, that is done in dbus-auth.c. The username here
2090 * need not be anything human-readable, it can be the machine-readable
2091 * form i.e. a user id.
2093 * @param str the string to append to
2094 * @returns #FALSE on no memory
2097 _dbus_append_user_from_current_process (DBusString *str)
2099 return _dbus_string_append_uint (str,
2104 * Gets our process ID
2105 * @returns process ID
2114 * @returns process UID
2122 /** Gets our effective UID
2123 * @returns process effective UID
2126 _dbus_geteuid (void)
2132 * The only reason this is separate from _dbus_getpid() is to allow it
2133 * on Windows for logging but not for other purposes.
2135 * @returns process ID to put in log messages
2138 _dbus_pid_for_log (void)
2144 * Gets a UID from a UID string.
2146 * @param uid_str the UID in string form
2147 * @param uid UID to fill in
2148 * @returns #TRUE if successfully filled in UID
2151 _dbus_parse_uid (const DBusString *uid_str,
2157 if (_dbus_string_get_length (uid_str) == 0)
2159 _dbus_verbose ("UID string was zero length\n");
2165 if (!_dbus_string_parse_int (uid_str, 0, &val,
2168 _dbus_verbose ("could not parse string as a UID\n");
2172 if (end != _dbus_string_get_length (uid_str))
2174 _dbus_verbose ("string contained trailing stuff after UID\n");
2184 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2186 #if DBUS_USE_ATOMIC_INT_486_COND
2187 /* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */
2188 /* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */
2189 static inline dbus_int32_t
2190 atomic_exchange_and_add (DBusAtomic *atomic,
2191 volatile dbus_int32_t val)
2193 register dbus_int32_t result;
2195 __asm__ __volatile__ ("lock; xaddl %0,%1"
2196 : "=r" (result), "=m" (atomic->value)
2197 : "0" (val), "m" (atomic->value));
2203 * Atomically increments an integer
2205 * @param atomic pointer to the integer to increment
2206 * @returns the value before incrementing
2208 * @todo implement arch-specific faster atomic ops
2211 _dbus_atomic_inc (DBusAtomic *atomic)
2213 #if DBUS_USE_ATOMIC_INT_486_COND
2214 return atomic_exchange_and_add (atomic, 1);
2217 _DBUS_LOCK (atomic);
2218 res = atomic->value;
2220 _DBUS_UNLOCK (atomic);
2226 * Atomically decrement an integer
2228 * @param atomic pointer to the integer to decrement
2229 * @returns the value before decrementing
2231 * @todo implement arch-specific faster atomic ops
2234 _dbus_atomic_dec (DBusAtomic *atomic)
2236 #if DBUS_USE_ATOMIC_INT_486_COND
2237 return atomic_exchange_and_add (atomic, -1);
2241 _DBUS_LOCK (atomic);
2242 res = atomic->value;
2244 _DBUS_UNLOCK (atomic);
2249 #ifdef DBUS_BUILD_TESTS
2251 * @returns process GID
2261 * Wrapper for poll().
2263 * @param fds the file descriptors to poll
2264 * @param n_fds number of descriptors in the array
2265 * @param timeout_milliseconds timeout or -1 for infinite
2266 * @returns numbers of fds with revents, or <0 on error
2269 _dbus_poll (DBusPollFD *fds,
2271 int timeout_milliseconds)
2273 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2274 /* This big thing is a constant expression and should get optimized
2275 * out of existence. So it's more robust than a configure check at
2278 if (_DBUS_POLLIN == POLLIN &&
2279 _DBUS_POLLPRI == POLLPRI &&
2280 _DBUS_POLLOUT == POLLOUT &&
2281 _DBUS_POLLERR == POLLERR &&
2282 _DBUS_POLLHUP == POLLHUP &&
2283 _DBUS_POLLNVAL == POLLNVAL &&
2284 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2285 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2286 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2287 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2288 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2289 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2290 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2292 return poll ((struct pollfd*) fds,
2294 timeout_milliseconds);
2298 /* We have to convert the DBusPollFD to an array of
2299 * struct pollfd, poll, and convert back.
2301 _dbus_warn ("didn't implement poll() properly for this system yet\n");
2304 #else /* ! HAVE_POLL */
2306 fd_set read_set, write_set, err_set;
2312 FD_ZERO (&read_set);
2313 FD_ZERO (&write_set);
2316 for (i = 0; i < n_fds; i++)
2318 DBusPollFD *fdp = &fds[i];
2320 if (fdp->events & _DBUS_POLLIN)
2321 FD_SET (fdp->fd, &read_set);
2323 if (fdp->events & _DBUS_POLLOUT)
2324 FD_SET (fdp->fd, &write_set);
2326 FD_SET (fdp->fd, &err_set);
2328 max_fd = MAX (max_fd, fdp->fd);
2331 tv.tv_sec = timeout_milliseconds / 1000;
2332 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2334 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2335 timeout_milliseconds < 0 ? NULL : &tv);
2339 for (i = 0; i < n_fds; i++)
2341 DBusPollFD *fdp = &fds[i];
2345 if (FD_ISSET (fdp->fd, &read_set))
2346 fdp->revents |= _DBUS_POLLIN;
2348 if (FD_ISSET (fdp->fd, &write_set))
2349 fdp->revents |= _DBUS_POLLOUT;
2351 if (FD_ISSET (fdp->fd, &err_set))
2352 fdp->revents |= _DBUS_POLLERR;
2361 * Get current time, as in gettimeofday().
2363 * @param tv_sec return location for number of seconds
2364 * @param tv_usec return location for number of microseconds (thousandths)
2367 _dbus_get_current_time (long *tv_sec,
2372 gettimeofday (&t, NULL);
2377 *tv_usec = t.tv_usec;
2381 * Appends the contents of the given file to the string,
2382 * returning error code. At the moment, won't open a file
2383 * more than a megabyte in size.
2385 * @param str the string to append to
2386 * @param filename filename to load
2387 * @param error place to set an error
2388 * @returns #FALSE if error was set
2391 _dbus_file_get_contents (DBusString *str,
2392 const DBusString *filename,
2399 const char *filename_c;
2401 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2403 filename_c = _dbus_string_get_const_data (filename);
2405 /* O_BINARY useful on Cygwin */
2406 fd = open (filename_c, O_RDONLY | O_BINARY);
2409 dbus_set_error (error, _dbus_error_from_errno (errno),
2410 "Failed to open \"%s\": %s",
2412 _dbus_strerror (errno));
2416 _dbus_verbose ("file fd %d opened\n", fd);
2418 if (fstat (fd, &sb) < 0)
2420 dbus_set_error (error, _dbus_error_from_errno (errno),
2421 "Failed to stat \"%s\": %s",
2423 _dbus_strerror (errno));
2425 _dbus_verbose ("fstat() failed: %s",
2426 _dbus_strerror (errno));
2428 _dbus_close (fd, NULL);
2433 if (sb.st_size > _DBUS_ONE_MEGABYTE)
2435 dbus_set_error (error, DBUS_ERROR_FAILED,
2436 "File size %lu of \"%s\" is too large.",
2437 (unsigned long) sb.st_size, filename_c);
2438 _dbus_close (fd, NULL);
2443 orig_len = _dbus_string_get_length (str);
2444 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
2448 while (total < (int) sb.st_size)
2450 bytes_read = _dbus_read (fd, str,
2451 sb.st_size - total);
2452 if (bytes_read <= 0)
2454 dbus_set_error (error, _dbus_error_from_errno (errno),
2455 "Error reading \"%s\": %s",
2457 _dbus_strerror (errno));
2459 _dbus_verbose ("read() failed: %s",
2460 _dbus_strerror (errno));
2462 _dbus_close (fd, NULL);
2463 _dbus_string_set_length (str, orig_len);
2467 total += bytes_read;
2470 _dbus_close (fd, NULL);
2473 else if (sb.st_size != 0)
2475 _dbus_verbose ("Can only open regular files at the moment.\n");
2476 dbus_set_error (error, DBUS_ERROR_FAILED,
2477 "\"%s\" is not a regular file",
2479 _dbus_close (fd, NULL);
2484 _dbus_close (fd, NULL);
2490 * Writes a string out to a file. If the file exists,
2491 * it will be atomically overwritten by the new data.
2493 * @param str the string to write out
2494 * @param filename the file to save string to
2495 * @param error error to be filled in on failure
2496 * @returns #FALSE on failure
2499 _dbus_string_save_to_file (const DBusString *str,
2500 const DBusString *filename,
2505 const char *filename_c;
2506 DBusString tmp_filename;
2507 const char *tmp_filename_c;
2509 dbus_bool_t need_unlink;
2512 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2516 need_unlink = FALSE;
2518 if (!_dbus_string_init (&tmp_filename))
2520 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2524 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2526 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2527 _dbus_string_free (&tmp_filename);
2531 if (!_dbus_string_append (&tmp_filename, "."))
2533 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2534 _dbus_string_free (&tmp_filename);
2538 #define N_TMP_FILENAME_RANDOM_BYTES 8
2539 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2541 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2542 _dbus_string_free (&tmp_filename);
2546 filename_c = _dbus_string_get_const_data (filename);
2547 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2549 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2553 dbus_set_error (error, _dbus_error_from_errno (errno),
2554 "Could not create %s: %s", tmp_filename_c,
2555 _dbus_strerror (errno));
2559 _dbus_verbose ("tmp file fd %d opened\n", fd);
2564 bytes_to_write = _dbus_string_get_length (str);
2566 while (total < bytes_to_write)
2570 bytes_written = _dbus_write (fd, str, total,
2571 bytes_to_write - total);
2573 if (bytes_written <= 0)
2575 dbus_set_error (error, _dbus_error_from_errno (errno),
2576 "Could not write to %s: %s", tmp_filename_c,
2577 _dbus_strerror (errno));
2582 total += bytes_written;
2587 dbus_set_error (error, _dbus_error_from_errno (errno),
2588 "Could not synchronize file %s: %s",
2589 tmp_filename_c, _dbus_strerror (errno));
2594 if (!_dbus_close (fd, NULL))
2596 dbus_set_error (error, _dbus_error_from_errno (errno),
2597 "Could not close file %s: %s",
2598 tmp_filename_c, _dbus_strerror (errno));
2605 if (rename (tmp_filename_c, filename_c) < 0)
2607 dbus_set_error (error, _dbus_error_from_errno (errno),
2608 "Could not rename %s to %s: %s",
2609 tmp_filename_c, filename_c,
2610 _dbus_strerror (errno));
2615 need_unlink = FALSE;
2620 /* close first, then unlink, to prevent ".nfs34234235" garbage
2625 _dbus_close (fd, NULL);
2627 if (need_unlink && unlink (tmp_filename_c) < 0)
2628 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2629 tmp_filename_c, _dbus_strerror (errno));
2631 _dbus_string_free (&tmp_filename);
2634 _DBUS_ASSERT_ERROR_IS_SET (error);
2639 /** Makes the file readable by every user in the system.
2641 * @param filename the filename
2642 * @param error error location
2643 * @returns #TRUE if the file's permissions could be changed.
2646 _dbus_make_file_world_readable(const DBusString *filename,
2649 const char *filename_c;
2651 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2653 filename_c = _dbus_string_get_const_data (filename);
2654 if (chmod (filename_c, 0644) == -1)
2656 dbus_set_error (error,
2658 "Could not change permissions of file %s: %s\n",
2660 _dbus_strerror (errno));
2666 /** Creates the given file, failing if the file already exists.
2668 * @param filename the filename
2669 * @param error error location
2670 * @returns #TRUE if we created the file and it didn't exist
2673 _dbus_create_file_exclusively (const DBusString *filename,
2677 const char *filename_c;
2679 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2681 filename_c = _dbus_string_get_const_data (filename);
2683 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2687 dbus_set_error (error,
2689 "Could not create file %s: %s\n",
2691 _dbus_strerror (errno));
2695 _dbus_verbose ("exclusive file fd %d opened\n", fd);
2697 if (!_dbus_close (fd, NULL))
2699 dbus_set_error (error,
2701 "Could not close file %s: %s\n",
2703 _dbus_strerror (errno));
2711 * Deletes the given file.
2713 * @param filename the filename
2714 * @param error error location
2716 * @returns #TRUE if unlink() succeeded
2719 _dbus_delete_file (const DBusString *filename,
2722 const char *filename_c;
2724 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2726 filename_c = _dbus_string_get_const_data (filename);
2728 if (unlink (filename_c) < 0)
2730 dbus_set_error (error, DBUS_ERROR_FAILED,
2731 "Failed to delete file %s: %s\n",
2732 filename_c, _dbus_strerror (errno));
2740 * Creates a directory; succeeds if the directory
2741 * is created or already existed.
2743 * @param filename directory filename
2744 * @param error initialized error object
2745 * @returns #TRUE on success
2748 _dbus_create_directory (const DBusString *filename,
2751 const char *filename_c;
2753 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2755 filename_c = _dbus_string_get_const_data (filename);
2757 if (mkdir (filename_c, 0700) < 0)
2759 if (errno == EEXIST)
2762 dbus_set_error (error, DBUS_ERROR_FAILED,
2763 "Failed to create directory %s: %s\n",
2764 filename_c, _dbus_strerror (errno));
2772 * Appends the given filename to the given directory.
2774 * @todo it might be cute to collapse multiple '/' such as "foo//"
2777 * @param dir the directory name
2778 * @param next_component the filename
2779 * @returns #TRUE on success
2782 _dbus_concat_dir_and_file (DBusString *dir,
2783 const DBusString *next_component)
2785 dbus_bool_t dir_ends_in_slash;
2786 dbus_bool_t file_starts_with_slash;
2788 if (_dbus_string_get_length (dir) == 0 ||
2789 _dbus_string_get_length (next_component) == 0)
2792 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2793 _dbus_string_get_length (dir) - 1);
2795 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2797 if (dir_ends_in_slash && file_starts_with_slash)
2799 _dbus_string_shorten (dir, 1);
2801 else if (!(dir_ends_in_slash || file_starts_with_slash))
2803 if (!_dbus_string_append_byte (dir, '/'))
2807 return _dbus_string_copy (next_component, 0, dir,
2808 _dbus_string_get_length (dir));
2811 /** nanoseconds in a second */
2812 #define NANOSECONDS_PER_SECOND 1000000000
2813 /** microseconds in a second */
2814 #define MICROSECONDS_PER_SECOND 1000000
2815 /** milliseconds in a second */
2816 #define MILLISECONDS_PER_SECOND 1000
2817 /** nanoseconds in a millisecond */
2818 #define NANOSECONDS_PER_MILLISECOND 1000000
2819 /** microseconds in a millisecond */
2820 #define MICROSECONDS_PER_MILLISECOND 1000
2823 * Sleeps the given number of milliseconds.
2824 * @param milliseconds number of milliseconds
2827 _dbus_sleep_milliseconds (int milliseconds)
2829 #ifdef HAVE_NANOSLEEP
2830 struct timespec req;
2831 struct timespec rem;
2833 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2834 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2838 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2840 #elif defined (HAVE_USLEEP)
2841 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2842 #else /* ! HAVE_USLEEP */
2843 sleep (MAX (milliseconds / 1000, 1));
2848 _dbus_generate_pseudorandom_bytes (DBusString *str,
2854 old_len = _dbus_string_get_length (str);
2856 if (!_dbus_string_lengthen (str, n_bytes))
2859 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2861 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2867 * Generates the given number of random bytes,
2868 * using the best mechanism we can come up with.
2870 * @param str the string
2871 * @param n_bytes the number of random bytes to append to string
2872 * @returns #TRUE on success, #FALSE if no memory
2875 _dbus_generate_random_bytes (DBusString *str,
2881 /* FALSE return means "no memory", if it could
2882 * mean something else then we'd need to return
2883 * a DBusError. So we always fall back to pseudorandom
2887 old_len = _dbus_string_get_length (str);
2890 /* note, urandom on linux will fall back to pseudorandom */
2891 fd = open ("/dev/urandom", O_RDONLY);
2893 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2895 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2897 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2899 _dbus_close (fd, NULL);
2900 _dbus_string_set_length (str, old_len);
2901 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2904 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2907 _dbus_close (fd, NULL);
2913 * Exit the process, returning the given value.
2915 * @param code the exit code
2918 _dbus_exit (int code)
2924 * A wrapper around strerror() because some platforms
2925 * may be lame and not have strerror(). Also, never
2928 * @param error_number errno.
2929 * @returns error description.
2932 _dbus_strerror (int error_number)
2936 msg = strerror (error_number);
2944 * signal (SIGPIPE, SIG_IGN);
2947 _dbus_disable_sigpipe (void)
2949 signal (SIGPIPE, SIG_IGN);
2953 * Sets the file descriptor to be close
2954 * on exec. Should be called for all file
2955 * descriptors in D-Bus code.
2957 * @param fd the file descriptor
2960 _dbus_fd_set_close_on_exec (int fd)
2964 val = fcntl (fd, F_GETFD, 0);
2971 fcntl (fd, F_SETFD, val);
2975 * Closes a file descriptor.
2977 * @param fd the file descriptor
2978 * @param error error object
2979 * @returns #FALSE if error set
2982 _dbus_close (int fd,
2985 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2993 dbus_set_error (error, _dbus_error_from_errno (errno),
2994 "Could not close fd %d", fd);
3002 * Duplicates a file descriptor. Makes sure the fd returned is >= 3
3003 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
3005 * @param fd the file descriptor to duplicate
3006 * @returns duplicated file descriptor
3014 #ifdef F_DUPFD_CLOEXEC
3015 dbus_bool_t cloexec_done;
3017 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3018 cloexec_done = new_fd >= 0;
3020 if (new_fd < 0 && errno == EINVAL)
3023 new_fd = fcntl(fd, F_DUPFD, 3);
3028 dbus_set_error (error, _dbus_error_from_errno (errno),
3029 "Could not duplicate fd %d", fd);
3033 #ifndef F_DUPFD_CLOEXEC
3037 _dbus_fd_set_close_on_exec(new_fd);
3044 * Sets a file descriptor to be nonblocking.
3046 * @param fd the file descriptor.
3047 * @param error address of error location.
3048 * @returns #TRUE on success.
3051 _dbus_set_fd_nonblocking (int fd,
3056 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3058 val = fcntl (fd, F_GETFL, 0);
3061 dbus_set_error (error, _dbus_error_from_errno (errno),
3062 "Failed to get flags from file descriptor %d: %s",
3063 fd, _dbus_strerror (errno));
3064 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3065 _dbus_strerror (errno));
3069 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3071 dbus_set_error (error, _dbus_error_from_errno (errno),
3072 "Failed to set nonblocking flag of file descriptor %d: %s",
3073 fd, _dbus_strerror (errno));
3074 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3075 fd, _dbus_strerror (errno));
3084 * On GNU libc systems, print a crude backtrace to stderr. On other
3085 * systems, print "no backtrace support" and block for possible gdb
3086 * attachment if an appropriate environment variable is set.
3089 _dbus_print_backtrace (void)
3091 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3097 bt_size = backtrace (bt, 500);
3099 syms = backtrace_symbols (bt, bt_size);
3104 /* don't use dbus_warn since it can _dbus_abort() */
3105 fprintf (stderr, " %s\n", syms[i]);
3111 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3112 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3114 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3119 * Creates a full-duplex pipe (as in socketpair()).
3120 * Sets both ends of the pipe nonblocking.
3122 * Marks both file descriptors as close-on-exec
3124 * @todo libdbus only uses this for the debug-pipe server, so in
3125 * principle it could be in dbus-sysdeps-util.c, except that
3126 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
3127 * debug-pipe server is used.
3129 * @param fd1 return location for one end
3130 * @param fd2 return location for the other end
3131 * @param blocking #TRUE if pipe should be blocking
3132 * @param error error return
3133 * @returns #FALSE on failure (if error is set)
3136 _dbus_full_duplex_pipe (int *fd1,
3138 dbus_bool_t blocking,
3141 #ifdef HAVE_SOCKETPAIR
3146 dbus_bool_t cloexec_done;
3148 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3149 cloexec_done = retval >= 0;
3151 if (retval < 0 && errno == EINVAL)
3154 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3159 dbus_set_error (error, _dbus_error_from_errno (errno),
3160 "Could not create full-duplex pipe");
3164 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3170 _dbus_fd_set_close_on_exec (fds[0]);
3171 _dbus_fd_set_close_on_exec (fds[1]);
3175 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3176 !_dbus_set_fd_nonblocking (fds[1], NULL)))
3178 dbus_set_error (error, _dbus_error_from_errno (errno),
3179 "Could not set full-duplex pipe nonblocking");
3181 _dbus_close (fds[0], NULL);
3182 _dbus_close (fds[1], NULL);
3190 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3195 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3196 dbus_set_error (error, DBUS_ERROR_FAILED,
3197 "_dbus_full_duplex_pipe() not implemented on this OS");
3203 * Measure the length of the given format string and arguments,
3204 * not including the terminating nul.
3206 * @param format a printf-style format string
3207 * @param args arguments for the format string
3208 * @returns length of the given format string and args
3211 _dbus_printf_string_upper_bound (const char *format,
3215 return vsnprintf (&c, 1, format, args);
3219 * Gets the temporary files directory by inspecting the environment variables
3220 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3222 * @returns location of temp directory
3225 _dbus_get_tmpdir(void)
3227 static const char* tmpdir = NULL;
3231 /* TMPDIR is what glibc uses, then
3232 * glibc falls back to the P_tmpdir macro which
3233 * just expands to "/tmp"
3236 tmpdir = getenv("TMPDIR");
3238 /* These two env variables are probably
3239 * broken, but maybe some OS uses them?
3242 tmpdir = getenv("TMP");
3244 tmpdir = getenv("TEMP");
3246 /* And this is the sane fallback. */
3251 _dbus_assert(tmpdir != NULL);
3257 * Determines the address of the session bus by querying a
3258 * platform-specific method.
3260 * If successful, returns #TRUE and appends the address to @p
3261 * address. If a failure happens, returns #FALSE and
3262 * sets an error in @p error.
3264 * @param address a DBusString where the address can be stored
3265 * @param error a DBusError to store the error in case of failure
3266 * @returns #TRUE on success, #FALSE if an error happened
3269 _dbus_get_autolaunch_address (DBusString *address,
3272 static char *argv[6];
3273 int address_pipe[2] = { -1, -1 };
3274 int errors_pipe[2] = { -1, -1 };
3283 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3286 if (!_dbus_string_init (&uuid))
3288 _DBUS_SET_OOM (error);
3292 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3294 _DBUS_SET_OOM (error);
3299 argv[i] = "dbus-launch";
3301 argv[i] = "--autolaunch";
3303 argv[i] = _dbus_string_get_data (&uuid);
3305 argv[i] = "--binary-syntax";
3307 argv[i] = "--close-stderr";
3312 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3314 orig_len = _dbus_string_get_length (address);
3318 if (pipe (address_pipe) < 0)
3320 dbus_set_error (error, _dbus_error_from_errno (errno),
3321 "Failed to create a pipe: %s",
3322 _dbus_strerror (errno));
3323 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
3324 _dbus_strerror (errno));
3327 if (pipe (errors_pipe) < 0)
3329 dbus_set_error (error, _dbus_error_from_errno (errno),
3330 "Failed to create a pipe: %s",
3331 _dbus_strerror (errno));
3332 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
3333 _dbus_strerror (errno));
3340 dbus_set_error (error, _dbus_error_from_errno (errno),
3341 "Failed to fork(): %s",
3342 _dbus_strerror (errno));
3343 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
3344 _dbus_strerror (errno));
3354 fd = open ("/dev/null", O_RDWR);
3356 /* huh?! can't open /dev/null? */
3359 _dbus_verbose ("/dev/null fd %d opened\n", fd);
3362 close (address_pipe[READ_END]);
3363 close (errors_pipe[READ_END]);
3364 close (0); /* close stdin */
3365 close (1); /* close stdout */
3366 close (2); /* close stderr */
3368 if (dup2 (fd, 0) == -1)
3370 if (dup2 (address_pipe[WRITE_END], 1) == -1)
3372 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3375 maxfds = sysconf (_SC_OPEN_MAX);
3376 /* Pick something reasonable if for some reason sysconf
3381 /* close all inherited fds */
3382 for (i = 3; i < maxfds; i++)
3385 execv (DBUS_BINDIR "/dbus-launch", argv);
3387 /* failed, try searching PATH */
3388 execvp ("dbus-launch", argv);
3390 /* still nothing, we failed */
3394 /* parent process */
3395 close (address_pipe[WRITE_END]);
3396 close (errors_pipe[WRITE_END]);
3397 address_pipe[WRITE_END] = -1;
3398 errors_pipe[WRITE_END] = -1;
3403 ret = _dbus_read (address_pipe[READ_END], address, 1024);
3407 /* reap the child process to avoid it lingering as zombie */
3410 ret = waitpid (pid, &status, 0);
3412 while (ret == -1 && errno == EINTR);
3414 /* We succeeded if the process exited with status 0 and
3415 anything was read */
3416 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
3417 _dbus_string_get_length (address) == orig_len)
3419 /* The process ended with error */
3420 DBusString error_message;
3421 _dbus_string_init (&error_message);
3425 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3429 _dbus_string_set_length (address, orig_len);
3430 if (_dbus_string_get_length (&error_message) > 0)
3431 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3432 "dbus-launch failed to autolaunch D-Bus session: %s",
3433 _dbus_string_get_data (&error_message));
3435 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3436 "Failed to execute dbus-launch to autolaunch D-Bus session");
3444 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3446 _DBUS_ASSERT_ERROR_IS_SET (error);
3448 if (address_pipe[0] != -1)
3449 close (address_pipe[0]);
3450 if (address_pipe[1] != -1)
3451 close (address_pipe[1]);
3452 if (errors_pipe[0] != -1)
3453 close (errors_pipe[0]);
3454 if (errors_pipe[1] != -1)
3455 close (errors_pipe[1]);
3457 _dbus_string_free (&uuid);
3462 * Reads the uuid of the machine we're running on from
3463 * the dbus configuration. Optionally try to create it
3464 * (only root can do this usually).
3466 * On UNIX, reads a file that gets created by dbus-uuidgen
3467 * in a post-install script. On Windows, if there's a standard
3468 * machine uuid we could just use that, but I can't find one
3469 * with the right properties (the hardware profile guid can change
3470 * without rebooting I believe). If there's no standard one
3471 * we might want to use the registry instead of a file for
3472 * this, and I'm not sure how we'd ensure the uuid gets created.
3474 * @param machine_id guid to init with the machine's uuid
3475 * @param create_if_not_found try to create the uuid if it doesn't exist
3476 * @param error the error return
3477 * @returns #FALSE if the error is set
3480 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3481 dbus_bool_t create_if_not_found,
3484 DBusString filename;
3485 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3486 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3489 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3490 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3494 * Returns the standard directories for a session bus to look for service
3497 * On UNIX this should be the standard xdg freedesktop.org data directories:
3499 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3500 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3506 * @param dirs the directory list we are returning
3507 * @returns #FALSE on OOM
3511 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3513 const char *xdg_data_home;
3514 const char *xdg_data_dirs;
3515 DBusString servicedir_path;
3517 if (!_dbus_string_init (&servicedir_path))
3520 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3521 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3523 if (xdg_data_dirs != NULL)
3525 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3528 if (!_dbus_string_append (&servicedir_path, ":"))
3533 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3538 * add configured datadir to defaults
3539 * this may be the same as an xdg dir
3540 * however the config parser should take
3541 * care of duplicates
3543 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3546 if (xdg_data_home != NULL)
3548 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3553 const DBusString *homedir;
3554 DBusString local_share;
3556 if (!_dbus_homedir_from_current_process (&homedir))
3559 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3562 _dbus_string_init_const (&local_share, "/.local/share");
3563 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3567 if (!_dbus_split_paths_and_append (&servicedir_path,
3568 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3572 _dbus_string_free (&servicedir_path);
3576 _dbus_string_free (&servicedir_path);
3582 * Returns the standard directories for a system bus to look for service
3585 * On UNIX this should be the standard xdg freedesktop.org data directories:
3587 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3593 * On Windows there is no system bus and this function can return nothing.
3595 * @param dirs the directory list we are returning
3596 * @returns #FALSE on OOM
3600 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3602 const char *xdg_data_dirs;
3603 DBusString servicedir_path;
3605 if (!_dbus_string_init (&servicedir_path))
3608 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3610 if (xdg_data_dirs != NULL)
3612 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3615 if (!_dbus_string_append (&servicedir_path, ":"))
3620 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3625 * add configured datadir to defaults
3626 * this may be the same as an xdg dir
3627 * however the config parser should take
3628 * care of duplicates
3630 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3633 if (!_dbus_split_paths_and_append (&servicedir_path,
3634 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3638 _dbus_string_free (&servicedir_path);
3642 _dbus_string_free (&servicedir_path);
3647 * Append the absolute path of the system.conf file
3648 * (there is no system bus on Windows so this can just
3649 * return FALSE and print a warning or something)
3651 * @param str the string to append to
3652 * @returns #FALSE if no memory
3655 _dbus_append_system_config_file (DBusString *str)
3657 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3661 * Append the absolute path of the session.conf file.
3663 * @param str the string to append to
3664 * @returns #FALSE if no memory
3667 _dbus_append_session_config_file (DBusString *str)
3669 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3673 * Called when the bus daemon is signaled to reload its configuration; any
3674 * caches should be nuked. Of course any caches that need explicit reload
3675 * are probably broken, but c'est la vie.
3680 _dbus_flush_caches (void)
3682 _dbus_user_database_flush_system ();
3686 * Appends the directory in which a keyring for the given credentials
3687 * should be stored. The credentials should have either a Windows or
3688 * UNIX user in them. The directory should be an absolute path.
3690 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3691 * be something else, since the dotfile convention is not normal on Windows.
3693 * @param directory string to append directory to
3694 * @param credentials credentials the directory should be for
3696 * @returns #FALSE on no memory
3699 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3700 DBusCredentials *credentials)
3706 _dbus_assert (credentials != NULL);
3707 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3709 if (!_dbus_string_init (&homedir))
3712 uid = _dbus_credentials_get_unix_uid (credentials);
3713 _dbus_assert (uid != DBUS_UID_UNSET);
3715 if (!_dbus_homedir_from_uid (uid, &homedir))
3718 #ifdef DBUS_BUILD_TESTS
3720 const char *override;
3722 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3723 if (override != NULL && *override != '\0')
3725 _dbus_string_set_length (&homedir, 0);
3726 if (!_dbus_string_append (&homedir, override))
3729 _dbus_verbose ("Using fake homedir for testing: %s\n",
3730 _dbus_string_get_const_data (&homedir));
3734 static dbus_bool_t already_warned = FALSE;
3735 if (!already_warned)
3737 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3738 already_warned = TRUE;
3744 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3745 if (!_dbus_concat_dir_and_file (&homedir,
3749 if (!_dbus_string_copy (&homedir, 0,
3750 directory, _dbus_string_get_length (directory))) {
3754 _dbus_string_free (&homedir);
3758 _dbus_string_free (&homedir);
3764 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3765 * for Winsock so is abstracted)
3767 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3770 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3772 return errno == EAGAIN || errno == EWOULDBLOCK;
3776 * Checks whether file descriptors may be passed via the socket
3778 * @param fd the socket
3779 * @return TRUE when fd passing over this socket is supported
3783 _dbus_socket_can_pass_unix_fd(int fd) {
3788 struct sockaddr_storage storage;
3789 struct sockaddr_un un;
3792 socklen_t sa_len = sizeof(sa_buf);
3796 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3799 return sa_buf.sa.sa_family == AF_UNIX;
3807 /* tests in dbus-sysdeps-util.c */