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,
763 struct addrinfo hints;
764 struct addrinfo *ai, *tmp;
766 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
768 if (!_dbus_open_tcp_socket (&fd, error))
770 _DBUS_ASSERT_ERROR_IS_SET(error);
774 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
779 hints.ai_family = AF_UNSPEC;
780 else if (!strcmp(family, "ipv4"))
781 hints.ai_family = AF_INET;
782 else if (!strcmp(family, "ipv6"))
783 hints.ai_family = AF_INET6;
786 dbus_set_error (error,
787 DBUS_ERROR_BAD_ADDRESS,
788 "Unknown address family %s", family);
791 hints.ai_protocol = IPPROTO_TCP;
792 hints.ai_socktype = SOCK_STREAM;
793 hints.ai_flags = AI_ADDRCONFIG;
795 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
797 dbus_set_error (error,
798 _dbus_error_from_errno (errno),
799 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
800 host, port, gai_strerror(res), res);
801 _dbus_close (fd, NULL);
808 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
811 _DBUS_ASSERT_ERROR_IS_SET(error);
814 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
816 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
819 _dbus_close(fd, NULL);
831 dbus_set_error (error,
832 _dbus_error_from_errno (saved_errno),
833 "Failed to connect to socket \"%s:%s\" %s",
834 host, port, _dbus_strerror(saved_errno));
839 if (!_dbus_set_fd_nonblocking (fd, error))
841 _dbus_close (fd, NULL);
851 * Creates a socket and binds it to the given path, then listens on
852 * the socket. The socket is set to be nonblocking. In case of port=0
853 * a random free port is used and returned in the port parameter.
854 * If inaddr_any is specified, the hostname is ignored.
856 * @param host the host name to listen on
857 * @param port the port to listen on, if zero a free port will be used
858 * @param family the address family to listen on, NULL for all
859 * @param retport string to return the actual port listened on
860 * @param fds_p location to store returned file descriptors
861 * @param error return location for errors
862 * @returns the number of listening file descriptors or -1 on error
865 _dbus_listen_tcp_socket (const char *host,
873 int nlisten_fd = 0, *listen_fd = NULL, res, i;
874 struct addrinfo hints;
875 struct addrinfo *ai, *tmp;
878 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
883 hints.ai_family = AF_UNSPEC;
884 else if (!strcmp(family, "ipv4"))
885 hints.ai_family = AF_INET;
886 else if (!strcmp(family, "ipv6"))
887 hints.ai_family = AF_INET6;
890 dbus_set_error (error,
891 DBUS_ERROR_BAD_ADDRESS,
892 "Unknown address family %s", family);
896 hints.ai_protocol = IPPROTO_TCP;
897 hints.ai_socktype = SOCK_STREAM;
898 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
900 redo_lookup_with_port:
901 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
903 dbus_set_error (error,
904 _dbus_error_from_errno (errno),
905 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
906 host ? host : "*", port, gai_strerror(res), res);
913 int fd = -1, *newlisten_fd;
914 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
916 _DBUS_ASSERT_ERROR_IS_SET(error);
919 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
921 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
924 _dbus_close(fd, NULL);
925 if (saved_errno == EADDRINUSE)
927 /* Depending on kernel policy, it may or may not
928 be neccessary to bind to both IPv4 & 6 addresses
929 so ignore EADDRINUSE here */
933 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
934 "Failed to bind socket \"%s:%s\": %s",
935 host ? host : "*", port, _dbus_strerror (saved_errno));
939 if (listen (fd, 30 /* backlog */) < 0)
942 _dbus_close (fd, NULL);
943 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
944 "Failed to listen on socket \"%s:%s\": %s",
945 host ? host : "*", port, _dbus_strerror (saved_errno));
949 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
953 _dbus_close (fd, NULL);
954 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
955 "Failed to allocate file handle array: %s",
956 _dbus_strerror (saved_errno));
959 listen_fd = newlisten_fd;
960 listen_fd[nlisten_fd] = fd;
963 if (!_dbus_string_get_length(retport))
965 /* If the user didn't specify a port, or used 0, then
966 the kernel chooses a port. After the first address
967 is bound to, we need to force all remaining addresses
968 to use the same port */
969 if (!port || !strcmp(port, "0"))
971 struct sockaddr_storage addr;
975 addrlen = sizeof(addr);
976 getsockname(fd, (struct sockaddr*) &addr, &addrlen);
978 if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
979 portbuf, sizeof(portbuf),
980 NI_NUMERICHOST)) != 0)
982 dbus_set_error (error, _dbus_error_from_errno (errno),
983 "Failed to resolve port \"%s:%s\": %s (%s)",
984 host ? host : "*", port, gai_strerror(res), res);
987 if (!_dbus_string_append(retport, portbuf))
989 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
993 /* Release current address list & redo lookup */
994 port = _dbus_string_get_const_data(retport);
996 goto redo_lookup_with_port;
1000 if (!_dbus_string_append(retport, port))
1002 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1016 dbus_set_error (error, _dbus_error_from_errno (errno),
1017 "Failed to bind socket \"%s:%s\": %s",
1018 host ? host : "*", port, _dbus_strerror (errno));
1022 for (i = 0 ; i < nlisten_fd ; i++)
1024 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1037 for (i = 0 ; i < nlisten_fd ; i++)
1038 _dbus_close(listen_fd[i], NULL);
1039 dbus_free(listen_fd);
1044 write_credentials_byte (int server_fd,
1048 char buf[1] = { '\0' };
1049 #if defined(HAVE_CMSGCRED)
1052 struct cmsgcred cred;
1059 memset (&msg, 0, sizeof (msg));
1063 msg.msg_control = &cmsg;
1064 msg.msg_controllen = sizeof (cmsg);
1065 memset (&cmsg, 0, sizeof (cmsg));
1066 cmsg.hdr.cmsg_len = sizeof (cmsg);
1067 cmsg.hdr.cmsg_level = SOL_SOCKET;
1068 cmsg.hdr.cmsg_type = SCM_CREDS;
1071 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1075 #if defined(HAVE_CMSGCRED)
1076 bytes_written = sendmsg (server_fd, &msg, 0);
1078 bytes_written = write (server_fd, buf, 1);
1081 if (bytes_written < 0 && errno == EINTR)
1084 if (bytes_written < 0)
1086 dbus_set_error (error, _dbus_error_from_errno (errno),
1087 "Failed to write credentials byte: %s",
1088 _dbus_strerror (errno));
1091 else if (bytes_written == 0)
1093 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1094 "wrote zero bytes writing credentials byte");
1099 _dbus_assert (bytes_written == 1);
1100 _dbus_verbose ("wrote credentials byte\n");
1106 * Reads a single byte which must be nul (an error occurs otherwise),
1107 * and reads unix credentials if available. Clears the credentials
1108 * object, then adds pid/uid if available, so any previous credentials
1109 * stored in the object are lost.
1111 * Return value indicates whether a byte was read, not whether
1112 * we got valid credentials. On some systems, such as Linux,
1113 * reading/writing the byte isn't actually required, but we do it
1114 * anyway just to avoid multiple codepaths.
1116 * Fails if no byte is available, so you must select() first.
1118 * The point of the byte is that on some systems we have to
1119 * use sendmsg()/recvmsg() to transmit credentials.
1121 * @param client_fd the client file descriptor
1122 * @param credentials object to add client credentials to
1123 * @param error location to store error code
1124 * @returns #TRUE on success
1127 _dbus_read_credentials_socket (int client_fd,
1128 DBusCredentials *credentials,
1134 dbus_uid_t uid_read;
1135 dbus_pid_t pid_read;
1138 uid_read = DBUS_UID_UNSET;
1139 pid_read = DBUS_PID_UNSET;
1141 #ifdef HAVE_CMSGCRED
1144 struct cmsgcred cred;
1147 #elif defined(LOCAL_CREDS)
1150 struct sockcred cred;
1154 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1156 /* The POSIX spec certainly doesn't promise this, but
1157 * we need these assertions to fail as soon as we're wrong about
1158 * it so we can do the porting fixups
1160 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1161 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1162 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1164 _dbus_credentials_clear (credentials);
1166 /* Systems supporting LOCAL_CREDS are configured to have this feature
1167 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1168 * the connection. Therefore, the received message must carry the
1169 * credentials information without doing anything special.
1172 iov.iov_base = &buf;
1175 memset (&msg, 0, sizeof (msg));
1179 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1180 memset (&cmsg, 0, sizeof (cmsg));
1181 msg.msg_control = &cmsg;
1182 msg.msg_controllen = sizeof (cmsg);
1186 bytes_read = recvmsg (client_fd, &msg, 0);
1193 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1194 * normally only call read_credentials if the socket was ready
1198 dbus_set_error (error, _dbus_error_from_errno (errno),
1199 "Failed to read credentials byte: %s",
1200 _dbus_strerror (errno));
1203 else if (bytes_read == 0)
1205 /* this should not happen unless we are using recvmsg wrong,
1206 * so is essentially here for paranoia
1208 dbus_set_error (error, DBUS_ERROR_FAILED,
1209 "Failed to read credentials byte (zero-length read)");
1212 else if (buf != '\0')
1214 dbus_set_error (error, DBUS_ERROR_FAILED,
1215 "Credentials byte was not nul");
1219 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1220 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
1222 dbus_set_error (error, DBUS_ERROR_FAILED,
1223 "Message from recvmsg() was not SCM_CREDS");
1228 _dbus_verbose ("read credentials byte\n");
1233 int cr_len = sizeof (cr);
1235 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1236 cr_len == sizeof (cr))
1243 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1244 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1246 #elif defined(HAVE_CMSGCRED)
1247 pid_read = cmsg.cred.cmcred_pid;
1248 uid_read = cmsg.cred.cmcred_euid;
1249 #elif defined(LOCAL_CREDS)
1250 pid_read = DBUS_PID_UNSET;
1251 uid_read = cmsg.cred.sc_uid;
1252 /* Since we have already got the credentials from this socket, we can
1253 * disable its LOCAL_CREDS flag if it was ever set. */
1254 _dbus_set_local_creds (client_fd, FALSE);
1255 #elif defined(HAVE_GETPEEREID)
1258 if (getpeereid (client_fd, &euid, &egid) == 0)
1264 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1266 #elif defined(HAVE_GETPEERUCRED)
1267 ucred_t * ucred = NULL;
1268 if (getpeerucred (client_fd, &ucred) == 0)
1270 pid_read = ucred_getpid (ucred);
1271 uid_read = ucred_geteuid (ucred);
1273 /* generate audit session data based on socket ucred */
1274 adt_session_data_t *adth = NULL;
1275 adt_export_data_t *data = NULL;
1277 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1279 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1283 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1285 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1289 size = adt_export_session_data (adth, &data);
1292 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1296 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1300 (void) adt_end_session (adth);
1302 #endif /* HAVE_ADT */
1306 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1310 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1311 _dbus_verbose ("Socket credentials not supported on this OS\n");
1315 _dbus_verbose ("Credentials:"
1316 " pid "DBUS_PID_FORMAT
1317 " uid "DBUS_UID_FORMAT
1322 if (pid_read != DBUS_PID_UNSET)
1324 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1326 _DBUS_SET_OOM (error);
1331 if (uid_read != DBUS_UID_UNSET)
1333 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1335 _DBUS_SET_OOM (error);
1344 * Sends a single nul byte with our UNIX credentials as ancillary
1345 * data. Returns #TRUE if the data was successfully written. On
1346 * systems that don't support sending credentials, just writes a byte,
1347 * doesn't send any credentials. On some systems, such as Linux,
1348 * reading/writing the byte isn't actually required, but we do it
1349 * anyway just to avoid multiple codepaths.
1351 * Fails if no byte can be written, so you must select() first.
1353 * The point of the byte is that on some systems we have to
1354 * use sendmsg()/recvmsg() to transmit credentials.
1356 * @param server_fd file descriptor for connection to server
1357 * @param error return location for error code
1358 * @returns #TRUE if the byte was sent
1361 _dbus_send_credentials_socket (int server_fd,
1364 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1366 if (write_credentials_byte (server_fd, error))
1373 * Accepts a connection on a listening socket.
1374 * Handles EINTR for you.
1376 * @param listen_fd the listen file descriptor
1377 * @returns the connection fd of the client, or -1 on error
1380 _dbus_accept (int listen_fd)
1383 struct sockaddr addr;
1386 addrlen = sizeof (addr);
1389 client_fd = accept (listen_fd, &addr, &addrlen);
1397 _dbus_verbose ("client fd %d accepted\n", client_fd);
1403 * Checks to make sure the given directory is
1404 * private to the user
1406 * @param dir the name of the directory
1407 * @param error error return
1408 * @returns #FALSE on failure
1411 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1413 const char *directory;
1416 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1418 directory = _dbus_string_get_const_data (dir);
1420 if (stat (directory, &sb) < 0)
1422 dbus_set_error (error, _dbus_error_from_errno (errno),
1423 "%s", _dbus_strerror (errno));
1428 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1429 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1431 dbus_set_error (error, DBUS_ERROR_FAILED,
1432 "%s directory is not private to the user", directory);
1440 fill_user_info_from_passwd (struct passwd *p,
1444 _dbus_assert (p->pw_name != NULL);
1445 _dbus_assert (p->pw_dir != NULL);
1447 info->uid = p->pw_uid;
1448 info->primary_gid = p->pw_gid;
1449 info->username = _dbus_strdup (p->pw_name);
1450 info->homedir = _dbus_strdup (p->pw_dir);
1452 if (info->username == NULL ||
1453 info->homedir == NULL)
1455 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1463 fill_user_info (DBusUserInfo *info,
1465 const DBusString *username,
1468 const char *username_c;
1470 /* exactly one of username/uid provided */
1471 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1472 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1474 info->uid = DBUS_UID_UNSET;
1475 info->primary_gid = DBUS_GID_UNSET;
1476 info->group_ids = NULL;
1477 info->n_group_ids = 0;
1478 info->username = NULL;
1479 info->homedir = NULL;
1481 if (username != NULL)
1482 username_c = _dbus_string_get_const_data (username);
1486 /* For now assuming that the getpwnam() and getpwuid() flavors
1487 * are always symmetrical, if not we have to add more configure
1491 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1497 struct passwd p_str;
1499 /* retrieve maximum needed size for buf */
1500 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1502 /* sysconf actually returns a long, but everything else expects size_t,
1503 * so just recast here.
1504 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1506 if ((long) buflen <= 0)
1512 buf = dbus_malloc (buflen);
1515 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1520 #ifdef HAVE_POSIX_GETPWNAM_R
1521 if (uid != DBUS_UID_UNSET)
1522 result = getpwuid_r (uid, &p_str, buf, buflen,
1525 result = getpwnam_r (username_c, &p_str, buf, buflen,
1528 if (uid != DBUS_UID_UNSET)
1529 p = getpwuid_r (uid, &p_str, buf, buflen);
1531 p = getpwnam_r (username_c, &p_str, buf, buflen);
1533 #endif /* !HAVE_POSIX_GETPWNAM_R */
1534 //Try a bigger buffer if ERANGE was returned
1535 if (result == ERANGE && buflen < 512 * 1024)
1545 if (result == 0 && p == &p_str)
1547 if (!fill_user_info_from_passwd (p, info, error))
1556 dbus_set_error (error, _dbus_error_from_errno (errno),
1557 "User \"%s\" unknown or no memory to allocate password entry\n",
1558 username_c ? username_c : "???");
1559 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1564 #else /* ! HAVE_GETPWNAM_R */
1566 /* I guess we're screwed on thread safety here */
1569 if (uid != DBUS_UID_UNSET)
1572 p = getpwnam (username_c);
1576 if (!fill_user_info_from_passwd (p, info, error))
1583 dbus_set_error (error, _dbus_error_from_errno (errno),
1584 "User \"%s\" unknown or no memory to allocate password entry\n",
1585 username_c ? username_c : "???");
1586 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1590 #endif /* ! HAVE_GETPWNAM_R */
1592 /* Fill this in so we can use it to get groups */
1593 username_c = info->username;
1595 #ifdef HAVE_GETGROUPLIST
1600 int initial_buf_count;
1602 initial_buf_count = 17;
1603 buf_count = initial_buf_count;
1604 buf = dbus_new (gid_t, buf_count);
1607 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1611 if (getgrouplist (username_c,
1613 buf, &buf_count) < 0)
1616 /* Presumed cause of negative return code: buf has insufficient
1617 entries to hold the entire group list. The Linux behavior in this
1618 case is to pass back the actual number of groups in buf_count, but
1619 on Mac OS X 10.5, buf_count is unhelpfully left alone.
1620 So as a hack, try to help out a bit by guessing a larger
1621 number of groups, within reason.. might still fail, of course,
1622 but we can at least print a more informative message. I looked up
1623 the "right way" to do this by downloading Apple's own source code
1624 for the "id" command, and it turns out that they use an
1625 undocumented library function getgrouplist_2 (!) which is not
1626 declared in any header in /usr/include (!!). That did not seem
1627 like the way to go here.
1629 if (buf_count == initial_buf_count)
1631 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
1633 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1636 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1644 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
1648 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
1649 username_c, buf_count, buf_count);
1653 dbus_set_error (error,
1654 _dbus_error_from_errno (errno),
1655 "Failed to get groups for username \"%s\" primary GID "
1656 DBUS_GID_FORMAT ": %s\n",
1657 username_c, info->primary_gid,
1658 _dbus_strerror (errno));
1665 info->group_ids = dbus_new (dbus_gid_t, buf_count);
1666 if (info->group_ids == NULL)
1668 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1673 for (i = 0; i < buf_count; ++i)
1674 info->group_ids[i] = buf[i];
1676 info->n_group_ids = buf_count;
1680 #else /* HAVE_GETGROUPLIST */
1682 /* We just get the one group ID */
1683 info->group_ids = dbus_new (dbus_gid_t, 1);
1684 if (info->group_ids == NULL)
1686 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1690 info->n_group_ids = 1;
1692 (info->group_ids)[0] = info->primary_gid;
1694 #endif /* HAVE_GETGROUPLIST */
1696 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1701 _DBUS_ASSERT_ERROR_IS_SET (error);
1706 * Gets user info for the given username.
1708 * @param info user info object to initialize
1709 * @param username the username
1710 * @param error error return
1711 * @returns #TRUE on success
1714 _dbus_user_info_fill (DBusUserInfo *info,
1715 const DBusString *username,
1718 return fill_user_info (info, DBUS_UID_UNSET,
1723 * Gets user info for the given user ID.
1725 * @param info user info object to initialize
1726 * @param uid the user ID
1727 * @param error error return
1728 * @returns #TRUE on success
1731 _dbus_user_info_fill_uid (DBusUserInfo *info,
1735 return fill_user_info (info, uid,
1740 * Adds the credentials of the current process to the
1741 * passed-in credentials object.
1743 * @param credentials credentials to add to
1744 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
1747 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
1749 /* The POSIX spec certainly doesn't promise this, but
1750 * we need these assertions to fail as soon as we're wrong about
1751 * it so we can do the porting fixups
1753 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1754 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1755 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1757 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
1759 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
1766 * Append to the string the identity we would like to have when we
1767 * authenticate, on UNIX this is the current process UID and on
1768 * Windows something else, probably a Windows SID string. No escaping
1769 * is required, that is done in dbus-auth.c. The username here
1770 * need not be anything human-readable, it can be the machine-readable
1771 * form i.e. a user id.
1773 * @param str the string to append to
1774 * @returns #FALSE on no memory
1777 _dbus_append_user_from_current_process (DBusString *str)
1779 return _dbus_string_append_uint (str,
1784 * Gets our process ID
1785 * @returns process ID
1794 * @returns process UID
1802 /** Gets our effective UID
1803 * @returns process effective UID
1806 _dbus_geteuid (void)
1812 * The only reason this is separate from _dbus_getpid() is to allow it
1813 * on Windows for logging but not for other purposes.
1815 * @returns process ID to put in log messages
1818 _dbus_pid_for_log (void)
1824 * Gets a UID from a UID string.
1826 * @param uid_str the UID in string form
1827 * @param uid UID to fill in
1828 * @returns #TRUE if successfully filled in UID
1831 _dbus_parse_uid (const DBusString *uid_str,
1837 if (_dbus_string_get_length (uid_str) == 0)
1839 _dbus_verbose ("UID string was zero length\n");
1845 if (!_dbus_string_parse_int (uid_str, 0, &val,
1848 _dbus_verbose ("could not parse string as a UID\n");
1852 if (end != _dbus_string_get_length (uid_str))
1854 _dbus_verbose ("string contained trailing stuff after UID\n");
1864 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
1866 #if DBUS_USE_ATOMIC_INT_486_COND
1867 /* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */
1868 /* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */
1869 static inline dbus_int32_t
1870 atomic_exchange_and_add (DBusAtomic *atomic,
1871 volatile dbus_int32_t val)
1873 register dbus_int32_t result;
1875 __asm__ __volatile__ ("lock; xaddl %0,%1"
1876 : "=r" (result), "=m" (atomic->value)
1877 : "0" (val), "m" (atomic->value));
1883 * Atomically increments an integer
1885 * @param atomic pointer to the integer to increment
1886 * @returns the value before incrementing
1888 * @todo implement arch-specific faster atomic ops
1891 _dbus_atomic_inc (DBusAtomic *atomic)
1893 #if DBUS_USE_ATOMIC_INT_486_COND
1894 return atomic_exchange_and_add (atomic, 1);
1897 _DBUS_LOCK (atomic);
1898 res = atomic->value;
1900 _DBUS_UNLOCK (atomic);
1906 * Atomically decrement an integer
1908 * @param atomic pointer to the integer to decrement
1909 * @returns the value before decrementing
1911 * @todo implement arch-specific faster atomic ops
1914 _dbus_atomic_dec (DBusAtomic *atomic)
1916 #if DBUS_USE_ATOMIC_INT_486_COND
1917 return atomic_exchange_and_add (atomic, -1);
1921 _DBUS_LOCK (atomic);
1922 res = atomic->value;
1924 _DBUS_UNLOCK (atomic);
1929 #ifdef DBUS_BUILD_TESTS
1931 * @returns process GID
1941 * Wrapper for poll().
1943 * @param fds the file descriptors to poll
1944 * @param n_fds number of descriptors in the array
1945 * @param timeout_milliseconds timeout or -1 for infinite
1946 * @returns numbers of fds with revents, or <0 on error
1949 _dbus_poll (DBusPollFD *fds,
1951 int timeout_milliseconds)
1953 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
1954 /* This big thing is a constant expression and should get optimized
1955 * out of existence. So it's more robust than a configure check at
1958 if (_DBUS_POLLIN == POLLIN &&
1959 _DBUS_POLLPRI == POLLPRI &&
1960 _DBUS_POLLOUT == POLLOUT &&
1961 _DBUS_POLLERR == POLLERR &&
1962 _DBUS_POLLHUP == POLLHUP &&
1963 _DBUS_POLLNVAL == POLLNVAL &&
1964 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
1965 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
1966 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
1967 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
1968 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
1969 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
1970 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
1972 return poll ((struct pollfd*) fds,
1974 timeout_milliseconds);
1978 /* We have to convert the DBusPollFD to an array of
1979 * struct pollfd, poll, and convert back.
1981 _dbus_warn ("didn't implement poll() properly for this system yet\n");
1984 #else /* ! HAVE_POLL */
1986 fd_set read_set, write_set, err_set;
1992 FD_ZERO (&read_set);
1993 FD_ZERO (&write_set);
1996 for (i = 0; i < n_fds; i++)
1998 DBusPollFD *fdp = &fds[i];
2000 if (fdp->events & _DBUS_POLLIN)
2001 FD_SET (fdp->fd, &read_set);
2003 if (fdp->events & _DBUS_POLLOUT)
2004 FD_SET (fdp->fd, &write_set);
2006 FD_SET (fdp->fd, &err_set);
2008 max_fd = MAX (max_fd, fdp->fd);
2011 tv.tv_sec = timeout_milliseconds / 1000;
2012 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2014 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2015 timeout_milliseconds < 0 ? NULL : &tv);
2019 for (i = 0; i < n_fds; i++)
2021 DBusPollFD *fdp = &fds[i];
2025 if (FD_ISSET (fdp->fd, &read_set))
2026 fdp->revents |= _DBUS_POLLIN;
2028 if (FD_ISSET (fdp->fd, &write_set))
2029 fdp->revents |= _DBUS_POLLOUT;
2031 if (FD_ISSET (fdp->fd, &err_set))
2032 fdp->revents |= _DBUS_POLLERR;
2041 * Get current time, as in gettimeofday().
2043 * @param tv_sec return location for number of seconds
2044 * @param tv_usec return location for number of microseconds (thousandths)
2047 _dbus_get_current_time (long *tv_sec,
2052 gettimeofday (&t, NULL);
2057 *tv_usec = t.tv_usec;
2061 * Appends the contents of the given file to the string,
2062 * returning error code. At the moment, won't open a file
2063 * more than a megabyte in size.
2065 * @param str the string to append to
2066 * @param filename filename to load
2067 * @param error place to set an error
2068 * @returns #FALSE if error was set
2071 _dbus_file_get_contents (DBusString *str,
2072 const DBusString *filename,
2079 const char *filename_c;
2081 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2083 filename_c = _dbus_string_get_const_data (filename);
2085 /* O_BINARY useful on Cygwin */
2086 fd = open (filename_c, O_RDONLY | O_BINARY);
2089 dbus_set_error (error, _dbus_error_from_errno (errno),
2090 "Failed to open \"%s\": %s",
2092 _dbus_strerror (errno));
2096 _dbus_verbose ("file fd %d opened\n", fd);
2098 if (fstat (fd, &sb) < 0)
2100 dbus_set_error (error, _dbus_error_from_errno (errno),
2101 "Failed to stat \"%s\": %s",
2103 _dbus_strerror (errno));
2105 _dbus_verbose ("fstat() failed: %s",
2106 _dbus_strerror (errno));
2108 _dbus_close (fd, NULL);
2113 if (sb.st_size > _DBUS_ONE_MEGABYTE)
2115 dbus_set_error (error, DBUS_ERROR_FAILED,
2116 "File size %lu of \"%s\" is too large.",
2117 (unsigned long) sb.st_size, filename_c);
2118 _dbus_close (fd, NULL);
2123 orig_len = _dbus_string_get_length (str);
2124 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
2128 while (total < (int) sb.st_size)
2130 bytes_read = _dbus_read (fd, str,
2131 sb.st_size - total);
2132 if (bytes_read <= 0)
2134 dbus_set_error (error, _dbus_error_from_errno (errno),
2135 "Error reading \"%s\": %s",
2137 _dbus_strerror (errno));
2139 _dbus_verbose ("read() failed: %s",
2140 _dbus_strerror (errno));
2142 _dbus_close (fd, NULL);
2143 _dbus_string_set_length (str, orig_len);
2147 total += bytes_read;
2150 _dbus_close (fd, NULL);
2153 else if (sb.st_size != 0)
2155 _dbus_verbose ("Can only open regular files at the moment.\n");
2156 dbus_set_error (error, DBUS_ERROR_FAILED,
2157 "\"%s\" is not a regular file",
2159 _dbus_close (fd, NULL);
2164 _dbus_close (fd, NULL);
2170 * Writes a string out to a file. If the file exists,
2171 * it will be atomically overwritten by the new data.
2173 * @param str the string to write out
2174 * @param filename the file to save string to
2175 * @param error error to be filled in on failure
2176 * @returns #FALSE on failure
2179 _dbus_string_save_to_file (const DBusString *str,
2180 const DBusString *filename,
2185 const char *filename_c;
2186 DBusString tmp_filename;
2187 const char *tmp_filename_c;
2189 dbus_bool_t need_unlink;
2192 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2196 need_unlink = FALSE;
2198 if (!_dbus_string_init (&tmp_filename))
2200 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2204 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2206 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2207 _dbus_string_free (&tmp_filename);
2211 if (!_dbus_string_append (&tmp_filename, "."))
2213 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2214 _dbus_string_free (&tmp_filename);
2218 #define N_TMP_FILENAME_RANDOM_BYTES 8
2219 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2221 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2222 _dbus_string_free (&tmp_filename);
2226 filename_c = _dbus_string_get_const_data (filename);
2227 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2229 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2233 dbus_set_error (error, _dbus_error_from_errno (errno),
2234 "Could not create %s: %s", tmp_filename_c,
2235 _dbus_strerror (errno));
2239 _dbus_verbose ("tmp file fd %d opened\n", fd);
2244 bytes_to_write = _dbus_string_get_length (str);
2246 while (total < bytes_to_write)
2250 bytes_written = _dbus_write (fd, str, total,
2251 bytes_to_write - total);
2253 if (bytes_written <= 0)
2255 dbus_set_error (error, _dbus_error_from_errno (errno),
2256 "Could not write to %s: %s", tmp_filename_c,
2257 _dbus_strerror (errno));
2262 total += bytes_written;
2267 dbus_set_error (error, _dbus_error_from_errno (errno),
2268 "Could not synchronize file %s: %s",
2269 tmp_filename_c, _dbus_strerror (errno));
2274 if (!_dbus_close (fd, NULL))
2276 dbus_set_error (error, _dbus_error_from_errno (errno),
2277 "Could not close file %s: %s",
2278 tmp_filename_c, _dbus_strerror (errno));
2285 if (rename (tmp_filename_c, filename_c) < 0)
2287 dbus_set_error (error, _dbus_error_from_errno (errno),
2288 "Could not rename %s to %s: %s",
2289 tmp_filename_c, filename_c,
2290 _dbus_strerror (errno));
2295 need_unlink = FALSE;
2300 /* close first, then unlink, to prevent ".nfs34234235" garbage
2305 _dbus_close (fd, NULL);
2307 if (need_unlink && unlink (tmp_filename_c) < 0)
2308 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2309 tmp_filename_c, _dbus_strerror (errno));
2311 _dbus_string_free (&tmp_filename);
2314 _DBUS_ASSERT_ERROR_IS_SET (error);
2319 /** Makes the file readable by every user in the system.
2321 * @param filename the filename
2322 * @param error error location
2323 * @returns #TRUE if the file's permissions could be changed.
2326 _dbus_make_file_world_readable(const DBusString *filename,
2329 const char *filename_c;
2331 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2333 filename_c = _dbus_string_get_const_data (filename);
2334 if (chmod (filename_c, 0644) == -1)
2336 dbus_set_error (error,
2338 "Could not change permissions of file %s: %s\n",
2340 _dbus_strerror (errno));
2346 /** Creates the given file, failing if the file already exists.
2348 * @param filename the filename
2349 * @param error error location
2350 * @returns #TRUE if we created the file and it didn't exist
2353 _dbus_create_file_exclusively (const DBusString *filename,
2357 const char *filename_c;
2359 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2361 filename_c = _dbus_string_get_const_data (filename);
2363 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2367 dbus_set_error (error,
2369 "Could not create file %s: %s\n",
2371 _dbus_strerror (errno));
2375 _dbus_verbose ("exclusive file fd %d opened\n", fd);
2377 if (!_dbus_close (fd, NULL))
2379 dbus_set_error (error,
2381 "Could not close file %s: %s\n",
2383 _dbus_strerror (errno));
2391 * Deletes the given file.
2393 * @param filename the filename
2394 * @param error error location
2396 * @returns #TRUE if unlink() succeeded
2399 _dbus_delete_file (const DBusString *filename,
2402 const char *filename_c;
2404 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2406 filename_c = _dbus_string_get_const_data (filename);
2408 if (unlink (filename_c) < 0)
2410 dbus_set_error (error, DBUS_ERROR_FAILED,
2411 "Failed to delete file %s: %s\n",
2412 filename_c, _dbus_strerror (errno));
2420 * Creates a directory; succeeds if the directory
2421 * is created or already existed.
2423 * @param filename directory filename
2424 * @param error initialized error object
2425 * @returns #TRUE on success
2428 _dbus_create_directory (const DBusString *filename,
2431 const char *filename_c;
2433 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2435 filename_c = _dbus_string_get_const_data (filename);
2437 if (mkdir (filename_c, 0700) < 0)
2439 if (errno == EEXIST)
2442 dbus_set_error (error, DBUS_ERROR_FAILED,
2443 "Failed to create directory %s: %s\n",
2444 filename_c, _dbus_strerror (errno));
2452 * Appends the given filename to the given directory.
2454 * @todo it might be cute to collapse multiple '/' such as "foo//"
2457 * @param dir the directory name
2458 * @param next_component the filename
2459 * @returns #TRUE on success
2462 _dbus_concat_dir_and_file (DBusString *dir,
2463 const DBusString *next_component)
2465 dbus_bool_t dir_ends_in_slash;
2466 dbus_bool_t file_starts_with_slash;
2468 if (_dbus_string_get_length (dir) == 0 ||
2469 _dbus_string_get_length (next_component) == 0)
2472 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2473 _dbus_string_get_length (dir) - 1);
2475 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2477 if (dir_ends_in_slash && file_starts_with_slash)
2479 _dbus_string_shorten (dir, 1);
2481 else if (!(dir_ends_in_slash || file_starts_with_slash))
2483 if (!_dbus_string_append_byte (dir, '/'))
2487 return _dbus_string_copy (next_component, 0, dir,
2488 _dbus_string_get_length (dir));
2491 /** nanoseconds in a second */
2492 #define NANOSECONDS_PER_SECOND 1000000000
2493 /** microseconds in a second */
2494 #define MICROSECONDS_PER_SECOND 1000000
2495 /** milliseconds in a second */
2496 #define MILLISECONDS_PER_SECOND 1000
2497 /** nanoseconds in a millisecond */
2498 #define NANOSECONDS_PER_MILLISECOND 1000000
2499 /** microseconds in a millisecond */
2500 #define MICROSECONDS_PER_MILLISECOND 1000
2503 * Sleeps the given number of milliseconds.
2504 * @param milliseconds number of milliseconds
2507 _dbus_sleep_milliseconds (int milliseconds)
2509 #ifdef HAVE_NANOSLEEP
2510 struct timespec req;
2511 struct timespec rem;
2513 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2514 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2518 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2520 #elif defined (HAVE_USLEEP)
2521 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2522 #else /* ! HAVE_USLEEP */
2523 sleep (MAX (milliseconds / 1000, 1));
2528 _dbus_generate_pseudorandom_bytes (DBusString *str,
2534 old_len = _dbus_string_get_length (str);
2536 if (!_dbus_string_lengthen (str, n_bytes))
2539 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2541 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2547 * Generates the given number of random bytes,
2548 * using the best mechanism we can come up with.
2550 * @param str the string
2551 * @param n_bytes the number of random bytes to append to string
2552 * @returns #TRUE on success, #FALSE if no memory
2555 _dbus_generate_random_bytes (DBusString *str,
2561 /* FALSE return means "no memory", if it could
2562 * mean something else then we'd need to return
2563 * a DBusError. So we always fall back to pseudorandom
2567 old_len = _dbus_string_get_length (str);
2570 /* note, urandom on linux will fall back to pseudorandom */
2571 fd = open ("/dev/urandom", O_RDONLY);
2573 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2575 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2577 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2579 _dbus_close (fd, NULL);
2580 _dbus_string_set_length (str, old_len);
2581 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2584 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2587 _dbus_close (fd, NULL);
2593 * Exit the process, returning the given value.
2595 * @param code the exit code
2598 _dbus_exit (int code)
2604 * A wrapper around strerror() because some platforms
2605 * may be lame and not have strerror(). Also, never
2608 * @param error_number errno.
2609 * @returns error description.
2612 _dbus_strerror (int error_number)
2616 msg = strerror (error_number);
2624 * signal (SIGPIPE, SIG_IGN);
2627 _dbus_disable_sigpipe (void)
2629 signal (SIGPIPE, SIG_IGN);
2633 * Sets the file descriptor to be close
2634 * on exec. Should be called for all file
2635 * descriptors in D-Bus code.
2637 * @param fd the file descriptor
2640 _dbus_fd_set_close_on_exec (int fd)
2644 val = fcntl (fd, F_GETFD, 0);
2651 fcntl (fd, F_SETFD, val);
2655 * Closes a file descriptor.
2657 * @param fd the file descriptor
2658 * @param error error object
2659 * @returns #FALSE if error set
2662 _dbus_close (int fd,
2665 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2673 dbus_set_error (error, _dbus_error_from_errno (errno),
2674 "Could not close fd %d", fd);
2682 * Sets a file descriptor to be nonblocking.
2684 * @param fd the file descriptor.
2685 * @param error address of error location.
2686 * @returns #TRUE on success.
2689 _dbus_set_fd_nonblocking (int fd,
2694 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2696 val = fcntl (fd, F_GETFL, 0);
2699 dbus_set_error (error, _dbus_error_from_errno (errno),
2700 "Failed to get flags from file descriptor %d: %s",
2701 fd, _dbus_strerror (errno));
2702 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2703 _dbus_strerror (errno));
2707 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2709 dbus_set_error (error, _dbus_error_from_errno (errno),
2710 "Failed to set nonblocking flag of file descriptor %d: %s",
2711 fd, _dbus_strerror (errno));
2712 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2713 fd, _dbus_strerror (errno));
2722 * On GNU libc systems, print a crude backtrace to stderr. On other
2723 * systems, print "no backtrace support" and block for possible gdb
2724 * attachment if an appropriate environment variable is set.
2727 _dbus_print_backtrace (void)
2729 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2735 bt_size = backtrace (bt, 500);
2737 syms = backtrace_symbols (bt, bt_size);
2742 /* don't use dbus_warn since it can _dbus_abort() */
2743 fprintf (stderr, " %s\n", syms[i]);
2749 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2750 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
2752 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2757 * Creates a full-duplex pipe (as in socketpair()).
2758 * Sets both ends of the pipe nonblocking.
2760 * @todo libdbus only uses this for the debug-pipe server, so in
2761 * principle it could be in dbus-sysdeps-util.c, except that
2762 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2763 * debug-pipe server is used.
2765 * @param fd1 return location for one end
2766 * @param fd2 return location for the other end
2767 * @param blocking #TRUE if pipe should be blocking
2768 * @param error error return
2769 * @returns #FALSE on failure (if error is set)
2772 _dbus_full_duplex_pipe (int *fd1,
2774 dbus_bool_t blocking,
2777 #ifdef HAVE_SOCKETPAIR
2780 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2782 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2784 dbus_set_error (error, _dbus_error_from_errno (errno),
2785 "Could not create full-duplex pipe");
2790 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2791 !_dbus_set_fd_nonblocking (fds[1], NULL)))
2793 dbus_set_error (error, _dbus_error_from_errno (errno),
2794 "Could not set full-duplex pipe nonblocking");
2796 _dbus_close (fds[0], NULL);
2797 _dbus_close (fds[1], NULL);
2805 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2810 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2811 dbus_set_error (error, DBUS_ERROR_FAILED,
2812 "_dbus_full_duplex_pipe() not implemented on this OS");
2818 * Measure the length of the given format string and arguments,
2819 * not including the terminating nul.
2821 * @param format a printf-style format string
2822 * @param args arguments for the format string
2823 * @returns length of the given format string and args
2826 _dbus_printf_string_upper_bound (const char *format,
2830 return vsnprintf (&c, 1, format, args);
2834 * Gets the temporary files directory by inspecting the environment variables
2835 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2837 * @returns location of temp directory
2840 _dbus_get_tmpdir(void)
2842 static const char* tmpdir = NULL;
2846 /* TMPDIR is what glibc uses, then
2847 * glibc falls back to the P_tmpdir macro which
2848 * just expands to "/tmp"
2851 tmpdir = getenv("TMPDIR");
2853 /* These two env variables are probably
2854 * broken, but maybe some OS uses them?
2857 tmpdir = getenv("TMP");
2859 tmpdir = getenv("TEMP");
2861 /* And this is the sane fallback. */
2866 _dbus_assert(tmpdir != NULL);
2872 * Determines the address of the session bus by querying a
2873 * platform-specific method.
2875 * If successful, returns #TRUE and appends the address to @p
2876 * address. If a failure happens, returns #FALSE and
2877 * sets an error in @p error.
2879 * @param address a DBusString where the address can be stored
2880 * @param error a DBusError to store the error in case of failure
2881 * @returns #TRUE on success, #FALSE if an error happened
2884 _dbus_get_autolaunch_address (DBusString *address,
2887 static char *argv[6];
2888 int address_pipe[2] = { -1, -1 };
2889 int errors_pipe[2] = { -1, -1 };
2897 sigset_t new_set, old_set;
2899 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2902 if (!_dbus_string_init (&uuid))
2904 _DBUS_SET_OOM (error);
2908 /* We need to block any existing handlers for SIGCHLD temporarily; they
2909 * will cause waitpid() below to fail.
2910 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
2912 sigemptyset (&new_set);
2913 sigaddset (&new_set, SIGCHLD);
2914 sigprocmask (SIG_BLOCK, &new_set, &old_set);
2916 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
2918 _DBUS_SET_OOM (error);
2923 argv[i] = "dbus-launch";
2925 argv[i] = "--autolaunch";
2927 argv[i] = _dbus_string_get_data (&uuid);
2929 argv[i] = "--binary-syntax";
2931 argv[i] = "--close-stderr";
2936 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
2938 orig_len = _dbus_string_get_length (address);
2942 if (pipe (address_pipe) < 0)
2944 dbus_set_error (error, _dbus_error_from_errno (errno),
2945 "Failed to create a pipe: %s",
2946 _dbus_strerror (errno));
2947 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
2948 _dbus_strerror (errno));
2951 if (pipe (errors_pipe) < 0)
2953 dbus_set_error (error, _dbus_error_from_errno (errno),
2954 "Failed to create a pipe: %s",
2955 _dbus_strerror (errno));
2956 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
2957 _dbus_strerror (errno));
2964 dbus_set_error (error, _dbus_error_from_errno (errno),
2965 "Failed to fork(): %s",
2966 _dbus_strerror (errno));
2967 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
2968 _dbus_strerror (errno));
2978 fd = open ("/dev/null", O_RDWR);
2980 /* huh?! can't open /dev/null? */
2983 _dbus_verbose ("/dev/null fd %d opened\n", fd);
2986 close (address_pipe[READ_END]);
2987 close (errors_pipe[READ_END]);
2988 close (0); /* close stdin */
2989 close (1); /* close stdout */
2990 close (2); /* close stderr */
2992 if (dup2 (fd, 0) == -1)
2994 if (dup2 (address_pipe[WRITE_END], 1) == -1)
2996 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
2999 maxfds = sysconf (_SC_OPEN_MAX);
3000 /* Pick something reasonable if for some reason sysconf
3005 /* close all inherited fds */
3006 for (i = 3; i < maxfds; i++)
3009 sigprocmask(SIG_SETMASK, &old_set, NULL);
3011 execv (DBUS_BINDIR "/dbus-launch", argv);
3013 /* failed, try searching PATH */
3014 execvp ("dbus-launch", argv);
3016 /* still nothing, we failed */
3020 /* parent process */
3021 close (address_pipe[WRITE_END]);
3022 close (errors_pipe[WRITE_END]);
3023 address_pipe[WRITE_END] = -1;
3024 errors_pipe[WRITE_END] = -1;
3029 ret = _dbus_read (address_pipe[READ_END], address, 1024);
3033 /* reap the child process to avoid it lingering as zombie */
3036 ret = waitpid (pid, &status, 0);
3038 while (ret == -1 && errno == EINTR);
3040 /* We succeeded if the process exited with status 0 and
3041 anything was read */
3042 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
3043 _dbus_string_get_length (address) == orig_len)
3045 /* The process ended with error */
3046 DBusString error_message;
3047 _dbus_string_init (&error_message);
3051 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3055 _dbus_string_set_length (address, orig_len);
3056 if (_dbus_string_get_length (&error_message) > 0)
3057 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3058 "dbus-launch failed to autolaunch D-Bus session: %s",
3059 _dbus_string_get_data (&error_message));
3061 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3062 "Failed to execute dbus-launch to autolaunch D-Bus session");
3069 sigprocmask (SIG_SETMASK, &old_set, NULL);
3072 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3074 _DBUS_ASSERT_ERROR_IS_SET (error);
3076 if (address_pipe[0] != -1)
3077 close (address_pipe[0]);
3078 if (address_pipe[1] != -1)
3079 close (address_pipe[1]);
3080 if (errors_pipe[0] != -1)
3081 close (errors_pipe[0]);
3082 if (errors_pipe[1] != -1)
3083 close (errors_pipe[1]);
3085 _dbus_string_free (&uuid);
3090 * Reads the uuid of the machine we're running on from
3091 * the dbus configuration. Optionally try to create it
3092 * (only root can do this usually).
3094 * On UNIX, reads a file that gets created by dbus-uuidgen
3095 * in a post-install script. On Windows, if there's a standard
3096 * machine uuid we could just use that, but I can't find one
3097 * with the right properties (the hardware profile guid can change
3098 * without rebooting I believe). If there's no standard one
3099 * we might want to use the registry instead of a file for
3100 * this, and I'm not sure how we'd ensure the uuid gets created.
3102 * @param machine_id guid to init with the machine's uuid
3103 * @param create_if_not_found try to create the uuid if it doesn't exist
3104 * @param error the error return
3105 * @returns #FALSE if the error is set
3108 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3109 dbus_bool_t create_if_not_found,
3112 DBusString filename;
3113 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3114 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3117 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3118 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3121 * Determines the address of the session bus by querying a
3122 * platform-specific method.
3124 * The first parameter will be a boolean specifying whether
3125 * or not a dynamic session lookup is supported on this platform.
3127 * If supported is TRUE and the return value is #TRUE, the
3128 * address will be appended to @p address.
3129 * If a failure happens, returns #FALSE and sets an error in
3132 * If supported is FALSE, ignore the return value.
3134 * @param supported returns whether this method is supported
3135 * @param address a DBusString where the address can be stored
3136 * @param error a DBusError to store the error in case of failure
3137 * @returns #TRUE on success, #FALSE if an error happened
3140 _dbus_lookup_session_address (dbus_bool_t *supported,
3141 DBusString *address,
3144 /* On non-Mac Unix platforms, if the session address isn't already
3145 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3146 * fall back to the autolaunch: global default; see
3147 * init_session_address in dbus/dbus-bus.c. */
3153 * Returns the standard directories for a session bus to look for service
3156 * On UNIX this should be the standard xdg freedesktop.org data directories:
3158 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3159 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3165 * @param dirs the directory list we are returning
3166 * @returns #FALSE on OOM
3170 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3172 const char *xdg_data_home;
3173 const char *xdg_data_dirs;
3174 DBusString servicedir_path;
3176 if (!_dbus_string_init (&servicedir_path))
3179 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3180 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3182 if (xdg_data_dirs != NULL)
3184 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3187 if (!_dbus_string_append (&servicedir_path, ":"))
3192 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3197 * add configured datadir to defaults
3198 * this may be the same as an xdg dir
3199 * however the config parser should take
3200 * care of duplicates
3202 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3205 if (xdg_data_home != NULL)
3207 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3212 const DBusString *homedir;
3213 DBusString local_share;
3215 if (!_dbus_homedir_from_current_process (&homedir))
3218 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3221 _dbus_string_init_const (&local_share, "/.local/share");
3222 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3226 if (!_dbus_split_paths_and_append (&servicedir_path,
3227 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3231 _dbus_string_free (&servicedir_path);
3235 _dbus_string_free (&servicedir_path);
3241 * Returns the standard directories for a system bus to look for service
3244 * On UNIX this should be the standard xdg freedesktop.org data directories:
3246 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3252 * On Windows there is no system bus and this function can return nothing.
3254 * @param dirs the directory list we are returning
3255 * @returns #FALSE on OOM
3259 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3261 const char *xdg_data_dirs;
3262 DBusString servicedir_path;
3264 if (!_dbus_string_init (&servicedir_path))
3267 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3269 if (xdg_data_dirs != NULL)
3271 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3274 if (!_dbus_string_append (&servicedir_path, ":"))
3279 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3284 * add configured datadir to defaults
3285 * this may be the same as an xdg dir
3286 * however the config parser should take
3287 * care of duplicates
3289 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3292 if (!_dbus_split_paths_and_append (&servicedir_path,
3293 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3297 _dbus_string_free (&servicedir_path);
3301 _dbus_string_free (&servicedir_path);
3306 * Append the absolute path of the system.conf file
3307 * (there is no system bus on Windows so this can just
3308 * return FALSE and print a warning or something)
3310 * @param str the string to append to
3311 * @returns #FALSE if no memory
3314 _dbus_append_system_config_file (DBusString *str)
3316 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3320 * Append the absolute path of the session.conf file.
3322 * @param str the string to append to
3323 * @returns #FALSE if no memory
3326 _dbus_append_session_config_file (DBusString *str)
3328 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3332 * Called when the bus daemon is signaled to reload its configuration; any
3333 * caches should be nuked. Of course any caches that need explicit reload
3334 * are probably broken, but c'est la vie.
3339 _dbus_flush_caches (void)
3341 _dbus_user_database_flush_system ();
3345 * Appends the directory in which a keyring for the given credentials
3346 * should be stored. The credentials should have either a Windows or
3347 * UNIX user in them. The directory should be an absolute path.
3349 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3350 * be something else, since the dotfile convention is not normal on Windows.
3352 * @param directory string to append directory to
3353 * @param credentials credentials the directory should be for
3355 * @returns #FALSE on no memory
3358 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3359 DBusCredentials *credentials)
3365 _dbus_assert (credentials != NULL);
3366 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3368 if (!_dbus_string_init (&homedir))
3371 uid = _dbus_credentials_get_unix_uid (credentials);
3372 _dbus_assert (uid != DBUS_UID_UNSET);
3374 if (!_dbus_homedir_from_uid (uid, &homedir))
3377 #ifdef DBUS_BUILD_TESTS
3379 const char *override;
3381 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3382 if (override != NULL && *override != '\0')
3384 _dbus_string_set_length (&homedir, 0);
3385 if (!_dbus_string_append (&homedir, override))
3388 _dbus_verbose ("Using fake homedir for testing: %s\n",
3389 _dbus_string_get_const_data (&homedir));
3393 static dbus_bool_t already_warned = FALSE;
3394 if (!already_warned)
3396 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3397 already_warned = TRUE;
3403 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3404 if (!_dbus_concat_dir_and_file (&homedir,
3408 if (!_dbus_string_copy (&homedir, 0,
3409 directory, _dbus_string_get_length (directory))) {
3413 _dbus_string_free (&homedir);
3417 _dbus_string_free (&homedir);
3423 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3424 * for Winsock so is abstracted)
3426 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3429 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3431 return errno == EAGAIN || errno == EWOULDBLOCK;
3434 /* tests in dbus-sysdeps-util.c */