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"
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,
97 *fd_p = socket (domain, type, protocol);
100 _dbus_verbose ("socket fd %d opened\n", *fd_p);
105 dbus_set_error(error,
106 _dbus_error_from_errno (errno),
107 "Failed to open socket: %s",
108 _dbus_strerror (errno));
114 _dbus_open_tcp_socket (int *fd,
117 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
121 * Opens a UNIX domain socket (as in the socket() call).
122 * Does not bind the socket.
123 * @param fd return location for socket descriptor
124 * @param error return location for an error
125 * @returns #FALSE if error is set
128 _dbus_open_unix_socket (int *fd,
131 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
135 * Closes a socket. Should not be used on non-socket
136 * file descriptors or handles.
138 * @param fd the socket
139 * @param error return location for an error
140 * @returns #FALSE if error is set
143 _dbus_close_socket (int fd,
146 return _dbus_close (fd, error);
150 * Like _dbus_read(), but only works on sockets so is
151 * available on Windows.
153 * @param fd the socket
154 * @param buffer string to append data to
155 * @param count max amount of data to read
156 * @returns number of bytes appended to the string
159 _dbus_read_socket (int fd,
163 return _dbus_read (fd, buffer, count);
167 * Like _dbus_write(), but only supports sockets
168 * and is thus available on Windows.
170 * @param fd the file descriptor to write
171 * @param buffer the buffer to write data from
172 * @param start the first byte in the buffer to write
173 * @param len the number of bytes to try to write
174 * @returns the number of bytes written or -1 on error
177 _dbus_write_socket (int fd,
178 const DBusString *buffer,
182 return _dbus_write (fd, buffer, start, len);
186 * write data to a pipe.
188 * @param pipe the pipe instance
189 * @param buffer the buffer to write data from
190 * @param start the first byte in the buffer to write
191 * @param len the number of bytes to try to write
192 * @param error error return
193 * @returns the number of bytes written or -1 on error
196 _dbus_pipe_write (DBusPipe *pipe,
197 const DBusString *buffer,
204 written = _dbus_write (pipe->fd_or_handle, buffer, start, len);
207 dbus_set_error (error, DBUS_ERROR_FAILED,
208 "Writing to pipe: %s\n",
209 _dbus_strerror (errno));
217 * @param pipe the pipe instance
218 * @param error return location for an error
219 * @returns #FALSE if error is set
222 _dbus_pipe_close (DBusPipe *pipe,
225 if (_dbus_close (pipe->fd_or_handle, error) < 0)
231 _dbus_pipe_invalidate (pipe);
237 * Like _dbus_write_two() but only works on sockets and is thus
238 * available on Windows.
240 * @param fd the file descriptor
241 * @param buffer1 first buffer
242 * @param start1 first byte to write in first buffer
243 * @param len1 number of bytes to write from first buffer
244 * @param buffer2 second buffer, or #NULL
245 * @param start2 first byte to write in second buffer
246 * @param len2 number of bytes to write in second buffer
247 * @returns total bytes written from both buffers, or -1 on error
250 _dbus_write_socket_two (int fd,
251 const DBusString *buffer1,
254 const DBusString *buffer2,
258 return _dbus_write_two (fd, buffer1, start1, len1,
259 buffer2, start2, len2);
264 * Thin wrapper around the read() system call that appends
265 * the data it reads to the DBusString buffer. It appends
266 * up to the given count, and returns the same value
267 * and same errno as read(). The only exception is that
268 * _dbus_read() handles EINTR for you. Also, _dbus_read() can
269 * return ENOMEM, even though regular UNIX read doesn't.
271 * Unlike _dbus_read_socket(), _dbus_read() is not available
274 * @param fd the file descriptor to read from
275 * @param buffer the buffer to append data to
276 * @param count the amount of data to read
277 * @returns the number of bytes read or -1
288 _dbus_assert (count >= 0);
290 start = _dbus_string_get_length (buffer);
292 if (!_dbus_string_lengthen (buffer, count))
298 data = _dbus_string_get_data_len (buffer, start, count);
302 bytes_read = read (fd, data, count);
310 /* put length back (note that this doesn't actually realloc anything) */
311 _dbus_string_set_length (buffer, start);
317 /* put length back (doesn't actually realloc) */
318 _dbus_string_set_length (buffer, start + bytes_read);
322 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
330 * Thin wrapper around the write() system call that writes a part of a
331 * DBusString and handles EINTR for you.
333 * @param fd the file descriptor to write
334 * @param buffer the buffer to write data from
335 * @param start the first byte in the buffer to write
336 * @param len the number of bytes to try to write
337 * @returns the number of bytes written or -1 on error
341 const DBusString *buffer,
348 data = _dbus_string_get_const_data_len (buffer, start, len);
352 bytes_written = write (fd, data, len);
354 if (bytes_written < 0 && errno == EINTR)
358 if (bytes_written > 0)
359 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
362 return bytes_written;
366 * Like _dbus_write() but will use writev() if possible
367 * to write both buffers in sequence. The return value
368 * is the number of bytes written in the first buffer,
369 * plus the number written in the second. If the first
370 * buffer is written successfully and an error occurs
371 * writing the second, the number of bytes in the first
372 * is returned (i.e. the error is ignored), on systems that
373 * don't have writev. Handles EINTR for you.
374 * The second buffer may be #NULL.
376 * @param fd the file descriptor
377 * @param buffer1 first buffer
378 * @param start1 first byte to write in first buffer
379 * @param len1 number of bytes to write from first buffer
380 * @param buffer2 second buffer, or #NULL
381 * @param start2 first byte to write in second buffer
382 * @param len2 number of bytes to write in second buffer
383 * @returns total bytes written from both buffers, or -1 on error
386 _dbus_write_two (int fd,
387 const DBusString *buffer1,
390 const DBusString *buffer2,
394 _dbus_assert (buffer1 != NULL);
395 _dbus_assert (start1 >= 0);
396 _dbus_assert (start2 >= 0);
397 _dbus_assert (len1 >= 0);
398 _dbus_assert (len2 >= 0);
402 struct iovec vectors[2];
407 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
410 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
418 vectors[0].iov_base = (char*) data1;
419 vectors[0].iov_len = len1;
420 vectors[1].iov_base = (char*) data2;
421 vectors[1].iov_len = len2;
425 bytes_written = writev (fd,
429 if (bytes_written < 0 && errno == EINTR)
432 return bytes_written;
434 #else /* HAVE_WRITEV */
438 ret1 = _dbus_write (fd, buffer1, start1, len1);
439 if (ret1 == len1 && buffer2 != NULL)
441 ret2 = _dbus_write (fd, buffer2, start2, len2);
443 ret2 = 0; /* we can't report an error as the first write was OK */
450 #endif /* !HAVE_WRITEV */
453 #define _DBUS_MAX_SUN_PATH_LENGTH 99
456 * @def _DBUS_MAX_SUN_PATH_LENGTH
458 * Maximum length of the path to a UNIX domain socket,
459 * sockaddr_un::sun_path member. POSIX requires that all systems
460 * support at least 100 bytes here, including the nul termination.
461 * We use 99 for the max value to allow for the nul.
463 * We could probably also do sizeof (addr.sun_path)
464 * but this way we are the same on all platforms
465 * which is probably a good idea.
469 * Creates a socket and connects it to the UNIX domain socket at the
470 * given path. The connection fd is returned, and is set up as
473 * Uses abstract sockets instead of filesystem-linked sockets if
474 * requested (it's possible only on Linux; see "man 7 unix" on Linux).
475 * On non-Linux abstract socket usage always fails.
477 * @param path the path to UNIX domain socket
478 * @param abstract #TRUE to use abstract namespace
479 * @param error return location for error code
480 * @returns connection file descriptor or -1 on error
483 _dbus_connect_unix_socket (const char *path,
484 dbus_bool_t abstract,
489 struct sockaddr_un addr;
491 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
493 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
497 if (!_dbus_open_unix_socket (&fd, error))
499 _DBUS_ASSERT_ERROR_IS_SET(error);
502 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
505 addr.sun_family = AF_UNIX;
506 path_len = strlen (path);
510 #ifdef HAVE_ABSTRACT_SOCKETS
511 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
512 path_len++; /* Account for the extra nul byte added to the start of sun_path */
514 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
516 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
517 "Abstract socket name too long\n");
518 _dbus_close (fd, NULL);
522 strncpy (&addr.sun_path[1], path, path_len);
523 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
524 #else /* HAVE_ABSTRACT_SOCKETS */
525 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
526 "Operating system does not support abstract socket namespace\n");
527 _dbus_close (fd, NULL);
529 #endif /* ! HAVE_ABSTRACT_SOCKETS */
533 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
535 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
536 "Socket name too long\n");
537 _dbus_close (fd, NULL);
541 strncpy (addr.sun_path, path, path_len);
544 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
546 dbus_set_error (error,
547 _dbus_error_from_errno (errno),
548 "Failed to connect to socket %s: %s",
549 path, _dbus_strerror (errno));
551 _dbus_close (fd, NULL);
557 if (!_dbus_set_fd_nonblocking (fd, error))
559 _DBUS_ASSERT_ERROR_IS_SET (error);
561 _dbus_close (fd, NULL);
571 * Enables or disables the reception of credentials on the given socket during
572 * the next message transmission. This is only effective if the #LOCAL_CREDS
573 * system feature exists, in which case the other side of the connection does
574 * not have to do anything special to send the credentials.
576 * @param fd socket on which to change the #LOCAL_CREDS flag.
577 * @param on whether to enable or disable the #LOCAL_CREDS flag.
580 _dbus_set_local_creds (int fd, dbus_bool_t on)
582 dbus_bool_t retval = TRUE;
584 #if defined(HAVE_CMSGCRED)
585 /* NOOP just to make sure only one codepath is used
586 * and to prefer CMSGCRED
588 #elif defined(LOCAL_CREDS)
589 int val = on ? 1 : 0;
590 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
592 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
596 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
597 on ? "enabled" : "disabled", fd);
604 * Creates a socket and binds it to the given path,
605 * then listens on the socket. The socket is
606 * set to be nonblocking.
608 * Uses abstract sockets instead of filesystem-linked
609 * sockets if requested (it's possible only on Linux;
610 * see "man 7 unix" on Linux).
611 * On non-Linux abstract socket usage always fails.
613 * @param path the socket name
614 * @param abstract #TRUE to use abstract namespace
615 * @param error return location for errors
616 * @returns the listening file descriptor or -1 on error
619 _dbus_listen_unix_socket (const char *path,
620 dbus_bool_t abstract,
624 struct sockaddr_un addr;
627 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
629 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
632 if (!_dbus_open_unix_socket (&listen_fd, error))
634 _DBUS_ASSERT_ERROR_IS_SET(error);
637 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
640 addr.sun_family = AF_UNIX;
641 path_len = strlen (path);
645 #ifdef HAVE_ABSTRACT_SOCKETS
646 /* remember that abstract names aren't nul-terminated so we rely
647 * on sun_path being filled in with zeroes above.
649 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
650 path_len++; /* Account for the extra nul byte added to the start of sun_path */
652 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
654 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
655 "Abstract socket name too long\n");
656 _dbus_close (listen_fd, NULL);
660 strncpy (&addr.sun_path[1], path, path_len);
661 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
662 #else /* HAVE_ABSTRACT_SOCKETS */
663 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
664 "Operating system does not support abstract socket namespace\n");
665 _dbus_close (listen_fd, NULL);
667 #endif /* ! HAVE_ABSTRACT_SOCKETS */
671 /* Discussed security implications of this with Nalin,
672 * and we couldn't think of where it would kick our ass, but
673 * it still seems a bit sucky. It also has non-security suckage;
674 * really we'd prefer to exit if the socket is already in use.
675 * But there doesn't seem to be a good way to do this.
677 * Just to be extra careful, I threw in the stat() - clearly
678 * the stat() can't *fix* any security issue, but it at least
679 * avoids inadvertent/accidental data loss.
684 if (stat (path, &sb) == 0 &&
685 S_ISSOCK (sb.st_mode))
689 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
691 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
692 "Abstract socket name too long\n");
693 _dbus_close (listen_fd, NULL);
697 strncpy (addr.sun_path, path, path_len);
700 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
702 dbus_set_error (error, _dbus_error_from_errno (errno),
703 "Failed to bind socket \"%s\": %s",
704 path, _dbus_strerror (errno));
705 _dbus_close (listen_fd, NULL);
709 if (listen (listen_fd, 30 /* backlog */) < 0)
711 dbus_set_error (error, _dbus_error_from_errno (errno),
712 "Failed to listen on socket \"%s\": %s",
713 path, _dbus_strerror (errno));
714 _dbus_close (listen_fd, NULL);
718 if (!_dbus_set_local_creds (listen_fd, TRUE))
720 dbus_set_error (error, _dbus_error_from_errno (errno),
721 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
722 path, _dbus_strerror (errno));
727 if (!_dbus_set_fd_nonblocking (listen_fd, error))
729 _DBUS_ASSERT_ERROR_IS_SET (error);
730 _dbus_close (listen_fd, NULL);
734 /* Try opening up the permissions, but if we can't, just go ahead
735 * and continue, maybe it will be good enough.
737 if (!abstract && chmod (path, 0777) < 0)
738 _dbus_warn ("Could not set mode 0777 on socket %s\n",
745 * Creates a socket and connects to a socket at the given host
746 * and port. The connection fd is returned, and is set up as
749 * @param host the host name to connect to
750 * @param port the port to connect to
751 * @param family the address family to listen on, NULL for all
752 * @param error return location for error code
753 * @returns connection file descriptor or -1 on error
756 _dbus_connect_tcp_socket (const char *host,
762 struct addrinfo hints;
763 struct addrinfo *ai, *tmp;
765 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
767 if (!_dbus_open_tcp_socket (&fd, error))
769 _DBUS_ASSERT_ERROR_IS_SET(error);
773 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
778 hints.ai_family = AF_UNSPEC;
779 else if (!strcmp(family, "ipv4"))
780 hints.ai_family = AF_INET;
781 else if (!strcmp(family, "ipv6"))
782 hints.ai_family = AF_INET6;
785 dbus_set_error (error,
786 _dbus_error_from_errno (errno),
787 "Unknown address family %s", family);
790 hints.ai_protocol = IPPROTO_TCP;
791 hints.ai_socktype = SOCK_STREAM;
792 hints.ai_flags = AI_ADDRCONFIG;
794 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
796 dbus_set_error (error,
797 _dbus_error_from_errno (errno),
798 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
799 host, port, gai_strerror(res), res);
800 _dbus_close (fd, NULL);
807 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
810 _DBUS_ASSERT_ERROR_IS_SET(error);
813 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
815 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
817 _dbus_close(fd, NULL);
829 dbus_set_error (error,
830 _dbus_error_from_errno (errno),
831 "Failed to connect to socket \"%s:%s\" %s",
832 host, port, _dbus_strerror(errno));
837 if (!_dbus_set_fd_nonblocking (fd, error))
839 _dbus_close (fd, NULL);
849 * Creates a socket and binds it to the given path, then listens on
850 * the socket. The socket is set to be nonblocking. In case of port=0
851 * a random free port is used and returned in the port parameter.
852 * If inaddr_any is specified, the hostname is ignored.
854 * @param host the host name to listen on
855 * @param port the port to listen on, if zero a free port will be used
856 * @param family the address family to listen on, NULL for all
857 * @param retport string to return the actual port listened on
858 * @param fds_p location to store returned file descriptors
859 * @param error return location for errors
860 * @returns the number of listening file descriptors or -1 on error
863 _dbus_listen_tcp_socket (const char *host,
870 int nlisten_fd = 0, *listen_fd = NULL, res, i;
871 struct addrinfo hints;
872 struct addrinfo *ai, *tmp;
875 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
880 hints.ai_family = AF_UNSPEC;
881 else if (!strcmp(family, "ipv4"))
882 hints.ai_family = AF_INET;
883 else if (!strcmp(family, "ipv6"))
884 hints.ai_family = AF_INET6;
887 dbus_set_error (error,
888 _dbus_error_from_errno (errno),
889 "Unknown address family %s", family);
893 hints.ai_protocol = IPPROTO_TCP;
894 hints.ai_socktype = SOCK_STREAM;
895 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
897 redo_lookup_with_port:
898 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
900 dbus_set_error (error,
901 _dbus_error_from_errno (errno),
902 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
903 host ? host : "*", port, gai_strerror(res), res);
910 int fd = -1, *newlisten_fd;
911 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
913 _DBUS_ASSERT_ERROR_IS_SET(error);
916 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
918 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
920 _dbus_close(fd, NULL);
921 if (errno == EADDRINUSE)
923 /* Depending on kernel policy, it may or may not
924 be neccessary to bind to both IPv4 & 6 addresses
925 so ignore EADDRINUSE here */
929 dbus_set_error (error, _dbus_error_from_errno (errno),
930 "Failed to bind socket \"%s:%s\": %s",
931 host ? host : "*", port, _dbus_strerror (errno));
935 if (listen (fd, 30 /* backlog */) < 0)
937 _dbus_close (fd, NULL);
938 dbus_set_error (error, _dbus_error_from_errno (errno),
939 "Failed to listen on socket \"%s:%s\": %s",
940 host ? host : "*", port, _dbus_strerror (errno));
944 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
947 _dbus_close (fd, NULL);
948 dbus_set_error (error, _dbus_error_from_errno (errno),
949 "Failed to allocate file handle array: %s",
950 _dbus_strerror (errno));
953 listen_fd = newlisten_fd;
954 listen_fd[nlisten_fd] = fd;
957 if (!_dbus_string_get_length(retport))
959 /* If the user didn't specify a port, or used 0, then
960 the kernel chooses a port. After the first address
961 is bound to, we need to force all remaining addresses
962 to use the same port */
963 if (!port || !strcmp(port, "0"))
965 struct sockaddr_storage addr;
969 addrlen = sizeof(addr);
970 getsockname(fd, (struct sockaddr*) &addr, &addrlen);
972 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
973 portbuf, sizeof(portbuf),
974 NI_NUMERICHOST)) != 0)
976 dbus_set_error (error, _dbus_error_from_errno (errno),
977 "Failed to resolve port \"%s:%s\": %s (%s)",
978 host ? host : "*", port, gai_strerror(res), res);
981 if (!_dbus_string_append(retport, portbuf))
983 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
987 /* Release current address list & redo lookup */
988 port = _dbus_string_get_const_data(retport);
990 goto redo_lookup_with_port;
994 if (!_dbus_string_append(retport, port))
996 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1010 dbus_set_error (error, _dbus_error_from_errno (errno),
1011 "Failed to bind socket \"%s:%s\": %s",
1012 host ? host : "*", port, _dbus_strerror (errno));
1016 for (i = 0 ; i < nlisten_fd ; i++)
1018 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1031 for (i = 0 ; i < nlisten_fd ; i++)
1032 _dbus_close(listen_fd[i], NULL);
1033 dbus_free(listen_fd);
1038 write_credentials_byte (int server_fd,
1042 char buf[1] = { '\0' };
1043 #if defined(HAVE_CMSGCRED)
1046 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1053 memset (&msg, 0, sizeof (msg));
1057 msg.msg_control = (caddr_t) &cmsg;
1058 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1059 memset (&cmsg, 0, sizeof (cmsg));
1060 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1061 cmsg.hdr.cmsg_level = SOL_SOCKET;
1062 cmsg.hdr.cmsg_type = SCM_CREDS;
1065 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1069 #if defined(HAVE_CMSGCRED)
1070 bytes_written = sendmsg (server_fd, &msg, 0);
1072 bytes_written = write (server_fd, buf, 1);
1075 if (bytes_written < 0 && errno == EINTR)
1078 if (bytes_written < 0)
1080 dbus_set_error (error, _dbus_error_from_errno (errno),
1081 "Failed to write credentials byte: %s",
1082 _dbus_strerror (errno));
1085 else if (bytes_written == 0)
1087 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1088 "wrote zero bytes writing credentials byte");
1093 _dbus_assert (bytes_written == 1);
1094 _dbus_verbose ("wrote credentials byte\n");
1100 * Reads a single byte which must be nul (an error occurs otherwise),
1101 * and reads unix credentials if available. Clears the credentials
1102 * object, then adds pid/uid if available, so any previous credentials
1103 * stored in the object are lost.
1105 * Return value indicates whether a byte was read, not whether
1106 * we got valid credentials. On some systems, such as Linux,
1107 * reading/writing the byte isn't actually required, but we do it
1108 * anyway just to avoid multiple codepaths.
1110 * Fails if no byte is available, so you must select() first.
1112 * The point of the byte is that on some systems we have to
1113 * use sendmsg()/recvmsg() to transmit credentials.
1115 * @param client_fd the client file descriptor
1116 * @param credentials object to add client credentials to
1117 * @param error location to store error code
1118 * @returns #TRUE on success
1121 _dbus_read_credentials_socket (int client_fd,
1122 DBusCredentials *credentials,
1128 dbus_uid_t uid_read;
1129 dbus_pid_t pid_read;
1132 #ifdef HAVE_CMSGCRED
1135 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1138 #elif defined(LOCAL_CREDS)
1141 struct sockcred cred;
1145 uid_read = DBUS_UID_UNSET;
1146 pid_read = DBUS_PID_UNSET;
1148 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1150 /* The POSIX spec certainly doesn't promise this, but
1151 * we need these assertions to fail as soon as we're wrong about
1152 * it so we can do the porting fixups
1154 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1155 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1156 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1158 _dbus_credentials_clear (credentials);
1160 /* Systems supporting LOCAL_CREDS are configured to have this feature
1161 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1162 * the connection. Therefore, the received message must carry the
1163 * credentials information without doing anything special.
1166 iov.iov_base = &buf;
1169 memset (&msg, 0, sizeof (msg));
1173 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1174 memset (&cmsg, 0, sizeof (cmsg));
1175 msg.msg_control = (caddr_t) &cmsg;
1176 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1180 bytes_read = recvmsg (client_fd, &msg, 0);
1187 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1188 * normally only call read_credentials if the socket was ready
1192 dbus_set_error (error, _dbus_error_from_errno (errno),
1193 "Failed to read credentials byte: %s",
1194 _dbus_strerror (errno));
1197 else if (bytes_read == 0)
1199 /* this should not happen unless we are using recvmsg wrong,
1200 * so is essentially here for paranoia
1202 dbus_set_error (error, DBUS_ERROR_FAILED,
1203 "Failed to read credentials byte (zero-length read)");
1206 else if (buf != '\0')
1208 dbus_set_error (error, DBUS_ERROR_FAILED,
1209 "Credentials byte was not nul");
1213 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1214 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1215 || cmsg.hdr.cmsg_type != SCM_CREDS)
1217 dbus_set_error (error, DBUS_ERROR_FAILED,
1218 "Message from recvmsg() was not SCM_CREDS");
1223 _dbus_verbose ("read credentials byte\n");
1228 int cr_len = sizeof (cr);
1230 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1231 cr_len == sizeof (cr))
1238 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1239 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1241 #elif defined(HAVE_CMSGCRED)
1242 struct cmsgcred *cred;
1244 cred = (struct cmsgcred *) CMSG_DATA (&cmsg);
1245 pid_read = cred->cmcred_pid;
1246 uid_read = cred->cmcred_euid;
1247 #elif defined(LOCAL_CREDS)
1248 pid_read = DBUS_PID_UNSET;
1249 uid_read = cmsg.cred.sc_uid;
1250 /* Since we have already got the credentials from this socket, we can
1251 * disable its LOCAL_CREDS flag if it was ever set. */
1252 _dbus_set_local_creds (client_fd, FALSE);
1253 #elif defined(HAVE_GETPEEREID)
1256 if (getpeereid (client_fd, &euid, &egid) == 0)
1262 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1264 #elif defined(HAVE_GETPEERUCRED)
1265 ucred_t * ucred = NULL;
1266 if (getpeerucred (client_fd, &ucred) == 0)
1268 pid_read = ucred_getpid (ucred);
1269 uid_read = ucred_geteuid (ucred);
1271 /* generate audit session data based on socket ucred */
1272 adt_session_data_t *adth = NULL;
1273 adt_export_data_t *data = NULL;
1275 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1277 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1281 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1283 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1287 size = adt_export_session_data (adth, &data);
1290 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1294 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1298 (void) adt_end_session (adth);
1300 #endif /* HAVE_ADT */
1304 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1308 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1309 _dbus_verbose ("Socket credentials not supported on this OS\n");
1313 _dbus_verbose ("Credentials:"
1314 " pid "DBUS_PID_FORMAT
1315 " uid "DBUS_UID_FORMAT
1320 if (pid_read != DBUS_PID_UNSET)
1322 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1324 _DBUS_SET_OOM (error);
1329 if (uid_read != DBUS_UID_UNSET)
1331 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1333 _DBUS_SET_OOM (error);
1342 * Sends a single nul byte with our UNIX credentials as ancillary
1343 * data. Returns #TRUE if the data was successfully written. On
1344 * systems that don't support sending credentials, just writes a byte,
1345 * doesn't send any credentials. On some systems, such as Linux,
1346 * reading/writing the byte isn't actually required, but we do it
1347 * anyway just to avoid multiple codepaths.
1349 * Fails if no byte can be written, so you must select() first.
1351 * The point of the byte is that on some systems we have to
1352 * use sendmsg()/recvmsg() to transmit credentials.
1354 * @param server_fd file descriptor for connection to server
1355 * @param error return location for error code
1356 * @returns #TRUE if the byte was sent
1359 _dbus_send_credentials_socket (int server_fd,
1362 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1364 if (write_credentials_byte (server_fd, error))
1371 * Accepts a connection on a listening socket.
1372 * Handles EINTR for you.
1374 * @param listen_fd the listen file descriptor
1375 * @returns the connection fd of the client, or -1 on error
1378 _dbus_accept (int listen_fd)
1381 struct sockaddr addr;
1384 addrlen = sizeof (addr);
1387 client_fd = accept (listen_fd, &addr, &addrlen);
1395 _dbus_verbose ("client fd %d accepted\n", client_fd);
1401 * Checks to make sure the given directory is
1402 * private to the user
1404 * @param dir the name of the directory
1405 * @param error error return
1406 * @returns #FALSE on failure
1409 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1411 const char *directory;
1414 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1416 directory = _dbus_string_get_const_data (dir);
1418 if (stat (directory, &sb) < 0)
1420 dbus_set_error (error, _dbus_error_from_errno (errno),
1421 "%s", _dbus_strerror (errno));
1426 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1427 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1429 dbus_set_error (error, DBUS_ERROR_FAILED,
1430 "%s directory is not private to the user", directory);
1438 fill_user_info_from_passwd (struct passwd *p,
1442 _dbus_assert (p->pw_name != NULL);
1443 _dbus_assert (p->pw_dir != NULL);
1445 info->uid = p->pw_uid;
1446 info->primary_gid = p->pw_gid;
1447 info->username = _dbus_strdup (p->pw_name);
1448 info->homedir = _dbus_strdup (p->pw_dir);
1450 if (info->username == NULL ||
1451 info->homedir == NULL)
1453 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1461 fill_user_info (DBusUserInfo *info,
1463 const DBusString *username,
1466 const char *username_c;
1468 /* exactly one of username/uid provided */
1469 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1470 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1472 info->uid = DBUS_UID_UNSET;
1473 info->primary_gid = DBUS_GID_UNSET;
1474 info->group_ids = NULL;
1475 info->n_group_ids = 0;
1476 info->username = NULL;
1477 info->homedir = NULL;
1479 if (username != NULL)
1480 username_c = _dbus_string_get_const_data (username);
1484 /* For now assuming that the getpwnam() and getpwuid() flavors
1485 * are always symmetrical, if not we have to add more configure
1489 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1495 struct passwd p_str;
1497 /* retrieve maximum needed size for buf */
1498 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1500 /* sysconf actually returns a long, but everything else expects size_t,
1501 * so just recast here.
1502 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1504 if ((long) buflen <= 0)
1510 buf = dbus_malloc (buflen);
1513 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1518 #ifdef HAVE_POSIX_GETPWNAM_R
1519 if (uid != DBUS_UID_UNSET)
1520 result = getpwuid_r (uid, &p_str, buf, buflen,
1523 result = getpwnam_r (username_c, &p_str, buf, buflen,
1526 if (uid != DBUS_UID_UNSET)
1527 p = getpwuid_r (uid, &p_str, buf, buflen);
1529 p = getpwnam_r (username_c, &p_str, buf, buflen);
1531 #endif /* !HAVE_POSIX_GETPWNAM_R */
1532 //Try a bigger buffer if ERANGE was returned
1533 if (result == ERANGE && buflen < 512 * 1024)
1543 if (result == 0 && p == &p_str)
1545 if (!fill_user_info_from_passwd (p, info, error))
1554 dbus_set_error (error, _dbus_error_from_errno (errno),
1555 "User \"%s\" unknown or no memory to allocate password entry\n",
1556 username_c ? username_c : "???");
1557 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1562 #else /* ! HAVE_GETPWNAM_R */
1564 /* I guess we're screwed on thread safety here */
1567 if (uid != DBUS_UID_UNSET)
1570 p = getpwnam (username_c);
1574 if (!fill_user_info_from_passwd (p, info, error))
1581 dbus_set_error (error, _dbus_error_from_errno (errno),
1582 "User \"%s\" unknown or no memory to allocate password entry\n",
1583 username_c ? username_c : "???");
1584 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1588 #endif /* ! HAVE_GETPWNAM_R */
1590 /* Fill this in so we can use it to get groups */
1591 username_c = info->username;
1593 #ifdef HAVE_GETGROUPLIST
1598 int initial_buf_count;
1600 initial_buf_count = 17;
1601 buf_count = initial_buf_count;
1602 buf = dbus_new (gid_t, buf_count);
1605 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1609 if (getgrouplist (username_c,
1611 buf, &buf_count) < 0)
1614 /* Presumed cause of negative return code: buf has insufficient
1615 entries to hold the entire group list. The Linux behavior in this
1616 case is to pass back the actual number of groups in buf_count, but
1617 on Mac OS X 10.5, buf_count is unhelpfully left alone.
1618 So as a hack, try to help out a bit by guessing a larger
1619 number of groups, within reason.. might still fail, of course,
1620 but we can at least print a more informative message. I looked up
1621 the "right way" to do this by downloading Apple's own source code
1622 for the "id" command, and it turns out that they use an
1623 undocumented library function getgrouplist_2 (!) which is not
1624 declared in any header in /usr/include (!!). That did not seem
1625 like the way to go here.
1627 if (buf_count == initial_buf_count)
1629 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
1631 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1634 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1642 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
1646 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
1647 username_c, buf_count, buf_count);
1651 dbus_set_error (error,
1652 _dbus_error_from_errno (errno),
1653 "Failed to get groups for username \"%s\" primary GID "
1654 DBUS_GID_FORMAT ": %s\n",
1655 username_c, info->primary_gid,
1656 _dbus_strerror (errno));
1663 info->group_ids = dbus_new (dbus_gid_t, buf_count);
1664 if (info->group_ids == NULL)
1666 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1671 for (i = 0; i < buf_count; ++i)
1672 info->group_ids[i] = buf[i];
1674 info->n_group_ids = buf_count;
1678 #else /* HAVE_GETGROUPLIST */
1680 /* We just get the one group ID */
1681 info->group_ids = dbus_new (dbus_gid_t, 1);
1682 if (info->group_ids == NULL)
1684 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1688 info->n_group_ids = 1;
1690 (info->group_ids)[0] = info->primary_gid;
1692 #endif /* HAVE_GETGROUPLIST */
1694 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1699 _DBUS_ASSERT_ERROR_IS_SET (error);
1704 * Gets user info for the given username.
1706 * @param info user info object to initialize
1707 * @param username the username
1708 * @param error error return
1709 * @returns #TRUE on success
1712 _dbus_user_info_fill (DBusUserInfo *info,
1713 const DBusString *username,
1716 return fill_user_info (info, DBUS_UID_UNSET,
1721 * Gets user info for the given user ID.
1723 * @param info user info object to initialize
1724 * @param uid the user ID
1725 * @param error error return
1726 * @returns #TRUE on success
1729 _dbus_user_info_fill_uid (DBusUserInfo *info,
1733 return fill_user_info (info, uid,
1738 * Adds the credentials of the current process to the
1739 * passed-in credentials object.
1741 * @param credentials credentials to add to
1742 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
1745 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
1747 /* The POSIX spec certainly doesn't promise this, but
1748 * we need these assertions to fail as soon as we're wrong about
1749 * it so we can do the porting fixups
1751 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1752 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1753 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1755 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
1757 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
1764 * Append to the string the identity we would like to have when we
1765 * authenticate, on UNIX this is the current process UID and on
1766 * Windows something else, probably a Windows SID string. No escaping
1767 * is required, that is done in dbus-auth.c. The username here
1768 * need not be anything human-readable, it can be the machine-readable
1769 * form i.e. a user id.
1771 * @param str the string to append to
1772 * @returns #FALSE on no memory
1775 _dbus_append_user_from_current_process (DBusString *str)
1777 return _dbus_string_append_uint (str,
1782 * Gets our process ID
1783 * @returns process ID
1792 * @returns process UID
1800 /** Gets our effective UID
1801 * @returns process effective UID
1804 _dbus_geteuid (void)
1810 * The only reason this is separate from _dbus_getpid() is to allow it
1811 * on Windows for logging but not for other purposes.
1813 * @returns process ID to put in log messages
1816 _dbus_pid_for_log (void)
1822 * Gets a UID from a UID string.
1824 * @param uid_str the UID in string form
1825 * @param uid UID to fill in
1826 * @returns #TRUE if successfully filled in UID
1829 _dbus_parse_uid (const DBusString *uid_str,
1835 if (_dbus_string_get_length (uid_str) == 0)
1837 _dbus_verbose ("UID string was zero length\n");
1843 if (!_dbus_string_parse_int (uid_str, 0, &val,
1846 _dbus_verbose ("could not parse string as a UID\n");
1850 if (end != _dbus_string_get_length (uid_str))
1852 _dbus_verbose ("string contained trailing stuff after UID\n");
1862 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
1864 #if DBUS_USE_ATOMIC_INT_486_COND
1865 /* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */
1866 /* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */
1867 static inline dbus_int32_t
1868 atomic_exchange_and_add (DBusAtomic *atomic,
1869 volatile dbus_int32_t val)
1871 register dbus_int32_t result;
1873 __asm__ __volatile__ ("lock; xaddl %0,%1"
1874 : "=r" (result), "=m" (atomic->value)
1875 : "0" (val), "m" (atomic->value));
1881 * Atomically increments an integer
1883 * @param atomic pointer to the integer to increment
1884 * @returns the value before incrementing
1886 * @todo implement arch-specific faster atomic ops
1889 _dbus_atomic_inc (DBusAtomic *atomic)
1891 #if DBUS_USE_ATOMIC_INT_486_COND
1892 return atomic_exchange_and_add (atomic, 1);
1895 _DBUS_LOCK (atomic);
1896 res = atomic->value;
1898 _DBUS_UNLOCK (atomic);
1904 * Atomically decrement an integer
1906 * @param atomic pointer to the integer to decrement
1907 * @returns the value before decrementing
1909 * @todo implement arch-specific faster atomic ops
1912 _dbus_atomic_dec (DBusAtomic *atomic)
1914 #if DBUS_USE_ATOMIC_INT_486_COND
1915 return atomic_exchange_and_add (atomic, -1);
1919 _DBUS_LOCK (atomic);
1920 res = atomic->value;
1922 _DBUS_UNLOCK (atomic);
1927 #ifdef DBUS_BUILD_TESTS
1929 * @returns process GID
1939 * Wrapper for poll().
1941 * @param fds the file descriptors to poll
1942 * @param n_fds number of descriptors in the array
1943 * @param timeout_milliseconds timeout or -1 for infinite
1944 * @returns numbers of fds with revents, or <0 on error
1947 _dbus_poll (DBusPollFD *fds,
1949 int timeout_milliseconds)
1951 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
1952 /* This big thing is a constant expression and should get optimized
1953 * out of existence. So it's more robust than a configure check at
1956 if (_DBUS_POLLIN == POLLIN &&
1957 _DBUS_POLLPRI == POLLPRI &&
1958 _DBUS_POLLOUT == POLLOUT &&
1959 _DBUS_POLLERR == POLLERR &&
1960 _DBUS_POLLHUP == POLLHUP &&
1961 _DBUS_POLLNVAL == POLLNVAL &&
1962 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
1963 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
1964 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
1965 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
1966 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
1967 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
1968 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
1970 return poll ((struct pollfd*) fds,
1972 timeout_milliseconds);
1976 /* We have to convert the DBusPollFD to an array of
1977 * struct pollfd, poll, and convert back.
1979 _dbus_warn ("didn't implement poll() properly for this system yet\n");
1982 #else /* ! HAVE_POLL */
1984 fd_set read_set, write_set, err_set;
1990 FD_ZERO (&read_set);
1991 FD_ZERO (&write_set);
1994 for (i = 0; i < n_fds; i++)
1996 DBusPollFD *fdp = &fds[i];
1998 if (fdp->events & _DBUS_POLLIN)
1999 FD_SET (fdp->fd, &read_set);
2001 if (fdp->events & _DBUS_POLLOUT)
2002 FD_SET (fdp->fd, &write_set);
2004 FD_SET (fdp->fd, &err_set);
2006 max_fd = MAX (max_fd, fdp->fd);
2009 tv.tv_sec = timeout_milliseconds / 1000;
2010 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2012 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2013 timeout_milliseconds < 0 ? NULL : &tv);
2017 for (i = 0; i < n_fds; i++)
2019 DBusPollFD *fdp = &fds[i];
2023 if (FD_ISSET (fdp->fd, &read_set))
2024 fdp->revents |= _DBUS_POLLIN;
2026 if (FD_ISSET (fdp->fd, &write_set))
2027 fdp->revents |= _DBUS_POLLOUT;
2029 if (FD_ISSET (fdp->fd, &err_set))
2030 fdp->revents |= _DBUS_POLLERR;
2039 * Get current time, as in gettimeofday().
2041 * @param tv_sec return location for number of seconds
2042 * @param tv_usec return location for number of microseconds (thousandths)
2045 _dbus_get_current_time (long *tv_sec,
2050 gettimeofday (&t, NULL);
2055 *tv_usec = t.tv_usec;
2059 * Appends the contents of the given file to the string,
2060 * returning error code. At the moment, won't open a file
2061 * more than a megabyte in size.
2063 * @param str the string to append to
2064 * @param filename filename to load
2065 * @param error place to set an error
2066 * @returns #FALSE if error was set
2069 _dbus_file_get_contents (DBusString *str,
2070 const DBusString *filename,
2077 const char *filename_c;
2079 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2081 filename_c = _dbus_string_get_const_data (filename);
2083 /* O_BINARY useful on Cygwin */
2084 fd = open (filename_c, O_RDONLY | O_BINARY);
2087 dbus_set_error (error, _dbus_error_from_errno (errno),
2088 "Failed to open \"%s\": %s",
2090 _dbus_strerror (errno));
2094 _dbus_verbose ("file fd %d opened\n", fd);
2096 if (fstat (fd, &sb) < 0)
2098 dbus_set_error (error, _dbus_error_from_errno (errno),
2099 "Failed to stat \"%s\": %s",
2101 _dbus_strerror (errno));
2103 _dbus_verbose ("fstat() failed: %s",
2104 _dbus_strerror (errno));
2106 _dbus_close (fd, NULL);
2111 if (sb.st_size > _DBUS_ONE_MEGABYTE)
2113 dbus_set_error (error, DBUS_ERROR_FAILED,
2114 "File size %lu of \"%s\" is too large.",
2115 (unsigned long) sb.st_size, filename_c);
2116 _dbus_close (fd, NULL);
2121 orig_len = _dbus_string_get_length (str);
2122 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
2126 while (total < (int) sb.st_size)
2128 bytes_read = _dbus_read (fd, str,
2129 sb.st_size - total);
2130 if (bytes_read <= 0)
2132 dbus_set_error (error, _dbus_error_from_errno (errno),
2133 "Error reading \"%s\": %s",
2135 _dbus_strerror (errno));
2137 _dbus_verbose ("read() failed: %s",
2138 _dbus_strerror (errno));
2140 _dbus_close (fd, NULL);
2141 _dbus_string_set_length (str, orig_len);
2145 total += bytes_read;
2148 _dbus_close (fd, NULL);
2151 else if (sb.st_size != 0)
2153 _dbus_verbose ("Can only open regular files at the moment.\n");
2154 dbus_set_error (error, DBUS_ERROR_FAILED,
2155 "\"%s\" is not a regular file",
2157 _dbus_close (fd, NULL);
2162 _dbus_close (fd, NULL);
2168 * Writes a string out to a file. If the file exists,
2169 * it will be atomically overwritten by the new data.
2171 * @param str the string to write out
2172 * @param filename the file to save string to
2173 * @param error error to be filled in on failure
2174 * @returns #FALSE on failure
2177 _dbus_string_save_to_file (const DBusString *str,
2178 const DBusString *filename,
2183 const char *filename_c;
2184 DBusString tmp_filename;
2185 const char *tmp_filename_c;
2187 dbus_bool_t need_unlink;
2190 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2194 need_unlink = FALSE;
2196 if (!_dbus_string_init (&tmp_filename))
2198 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2202 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2204 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2205 _dbus_string_free (&tmp_filename);
2209 if (!_dbus_string_append (&tmp_filename, "."))
2211 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2212 _dbus_string_free (&tmp_filename);
2216 #define N_TMP_FILENAME_RANDOM_BYTES 8
2217 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2219 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2220 _dbus_string_free (&tmp_filename);
2224 filename_c = _dbus_string_get_const_data (filename);
2225 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2227 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2231 dbus_set_error (error, _dbus_error_from_errno (errno),
2232 "Could not create %s: %s", tmp_filename_c,
2233 _dbus_strerror (errno));
2237 _dbus_verbose ("tmp file fd %d opened\n", fd);
2242 bytes_to_write = _dbus_string_get_length (str);
2244 while (total < bytes_to_write)
2248 bytes_written = _dbus_write (fd, str, total,
2249 bytes_to_write - total);
2251 if (bytes_written <= 0)
2253 dbus_set_error (error, _dbus_error_from_errno (errno),
2254 "Could not write to %s: %s", tmp_filename_c,
2255 _dbus_strerror (errno));
2260 total += bytes_written;
2265 dbus_set_error (error, _dbus_error_from_errno (errno),
2266 "Could not synchronize file %s: %s",
2267 tmp_filename_c, _dbus_strerror (errno));
2272 if (!_dbus_close (fd, NULL))
2274 dbus_set_error (error, _dbus_error_from_errno (errno),
2275 "Could not close file %s: %s",
2276 tmp_filename_c, _dbus_strerror (errno));
2283 if (rename (tmp_filename_c, filename_c) < 0)
2285 dbus_set_error (error, _dbus_error_from_errno (errno),
2286 "Could not rename %s to %s: %s",
2287 tmp_filename_c, filename_c,
2288 _dbus_strerror (errno));
2293 need_unlink = FALSE;
2298 /* close first, then unlink, to prevent ".nfs34234235" garbage
2303 _dbus_close (fd, NULL);
2305 if (need_unlink && unlink (tmp_filename_c) < 0)
2306 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2307 tmp_filename_c, _dbus_strerror (errno));
2309 _dbus_string_free (&tmp_filename);
2312 _DBUS_ASSERT_ERROR_IS_SET (error);
2317 /** Makes the file readable by every user in the system.
2319 * @param filename the filename
2320 * @param error error location
2321 * @returns #TRUE if the file's permissions could be changed.
2324 _dbus_make_file_world_readable(const DBusString *filename,
2327 const char *filename_c;
2329 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2331 filename_c = _dbus_string_get_const_data (filename);
2332 if (chmod (filename_c, 0644) == -1)
2334 dbus_set_error (error,
2336 "Could not change permissions of file %s: %s\n",
2338 _dbus_strerror (errno));
2344 /** Creates the given file, failing if the file already exists.
2346 * @param filename the filename
2347 * @param error error location
2348 * @returns #TRUE if we created the file and it didn't exist
2351 _dbus_create_file_exclusively (const DBusString *filename,
2355 const char *filename_c;
2357 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2359 filename_c = _dbus_string_get_const_data (filename);
2361 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2365 dbus_set_error (error,
2367 "Could not create file %s: %s\n",
2369 _dbus_strerror (errno));
2373 _dbus_verbose ("exclusive file fd %d opened\n", fd);
2375 if (!_dbus_close (fd, NULL))
2377 dbus_set_error (error,
2379 "Could not close file %s: %s\n",
2381 _dbus_strerror (errno));
2389 * Deletes the given file.
2391 * @param filename the filename
2392 * @param error error location
2394 * @returns #TRUE if unlink() succeeded
2397 _dbus_delete_file (const DBusString *filename,
2400 const char *filename_c;
2402 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2404 filename_c = _dbus_string_get_const_data (filename);
2406 if (unlink (filename_c) < 0)
2408 dbus_set_error (error, DBUS_ERROR_FAILED,
2409 "Failed to delete file %s: %s\n",
2410 filename_c, _dbus_strerror (errno));
2418 * Creates a directory; succeeds if the directory
2419 * is created or already existed.
2421 * @param filename directory filename
2422 * @param error initialized error object
2423 * @returns #TRUE on success
2426 _dbus_create_directory (const DBusString *filename,
2429 const char *filename_c;
2431 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2433 filename_c = _dbus_string_get_const_data (filename);
2435 if (mkdir (filename_c, 0700) < 0)
2437 if (errno == EEXIST)
2440 dbus_set_error (error, DBUS_ERROR_FAILED,
2441 "Failed to create directory %s: %s\n",
2442 filename_c, _dbus_strerror (errno));
2450 * Appends the given filename to the given directory.
2452 * @todo it might be cute to collapse multiple '/' such as "foo//"
2455 * @param dir the directory name
2456 * @param next_component the filename
2457 * @returns #TRUE on success
2460 _dbus_concat_dir_and_file (DBusString *dir,
2461 const DBusString *next_component)
2463 dbus_bool_t dir_ends_in_slash;
2464 dbus_bool_t file_starts_with_slash;
2466 if (_dbus_string_get_length (dir) == 0 ||
2467 _dbus_string_get_length (next_component) == 0)
2470 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2471 _dbus_string_get_length (dir) - 1);
2473 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2475 if (dir_ends_in_slash && file_starts_with_slash)
2477 _dbus_string_shorten (dir, 1);
2479 else if (!(dir_ends_in_slash || file_starts_with_slash))
2481 if (!_dbus_string_append_byte (dir, '/'))
2485 return _dbus_string_copy (next_component, 0, dir,
2486 _dbus_string_get_length (dir));
2489 /** nanoseconds in a second */
2490 #define NANOSECONDS_PER_SECOND 1000000000
2491 /** microseconds in a second */
2492 #define MICROSECONDS_PER_SECOND 1000000
2493 /** milliseconds in a second */
2494 #define MILLISECONDS_PER_SECOND 1000
2495 /** nanoseconds in a millisecond */
2496 #define NANOSECONDS_PER_MILLISECOND 1000000
2497 /** microseconds in a millisecond */
2498 #define MICROSECONDS_PER_MILLISECOND 1000
2501 * Sleeps the given number of milliseconds.
2502 * @param milliseconds number of milliseconds
2505 _dbus_sleep_milliseconds (int milliseconds)
2507 #ifdef HAVE_NANOSLEEP
2508 struct timespec req;
2509 struct timespec rem;
2511 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2512 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2516 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2518 #elif defined (HAVE_USLEEP)
2519 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2520 #else /* ! HAVE_USLEEP */
2521 sleep (MAX (milliseconds / 1000, 1));
2526 _dbus_generate_pseudorandom_bytes (DBusString *str,
2532 old_len = _dbus_string_get_length (str);
2534 if (!_dbus_string_lengthen (str, n_bytes))
2537 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2539 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2545 * Generates the given number of random bytes,
2546 * using the best mechanism we can come up with.
2548 * @param str the string
2549 * @param n_bytes the number of random bytes to append to string
2550 * @returns #TRUE on success, #FALSE if no memory
2553 _dbus_generate_random_bytes (DBusString *str,
2559 /* FALSE return means "no memory", if it could
2560 * mean something else then we'd need to return
2561 * a DBusError. So we always fall back to pseudorandom
2565 old_len = _dbus_string_get_length (str);
2568 /* note, urandom on linux will fall back to pseudorandom */
2569 fd = open ("/dev/urandom", O_RDONLY);
2571 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2573 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2575 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2577 _dbus_close (fd, NULL);
2578 _dbus_string_set_length (str, old_len);
2579 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2582 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2585 _dbus_close (fd, NULL);
2591 * Exit the process, returning the given value.
2593 * @param code the exit code
2596 _dbus_exit (int code)
2602 * A wrapper around strerror() because some platforms
2603 * may be lame and not have strerror(). Also, never
2606 * @param error_number errno.
2607 * @returns error description.
2610 _dbus_strerror (int error_number)
2614 msg = strerror (error_number);
2622 * signal (SIGPIPE, SIG_IGN);
2625 _dbus_disable_sigpipe (void)
2627 signal (SIGPIPE, SIG_IGN);
2631 * Sets the file descriptor to be close
2632 * on exec. Should be called for all file
2633 * descriptors in D-Bus code.
2635 * @param fd the file descriptor
2638 _dbus_fd_set_close_on_exec (int fd)
2642 val = fcntl (fd, F_GETFD, 0);
2649 fcntl (fd, F_SETFD, val);
2653 * Closes a file descriptor.
2655 * @param fd the file descriptor
2656 * @param error error object
2657 * @returns #FALSE if error set
2660 _dbus_close (int fd,
2663 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2671 dbus_set_error (error, _dbus_error_from_errno (errno),
2672 "Could not close fd %d", fd);
2680 * Sets a file descriptor to be nonblocking.
2682 * @param fd the file descriptor.
2683 * @param error address of error location.
2684 * @returns #TRUE on success.
2687 _dbus_set_fd_nonblocking (int fd,
2692 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2694 val = fcntl (fd, F_GETFL, 0);
2697 dbus_set_error (error, _dbus_error_from_errno (errno),
2698 "Failed to get flags from file descriptor %d: %s",
2699 fd, _dbus_strerror (errno));
2700 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2701 _dbus_strerror (errno));
2705 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2707 dbus_set_error (error, _dbus_error_from_errno (errno),
2708 "Failed to set nonblocking flag of file descriptor %d: %s",
2709 fd, _dbus_strerror (errno));
2710 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2711 fd, _dbus_strerror (errno));
2720 * On GNU libc systems, print a crude backtrace to stderr. On other
2721 * systems, print "no backtrace support" and block for possible gdb
2722 * attachment if an appropriate environment variable is set.
2725 _dbus_print_backtrace (void)
2727 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2733 bt_size = backtrace (bt, 500);
2735 syms = backtrace_symbols (bt, bt_size);
2740 /* don't use dbus_warn since it can _dbus_abort() */
2741 fprintf (stderr, " %s\n", syms[i]);
2747 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2748 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
2750 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2755 * Creates a full-duplex pipe (as in socketpair()).
2756 * Sets both ends of the pipe nonblocking.
2758 * @todo libdbus only uses this for the debug-pipe server, so in
2759 * principle it could be in dbus-sysdeps-util.c, except that
2760 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2761 * debug-pipe server is used.
2763 * @param fd1 return location for one end
2764 * @param fd2 return location for the other end
2765 * @param blocking #TRUE if pipe should be blocking
2766 * @param error error return
2767 * @returns #FALSE on failure (if error is set)
2770 _dbus_full_duplex_pipe (int *fd1,
2772 dbus_bool_t blocking,
2775 #ifdef HAVE_SOCKETPAIR
2778 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2780 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2782 dbus_set_error (error, _dbus_error_from_errno (errno),
2783 "Could not create full-duplex pipe");
2788 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2789 !_dbus_set_fd_nonblocking (fds[1], NULL)))
2791 dbus_set_error (error, _dbus_error_from_errno (errno),
2792 "Could not set full-duplex pipe nonblocking");
2794 _dbus_close (fds[0], NULL);
2795 _dbus_close (fds[1], NULL);
2803 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2808 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2809 dbus_set_error (error, DBUS_ERROR_FAILED,
2810 "_dbus_full_duplex_pipe() not implemented on this OS");
2816 * Measure the length of the given format string and arguments,
2817 * not including the terminating nul.
2819 * @param format a printf-style format string
2820 * @param args arguments for the format string
2821 * @returns length of the given format string and args
2824 _dbus_printf_string_upper_bound (const char *format,
2828 return vsnprintf (&c, 1, format, args);
2832 * Gets the temporary files directory by inspecting the environment variables
2833 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2835 * @returns location of temp directory
2838 _dbus_get_tmpdir(void)
2840 static const char* tmpdir = NULL;
2844 /* TMPDIR is what glibc uses, then
2845 * glibc falls back to the P_tmpdir macro which
2846 * just expands to "/tmp"
2849 tmpdir = getenv("TMPDIR");
2851 /* These two env variables are probably
2852 * broken, but maybe some OS uses them?
2855 tmpdir = getenv("TMP");
2857 tmpdir = getenv("TEMP");
2859 /* And this is the sane fallback. */
2864 _dbus_assert(tmpdir != NULL);
2870 * Execute a subprocess, returning up to 1024 bytes of output
2873 * If successful, returns #TRUE and appends the output to @p
2874 * result. If a failure happens, returns #FALSE and
2875 * sets an error in @p error.
2877 * @note It's not an error if the subprocess terminates normally
2878 * without writing any data to stdout. Verify the @p result length
2879 * before and after this function call to cover this case.
2881 * @param progname initial path to exec
2882 * @param argv NULL-terminated list of arguments
2883 * @param result a DBusString where the output can be append
2884 * @param error a DBusError to store the error in case of failure
2885 * @returns #TRUE on success, #FALSE if an error happened
2888 _read_subprocess_line_argv (const char *progpath,
2893 int result_pipe[2] = { -1, -1 };
2894 int errors_pipe[2] = { -1, -1 };
2902 sigset_t new_set, old_set;
2904 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2907 if (!_dbus_string_init (&uuid))
2909 _DBUS_SET_OOM (error);
2913 /* We need to block any existing handlers for SIGCHLD temporarily; they
2914 * will cause waitpid() below to fail.
2915 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
2917 sigemptyset (&new_set);
2918 sigaddset (&new_set, SIGCHLD);
2919 sigprocmask (SIG_BLOCK, &new_set, &old_set);
2921 orig_len = _dbus_string_get_length (result);
2925 if (pipe (result_pipe) < 0)
2927 dbus_set_error (error, _dbus_error_from_errno (errno),
2928 "Failed to create a pipe to call %s: %s",
2929 progpath, _dbus_strerror (errno));
2930 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
2931 progpath, _dbus_strerror (errno));
2934 if (pipe (errors_pipe) < 0)
2936 dbus_set_error (error, _dbus_error_from_errno (errno),
2937 "Failed to create a pipe to call %s: %s",
2938 progpath, _dbus_strerror (errno));
2939 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
2940 progpath, _dbus_strerror (errno));
2947 dbus_set_error (error, _dbus_error_from_errno (errno),
2948 "Failed to fork() to call %s: %s",
2949 progpath, _dbus_strerror (errno));
2950 _dbus_verbose ("Failed to fork() to call %s: %s\n",
2951 progpath, _dbus_strerror (errno));
2961 fd = open ("/dev/null", O_RDWR);
2963 /* huh?! can't open /dev/null? */
2966 _dbus_verbose ("/dev/null fd %d opened\n", fd);
2969 close (result_pipe[READ_END]);
2970 close (errors_pipe[READ_END]);
2971 close (0); /* close stdin */
2972 close (1); /* close stdout */
2973 close (2); /* close stderr */
2975 if (dup2 (fd, 0) == -1)
2977 if (dup2 (result_pipe[WRITE_END], 1) == -1)
2979 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
2982 maxfds = sysconf (_SC_OPEN_MAX);
2983 /* Pick something reasonable if for some reason sysconf
2988 /* close all inherited fds */
2989 for (i = 3; i < maxfds; i++)
2992 sigprocmask(SIG_SETMASK, &old_set, NULL);
2994 /* If it looks fully-qualified, try execv first */
2995 if (progpath[0] == '/')
2996 execv (progpath, argv);
2998 execvp (progpath, argv);
3000 /* still nothing, we failed */
3004 /* parent process */
3005 close (result_pipe[WRITE_END]);
3006 close (errors_pipe[WRITE_END]);
3007 result_pipe[WRITE_END] = -1;
3008 errors_pipe[WRITE_END] = -1;
3013 ret = _dbus_read (result_pipe[READ_END], result, 1024);
3017 /* reap the child process to avoid it lingering as zombie */
3020 ret = waitpid (pid, &status, 0);
3022 while (ret == -1 && errno == EINTR);
3024 /* We succeeded if the process exited with status 0 and
3025 anything was read */
3026 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3028 /* The process ended with error */
3029 DBusString error_message;
3030 _dbus_string_init (&error_message);
3034 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3038 _dbus_string_set_length (result, orig_len);
3039 if (_dbus_string_get_length (&error_message) > 0)
3040 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3041 "%s terminated abnormally with the following error: %s",
3042 progpath, _dbus_string_get_data (&error_message));
3044 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3045 "%s terminated abnormally without any error message",
3053 sigprocmask (SIG_SETMASK, &old_set, NULL);
3056 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3058 _DBUS_ASSERT_ERROR_IS_SET (error);
3060 if (result_pipe[0] != -1)
3061 close (result_pipe[0]);
3062 if (result_pipe[1] != -1)
3063 close (result_pipe[1]);
3064 if (errors_pipe[0] != -1)
3065 close (errors_pipe[0]);
3066 if (errors_pipe[1] != -1)
3067 close (errors_pipe[1]);
3073 * Returns the address of a new session bus.
3075 * If successful, returns #TRUE and appends the address to @p
3076 * address. If a failure happens, returns #FALSE and
3077 * sets an error in @p error.
3079 * @param address a DBusString where the address can be stored
3080 * @param error a DBusError to store the error in case of failure
3081 * @returns #TRUE on success, #FALSE if an error happened
3084 _dbus_get_autolaunch_address (DBusString *address,
3087 static char *argv[6];
3092 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3095 if (!_dbus_string_init (&uuid))
3097 _DBUS_SET_OOM (error);
3101 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3103 _DBUS_SET_OOM (error);
3108 argv[i] = "dbus-launch";
3110 argv[i] = "--autolaunch";
3112 argv[i] = _dbus_string_get_data (&uuid);
3114 argv[i] = "--binary-syntax";
3116 argv[i] = "--close-stderr";
3121 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3123 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3124 argv, address, error);
3127 _dbus_string_free (&uuid);
3132 * Reads the uuid of the machine we're running on from
3133 * the dbus configuration. Optionally try to create it
3134 * (only root can do this usually).
3136 * On UNIX, reads a file that gets created by dbus-uuidgen
3137 * in a post-install script. On Windows, if there's a standard
3138 * machine uuid we could just use that, but I can't find one
3139 * with the right properties (the hardware profile guid can change
3140 * without rebooting I believe). If there's no standard one
3141 * we might want to use the registry instead of a file for
3142 * this, and I'm not sure how we'd ensure the uuid gets created.
3144 * @param machine_id guid to init with the machine's uuid
3145 * @param create_if_not_found try to create the uuid if it doesn't exist
3146 * @param error the error return
3147 * @returns #FALSE if the error is set
3150 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3151 dbus_bool_t create_if_not_found,
3154 DBusString filename;
3155 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3156 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3159 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3160 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3163 * Determines the address of the session bus by querying a
3164 * platform-specific method.
3166 * The first parameter will be a boolean specifying whether
3167 * or not a dynamic session lookup is supported on this platform.
3169 * If supported is TRUE and the return value is #TRUE, the
3170 * address will be appended to @p address.
3171 * If a failure happens, returns #FALSE and sets an error in
3174 * If supported is FALSE, ignore the return value.
3176 * @param supported returns whether this method is supported
3177 * @param address a DBusString where the address can be stored
3178 * @param error a DBusError to store the error in case of failure
3179 * @returns #TRUE on success, #FALSE if an error happened
3182 _dbus_lookup_session_address (dbus_bool_t *supported,
3183 DBusString *address,
3186 /* On non-Mac Unix platforms, if the session address isn't already
3187 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3188 * fall back to the autolaunch: global default; see
3189 * init_session_address in dbus/dbus-bus.c. */
3195 * Returns the standard directories for a session bus to look for service
3198 * On UNIX this should be the standard xdg freedesktop.org data directories:
3200 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3201 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3207 * @param dirs the directory list we are returning
3208 * @returns #FALSE on OOM
3212 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3214 const char *xdg_data_home;
3215 const char *xdg_data_dirs;
3216 DBusString servicedir_path;
3218 if (!_dbus_string_init (&servicedir_path))
3221 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3222 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3224 if (xdg_data_dirs != NULL)
3226 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3229 if (!_dbus_string_append (&servicedir_path, ":"))
3234 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3239 * add configured datadir to defaults
3240 * this may be the same as an xdg dir
3241 * however the config parser should take
3242 * care of duplicates
3244 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3247 if (xdg_data_home != NULL)
3249 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3254 const DBusString *homedir;
3255 DBusString local_share;
3257 if (!_dbus_homedir_from_current_process (&homedir))
3260 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3263 _dbus_string_init_const (&local_share, "/.local/share");
3264 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3268 if (!_dbus_split_paths_and_append (&servicedir_path,
3269 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3273 _dbus_string_free (&servicedir_path);
3277 _dbus_string_free (&servicedir_path);
3283 * Returns the standard directories for a system bus to look for service
3286 * On UNIX this should be the standard xdg freedesktop.org data directories:
3288 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3294 * On Windows there is no system bus and this function can return nothing.
3296 * @param dirs the directory list we are returning
3297 * @returns #FALSE on OOM
3301 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3303 const char *xdg_data_dirs;
3304 DBusString servicedir_path;
3306 if (!_dbus_string_init (&servicedir_path))
3309 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3311 if (xdg_data_dirs != NULL)
3313 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3316 if (!_dbus_string_append (&servicedir_path, ":"))
3321 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3326 * add configured datadir to defaults
3327 * this may be the same as an xdg dir
3328 * however the config parser should take
3329 * care of duplicates
3331 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3334 if (!_dbus_split_paths_and_append (&servicedir_path,
3335 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3339 _dbus_string_free (&servicedir_path);
3343 _dbus_string_free (&servicedir_path);
3348 * Append the absolute path of the system.conf file
3349 * (there is no system bus on Windows so this can just
3350 * return FALSE and print a warning or something)
3352 * @param str the string to append to
3353 * @returns #FALSE if no memory
3356 _dbus_append_system_config_file (DBusString *str)
3358 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3362 * Append the absolute path of the session.conf file.
3364 * @param str the string to append to
3365 * @returns #FALSE if no memory
3368 _dbus_append_session_config_file (DBusString *str)
3370 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3374 * Called when the bus daemon is signaled to reload its configuration; any
3375 * caches should be nuked. Of course any caches that need explicit reload
3376 * are probably broken, but c'est la vie.
3381 _dbus_flush_caches (void)
3383 _dbus_user_database_flush_system ();
3387 * Appends the directory in which a keyring for the given credentials
3388 * should be stored. The credentials should have either a Windows or
3389 * UNIX user in them. The directory should be an absolute path.
3391 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3392 * be something else, since the dotfile convention is not normal on Windows.
3394 * @param directory string to append directory to
3395 * @param credentials credentials the directory should be for
3397 * @returns #FALSE on no memory
3400 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3401 DBusCredentials *credentials)
3407 _dbus_assert (credentials != NULL);
3408 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3410 if (!_dbus_string_init (&homedir))
3413 uid = _dbus_credentials_get_unix_uid (credentials);
3414 _dbus_assert (uid != DBUS_UID_UNSET);
3416 if (!_dbus_homedir_from_uid (uid, &homedir))
3419 #ifdef DBUS_BUILD_TESTS
3421 const char *override;
3423 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3424 if (override != NULL && *override != '\0')
3426 _dbus_string_set_length (&homedir, 0);
3427 if (!_dbus_string_append (&homedir, override))
3430 _dbus_verbose ("Using fake homedir for testing: %s\n",
3431 _dbus_string_get_const_data (&homedir));
3435 static dbus_bool_t already_warned = FALSE;
3436 if (!already_warned)
3438 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3439 already_warned = TRUE;
3445 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3446 if (!_dbus_concat_dir_and_file (&homedir,
3450 if (!_dbus_string_copy (&homedir, 0,
3451 directory, _dbus_string_get_length (directory))) {
3455 _dbus_string_free (&homedir);
3459 _dbus_string_free (&homedir);
3465 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3466 * for Winsock so is abstracted)
3468 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3471 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3473 return errno == EAGAIN || errno == EWOULDBLOCK;
3476 /* tests in dbus-sysdeps-util.c */