1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-sysdeps.c Wrappers around system/libc features (internal to D-BUS implementation)
4 * Copyright (C) 2002, 2003 Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
7 * Licensed under the Academic Free License version 1.2
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "dbus-internals.h"
26 #include "dbus-sysdeps.h"
27 #include "dbus-threads.h"
28 #include "dbus-test.h"
29 #include <sys/types.h>
37 #include <sys/socket.h>
45 #include <netinet/in.h>
65 /* This system is not POSIX.1g. */
66 #define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
67 + strlen ((ptr)->sun_path))
71 * @addtogroup DBusInternalsUtils
75 * Aborts the program with SIGABRT (dumping core).
81 _exit (1); /* in case someone manages to ignore SIGABRT */
85 * Wrapper for setenv(). If the value is #NULL, unsets
86 * the environment variable.
88 * @todo if someone can verify it's safe, we could avoid the
89 * memleak when doing an unset.
91 * @param varname name of environment variable
92 * @param value value of environment variable
93 * @returns #TRUE on success.
96 _dbus_setenv (const char *varname,
99 _dbus_assert (varname != NULL);
110 len = strlen (varname);
112 /* Use system malloc to avoid memleaks that dbus_malloc
113 * will get upset about.
116 putenv_value = malloc (len + 1);
117 if (putenv_value == NULL)
120 strcpy (putenv_value, varname);
122 return (putenv (putenv_value) == 0);
128 return (setenv (varname, value, TRUE) == 0);
135 varname_len = strlen (varname);
136 value_len = strlen (value);
138 len = varname_len + value_len + 1 /* '=' */ ;
140 /* Use system malloc to avoid memleaks that dbus_malloc
141 * will get upset about.
144 putenv_value = malloc (len + 1);
145 if (putenv_value == NULL)
148 strcpy (putenv_value, varname);
149 strcpy (putenv_value + varname_len, "=");
150 strcpy (putenv_value + varname_len + 1, value);
152 return (putenv (putenv_value) == 0);
158 * Wrapper for getenv().
160 * @param varname name of environment variable
161 * @returns value of environment variable or #NULL if unset
164 _dbus_getenv (const char *varname)
166 return getenv (varname);
170 * Thin wrapper around the read() system call that appends
171 * the data it reads to the DBusString buffer. It appends
172 * up to the given count, and returns the same value
173 * and same errno as read(). The only exception is that
174 * _dbus_read() handles EINTR for you. _dbus_read() can
175 * return ENOMEM, even though regular UNIX read doesn't.
177 * @param fd the file descriptor to read from
178 * @param buffer the buffer to append data to
179 * @param count the amount of data to read
180 * @returns the number of bytes read or -1
191 _dbus_assert (count >= 0);
193 start = _dbus_string_get_length (buffer);
195 if (!_dbus_string_lengthen (buffer, count))
201 data = _dbus_string_get_data_len (buffer, start, count);
205 bytes_read = read (fd, data, count);
213 /* put length back (note that this doesn't actually realloc anything) */
214 _dbus_string_set_length (buffer, start);
220 /* put length back (doesn't actually realloc) */
221 _dbus_string_set_length (buffer, start + bytes_read);
225 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
233 * Thin wrapper around the write() system call that writes a part of a
234 * DBusString and handles EINTR for you.
236 * @param fd the file descriptor to write
237 * @param buffer the buffer to write data from
238 * @param start the first byte in the buffer to write
239 * @param len the number of bytes to try to write
240 * @returns the number of bytes written or -1 on error
244 const DBusString *buffer,
251 data = _dbus_string_get_const_data_len (buffer, start, len);
255 bytes_written = write (fd, data, len);
257 if (bytes_written < 0 && errno == EINTR)
261 if (bytes_written > 0)
262 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
265 return bytes_written;
269 * Like _dbus_write() but will use writev() if possible
270 * to write both buffers in sequence. The return value
271 * is the number of bytes written in the first buffer,
272 * plus the number written in the second. If the first
273 * buffer is written successfully and an error occurs
274 * writing the second, the number of bytes in the first
275 * is returned (i.e. the error is ignored), on systems that
276 * don't have writev. Handles EINTR for you.
277 * The second buffer may be #NULL.
279 * @param fd the file descriptor
280 * @param buffer1 first buffer
281 * @param start1 first byte to write in first buffer
282 * @param len1 number of bytes to write from first buffer
283 * @param buffer2 second buffer, or #NULL
284 * @param start2 first byte to write in second buffer
285 * @param len2 number of bytes to write in second buffer
286 * @returns total bytes written from both buffers, or -1 on error
289 _dbus_write_two (int fd,
290 const DBusString *buffer1,
293 const DBusString *buffer2,
297 _dbus_assert (buffer1 != NULL);
298 _dbus_assert (start1 >= 0);
299 _dbus_assert (start2 >= 0);
300 _dbus_assert (len1 >= 0);
301 _dbus_assert (len2 >= 0);
305 struct iovec vectors[2];
310 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
313 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
321 vectors[0].iov_base = (char*) data1;
322 vectors[0].iov_len = len1;
323 vectors[1].iov_base = (char*) data2;
324 vectors[1].iov_len = len2;
328 bytes_written = writev (fd,
332 if (bytes_written < 0 && errno == EINTR)
335 return bytes_written;
337 #else /* HAVE_WRITEV */
341 ret1 = _dbus_write (fd, buffer1, start1, len1);
342 if (ret1 == len1 && buffer2 != NULL)
344 ret2 = _dbus_write (fd, buffer2, start2, len2);
346 ret2 = 0; /* we can't report an error as the first write was OK */
353 #endif /* !HAVE_WRITEV */
356 #define _DBUS_MAX_SUN_PATH_LENGTH 99
359 * @def _DBUS_MAX_SUN_PATH_LENGTH
361 * Maximum length of the path to a UNIX domain socket,
362 * sockaddr_un::sun_path member. POSIX requires that all systems
363 * support at least 100 bytes here, including the nul termination.
364 * We use 99 for the max value to allow for the nul.
366 * We could probably also do sizeof (addr.sun_path)
367 * but this way we are the same on all platforms
368 * which is probably a good idea.
372 * Creates a socket and connects it to the UNIX domain socket at the
373 * given path. The connection fd is returned, and is set up as
376 * @param path the path to UNIX domain socket
377 * @param error return location for error code
378 * @returns connection file descriptor or -1 on error
381 _dbus_connect_unix_socket (const char *path,
385 struct sockaddr_un addr;
387 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
389 fd = socket (PF_UNIX, SOCK_STREAM, 0);
393 dbus_set_error (error,
394 _dbus_error_from_errno (errno),
395 "Failed to create socket: %s",
396 _dbus_strerror (errno));
402 addr.sun_family = AF_UNIX;
403 strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
405 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
407 dbus_set_error (error,
408 _dbus_error_from_errno (errno),
409 "Failed to connect to socket %s: %s",
410 path, _dbus_strerror (errno));
418 if (!_dbus_set_fd_nonblocking (fd, error))
420 _DBUS_ASSERT_ERROR_IS_SET (error);
432 * Creates a socket and binds it to the given path,
433 * then listens on the socket. The socket is
434 * set to be nonblocking.
436 * @todo we'd like to be able to use the abstract namespace on linux
437 * (see "man 7 unix"). The question is whether to silently move all
438 * paths into that namespace if we can (I think that's best) or to
439 * require it to be specified explicitly in the dbus address. Also,
440 * need to sort out how to check for abstract namespace support.
442 * @param path the socket name
443 * @param error return location for errors
444 * @returns the listening file descriptor or -1 on error
447 _dbus_listen_unix_socket (const char *path,
451 struct sockaddr_un addr;
453 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
455 listen_fd = socket (PF_UNIX, SOCK_STREAM, 0);
459 dbus_set_error (error, _dbus_error_from_errno (errno),
460 "Failed to create socket \"%s\": %s",
461 path, _dbus_strerror (errno));
465 /* FIXME discussed security implications of this with Nalin,
466 * and we couldn't think of where it would kick our ass, but
467 * it still seems a bit sucky. It also has non-security suckage;
468 * really we'd prefer to exit if the socket is already in use.
469 * But there doesn't seem to be a good way to do this.
471 * Just to be extra careful, I threw in the stat() - clearly
472 * the stat() can't *fix* any security issue, but it probably
473 * makes it harder to exploit.
478 if (stat (path, &sb) == 0 &&
479 S_ISSOCK (sb.st_mode))
484 addr.sun_family = AF_UNIX;
485 strncpy (addr.sun_path, path, _DBUS_MAX_SUN_PATH_LENGTH - 1);
487 if (bind (listen_fd, (struct sockaddr*) &addr, SUN_LEN (&addr)) < 0)
489 dbus_set_error (error, _dbus_error_from_errno (errno),
490 "Failed to bind socket \"%s\": %s",
491 path, _dbus_strerror (errno));
496 if (listen (listen_fd, 30 /* backlog */) < 0)
498 dbus_set_error (error, _dbus_error_from_errno (errno),
499 "Failed to listen on socket \"%s\": %s",
500 path, _dbus_strerror (errno));
505 if (!_dbus_set_fd_nonblocking (listen_fd, error))
507 _DBUS_ASSERT_ERROR_IS_SET (error);
512 /* Try opening up the permissions, but if we can't, just go ahead
513 * and continue, maybe it will be good enough.
515 if (chmod (path, 0777) < 0)
516 _dbus_warn ("Could not set mode 0777 on socket %s\n",
523 * Creates a socket and connects to a socket at the given host
524 * and port. The connection fd is returned, and is set up as
527 * @param host the host name to connect to
528 * @param port the prot to connect to
529 * @param error return location for error code
530 * @returns connection file descriptor or -1 on error
533 _dbus_connect_tcp_socket (const char *host,
538 struct sockaddr_in addr;
540 struct in_addr *haddr;
542 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
544 fd = socket (AF_INET, SOCK_STREAM, 0);
548 dbus_set_error (error,
549 _dbus_error_from_errno (errno),
550 "Failed to create socket: %s",
551 _dbus_strerror (errno));
559 he = gethostbyname (host);
562 dbus_set_error (error,
563 _dbus_error_from_errno (errno),
564 "Failed to lookup hostname: %s",
569 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
572 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
573 addr.sin_family = AF_INET;
574 addr.sin_port = htons (port);
576 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
578 dbus_set_error (error,
579 _dbus_error_from_errno (errno),
580 "Failed to connect to socket %s: %s:%d",
581 host, _dbus_strerror (errno), port);
589 if (!_dbus_set_fd_nonblocking (fd, error))
601 * Creates a socket and binds it to the given path,
602 * then listens on the socket. The socket is
603 * set to be nonblocking.
605 * @param host the host name to listen on
606 * @param port the prot to listen on
607 * @param error return location for errors
608 * @returns the listening file descriptor or -1 on error
611 _dbus_listen_tcp_socket (const char *host,
616 struct sockaddr_in addr;
618 struct in_addr *haddr;
620 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
622 listen_fd = socket (AF_INET, SOCK_STREAM, 0);
626 dbus_set_error (error, _dbus_error_from_errno (errno),
627 "Failed to create socket \"%s:%d\": %s",
628 host, port, _dbus_strerror (errno));
635 he = gethostbyname (host);
638 dbus_set_error (error,
639 _dbus_error_from_errno (errno),
640 "Failed to lookup hostname: %s",
645 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
648 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
649 addr.sin_family = AF_INET;
650 addr.sin_port = htons (port);
652 if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
654 dbus_set_error (error, _dbus_error_from_errno (errno),
655 "Failed to bind socket \"%s:%d\": %s",
656 host, port, _dbus_strerror (errno));
661 if (listen (listen_fd, 30 /* backlog */) < 0)
663 dbus_set_error (error, _dbus_error_from_errno (errno),
664 "Failed to listen on socket \"%s:%d\": %s",
665 host, port, _dbus_strerror (errno));
670 if (!_dbus_set_fd_nonblocking (listen_fd, error))
680 write_credentials_byte (int server_fd,
684 char buf[1] = { '\0' };
686 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
690 bytes_written = write (server_fd, buf, 1);
692 if (bytes_written < 0 && errno == EINTR)
695 if (bytes_written < 0)
697 dbus_set_error (error, _dbus_error_from_errno (errno),
698 "Failed to write credentials byte: %s",
699 _dbus_strerror (errno));
702 else if (bytes_written == 0)
704 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
705 "wrote zero bytes writing credentials byte");
710 _dbus_assert (bytes_written == 1);
711 _dbus_verbose ("wrote credentials byte\n");
717 * Reads a single byte which must be nul (an error occurs otherwise),
718 * and reads unix credentials if available. Fills in pid/uid/gid with
719 * -1 if no credentials are available. Return value indicates whether
720 * a byte was read, not whether we got valid credentials. On some
721 * systems, such as Linux, reading/writing the byte isn't actually
722 * required, but we do it anyway just to avoid multiple codepaths.
724 * Fails if no byte is available, so you must select() first.
726 * The point of the byte is that on some systems we have to
727 * use sendmsg()/recvmsg() to transmit credentials.
729 * @param client_fd the client file descriptor
730 * @param credentials struct to fill with credentials of client
731 * @param error location to store error code
732 * @returns #TRUE on success
735 _dbus_read_credentials_unix_socket (int client_fd,
736 DBusCredentials *credentials,
744 char cmsgmem[CMSG_SPACE (sizeof (struct cmsgcred))];
745 struct cmsghdr *cmsg = (struct cmsghdr *) cmsgmem;
748 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
750 /* The POSIX spec certainly doesn't promise this, but
751 * we need these assertions to fail as soon as we're wrong about
752 * it so we can do the porting fixups
754 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
755 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
756 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
758 credentials->pid = -1;
759 credentials->uid = -1;
760 credentials->gid = -1;
762 #if defined(LOCAL_CREDS) && defined(HAVE_CMSGCRED)
763 /* Set the socket to receive credentials on the next message */
766 if (setsockopt (client_fd, 0, LOCAL_CREDS, &on, sizeof (on)) < 0)
768 _dbus_verbose ("Unable to set LOCAL_CREDS socket option\n");
777 memset (&msg, 0, sizeof (msg));
782 memset (cmsgmem, 0, sizeof (cmsgmem));
783 msg.msg_control = cmsgmem;
784 msg.msg_controllen = sizeof (cmsgmem);
788 if (recvmsg (client_fd, &msg, 0) < 0)
793 dbus_set_error (error, _dbus_error_from_errno (errno),
794 "Failed to read credentials byte: %s",
795 _dbus_strerror (errno));
801 dbus_set_error (error, DBUS_ERROR_FAILED,
802 "Credentials byte was not nul");
807 if (cmsg->cmsg_len < sizeof (cmsgmem) || cmsg->cmsg_type != SCM_CREDS)
809 dbus_set_error (error, DBUS_ERROR_FAILED);
810 _dbus_verbose ("Message from recvmsg() was not SCM_CREDS\n");
815 _dbus_verbose ("read credentials byte\n");
820 int cr_len = sizeof (cr);
822 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
823 cr_len == sizeof (cr))
825 credentials->pid = cr.pid;
826 credentials->uid = cr.uid;
827 credentials->gid = cr.gid;
831 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
832 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
834 #elif defined(HAVE_CMSGCRED)
835 struct cmsgcred *cred;
837 cred = (struct cmsgcred *) CMSG_DATA (cmsg);
839 credentials->pid = cred->cmcred_pid;
840 credentials->uid = cred->cmcred_euid;
841 credentials->gid = cred->cmcred_groups[0];
842 #else /* !SO_PEERCRED && !HAVE_CMSGCRED */
843 _dbus_verbose ("Socket credentials not supported on this OS\n");
847 _dbus_verbose ("Credentials: pid %d uid %d gid %d\n",
856 * Sends a single nul byte with our UNIX credentials as ancillary
857 * data. Returns #TRUE if the data was successfully written. On
858 * systems that don't support sending credentials, just writes a byte,
859 * doesn't send any credentials. On some systems, such as Linux,
860 * reading/writing the byte isn't actually required, but we do it
861 * anyway just to avoid multiple codepaths.
863 * Fails if no byte can be written, so you must select() first.
865 * The point of the byte is that on some systems we have to
866 * use sendmsg()/recvmsg() to transmit credentials.
868 * @param server_fd file descriptor for connection to server
869 * @param error return location for error code
870 * @returns #TRUE if the byte was sent
873 _dbus_send_credentials_unix_socket (int server_fd,
876 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
878 if (write_credentials_byte (server_fd, error))
885 * Accepts a connection on a listening socket.
886 * Handles EINTR for you.
888 * @param listen_fd the listen file descriptor
889 * @returns the connection fd of the client, or -1 on error
892 _dbus_accept (int listen_fd)
895 struct sockaddr addr;
898 addrlen = sizeof (addr);
901 client_fd = accept (listen_fd, &addr, &addrlen);
915 * @addtogroup DBusString
920 * Appends an integer to a DBusString.
922 * @param str the string
923 * @param value the integer value
924 * @returns #FALSE if not enough memory or other failure.
927 _dbus_string_append_int (DBusString *str,
930 /* this calculation is from comp.lang.c faq */
931 #define MAX_LONG_LEN ((sizeof (long) * 8 + 2) / 3 + 1) /* +1 for '-' */
936 orig_len = _dbus_string_get_length (str);
938 if (!_dbus_string_lengthen (str, MAX_LONG_LEN))
941 buf = _dbus_string_get_data_len (str, orig_len, MAX_LONG_LEN);
943 snprintf (buf, MAX_LONG_LEN, "%ld", value);
952 _dbus_string_shorten (str, MAX_LONG_LEN - i);
958 * Appends an unsigned integer to a DBusString.
960 * @param str the string
961 * @param value the integer value
962 * @returns #FALSE if not enough memory or other failure.
965 _dbus_string_append_uint (DBusString *str,
968 /* this is wrong, but definitely on the high side. */
969 #define MAX_ULONG_LEN (MAX_LONG_LEN * 2)
974 orig_len = _dbus_string_get_length (str);
976 if (!_dbus_string_lengthen (str, MAX_ULONG_LEN))
979 buf = _dbus_string_get_data_len (str, orig_len, MAX_ULONG_LEN);
981 snprintf (buf, MAX_ULONG_LEN, "%lu", value);
990 _dbus_string_shorten (str, MAX_ULONG_LEN - i);
996 * Appends a double to a DBusString.
998 * @param str the string
999 * @param value the floating point value
1000 * @returns #FALSE if not enough memory or other failure.
1003 _dbus_string_append_double (DBusString *str,
1006 #define MAX_DOUBLE_LEN 64 /* this is completely made up :-/ */
1011 orig_len = _dbus_string_get_length (str);
1013 if (!_dbus_string_lengthen (str, MAX_DOUBLE_LEN))
1016 buf = _dbus_string_get_data_len (str, orig_len, MAX_DOUBLE_LEN);
1018 snprintf (buf, MAX_LONG_LEN, "%g", value);
1027 _dbus_string_shorten (str, MAX_DOUBLE_LEN - i);
1033 * Parses an integer contained in a DBusString. Either return parameter
1034 * may be #NULL if you aren't interested in it. The integer is parsed
1035 * and stored in value_return. Return parameters are not initialized
1036 * if the function returns #FALSE.
1038 * @param str the string
1039 * @param start the byte index of the start of the integer
1040 * @param value_return return location of the integer value or #NULL
1041 * @param end_return return location of the end of the integer, or #NULL
1042 * @returns #TRUE on success
1045 _dbus_string_parse_int (const DBusString *str,
1054 p = _dbus_string_get_const_data_len (str, start,
1055 _dbus_string_get_length (str) - start);
1059 v = strtol (p, &end, 0);
1060 if (end == NULL || end == p || errno != 0)
1066 *end_return = start + (end - p);
1072 * Parses an unsigned integer contained in a DBusString. Either return
1073 * parameter may be #NULL if you aren't interested in it. The integer
1074 * is parsed and stored in value_return. Return parameters are not
1075 * initialized if the function returns #FALSE.
1077 * @param str the string
1078 * @param start the byte index of the start of the integer
1079 * @param value_return return location of the integer value or #NULL
1080 * @param end_return return location of the end of the integer, or #NULL
1081 * @returns #TRUE on success
1084 _dbus_string_parse_uint (const DBusString *str,
1086 unsigned long *value_return,
1093 p = _dbus_string_get_const_data_len (str, start,
1094 _dbus_string_get_length (str) - start);
1098 v = strtoul (p, &end, 0);
1099 if (end == NULL || end == p || errno != 0)
1105 *end_return = start + (end - p);
1111 * Parses a floating point number contained in a DBusString. Either
1112 * return parameter may be #NULL if you aren't interested in it. The
1113 * integer is parsed and stored in value_return. Return parameters are
1114 * not initialized if the function returns #FALSE.
1116 * @todo this function is currently locale-dependent. Should
1117 * ask alexl to relicense g_ascii_strtod() code and put that in
1118 * here instead, so it's locale-independent.
1120 * @param str the string
1121 * @param start the byte index of the start of the float
1122 * @param value_return return location of the float value or #NULL
1123 * @param end_return return location of the end of the float, or #NULL
1124 * @returns #TRUE on success
1127 _dbus_string_parse_double (const DBusString *str,
1129 double *value_return,
1136 _dbus_warn ("_dbus_string_parse_double() needs to be made locale-independent\n");
1138 p = _dbus_string_get_const_data_len (str, start,
1139 _dbus_string_get_length (str) - start);
1143 v = strtod (p, &end);
1144 if (end == NULL || end == p || errno != 0)
1150 *end_return = start + (end - p);
1155 /** @} */ /* DBusString group */
1158 * @addtogroup DBusInternalsUtils
1163 store_user_info (struct passwd *p,
1164 DBusCredentials *credentials,
1165 DBusString *homedir,
1166 DBusString *username_out)
1168 int old_homedir_len;
1170 if (credentials != NULL)
1172 credentials->uid = p->pw_uid;
1173 credentials->gid = p->pw_gid;
1176 old_homedir_len = 0;
1177 if (homedir != NULL)
1179 old_homedir_len = _dbus_string_get_length (homedir);
1181 if (!_dbus_string_append (homedir, p->pw_dir))
1183 _dbus_verbose ("No memory to get homedir\n");
1189 !_dbus_string_append (username_out, p->pw_name))
1192 _dbus_string_set_length (homedir, old_homedir_len);
1193 _dbus_verbose ("No memory to get username\n");
1197 _dbus_verbose ("Username %s has uid %d gid %d homedir %s\n",
1198 p->pw_name, (int) p->pw_uid, (int) p->pw_gid,
1205 * Gets user info using either username or uid. Only
1206 * one of these may be passed in, either username
1207 * must be #NULL or uid must be < 0.
1209 * @param username the username
1210 * @param uid the user ID
1211 * @param credentials to fill in or #NULL
1212 * @param homedir string to append homedir to or #NULL
1213 * @param username_out string to append username to or #NULL
1215 * @returns #TRUE on success
1218 get_user_info (const DBusString *username,
1220 DBusCredentials *credentials,
1221 DBusString *homedir,
1222 DBusString *username_out)
1224 const char *username_c_str;
1226 /* exactly one of username/uid provided */
1227 _dbus_assert (username != NULL || uid >= 0);
1228 _dbus_assert (username == NULL || uid < 0);
1232 credentials->pid = -1;
1233 credentials->uid = -1;
1234 credentials->gid = -1;
1237 if (username != NULL)
1238 username_c_str = _dbus_string_get_const_data (username);
1240 username_c_str = NULL;
1242 /* For now assuming that the getpwnam() and getpwuid() flavors
1243 * are always symmetrical, if not we have to add more configure
1247 #if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)
1252 struct passwd p_str;
1255 #ifdef HAVE_POSIX_GETPWNAME_R
1257 result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
1260 result = getpwnam_r (username_c_str, &p_str, buf, sizeof (buf),
1264 p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
1266 p = getpwnam_r (username_c_str, &p_str, buf, sizeof (buf));
1268 #endif /* !HAVE_POSIX_GETPWNAME_R */
1269 if (result == 0 && p == &p_str)
1271 return store_user_info (p, credentials, homedir,
1276 _dbus_verbose ("User %s unknown\n", username_c_str);
1280 #else /* ! HAVE_GETPWNAM_R */
1282 /* I guess we're screwed on thread safety here */
1288 p = getpwnam (username_c_str);
1292 return store_user_info (p, credentials, homedir,
1297 _dbus_verbose ("User %s unknown\n", username_c_str);
1301 #endif /* ! HAVE_GETPWNAM_R */
1305 * Gets the credentials corresponding to the given username.
1307 * @param username the username
1308 * @param credentials credentials to fill in
1309 * @returns #TRUE if the username existed and we got some credentials
1312 _dbus_credentials_from_username (const DBusString *username,
1313 DBusCredentials *credentials)
1315 return get_user_info (username, -1, credentials, NULL, NULL);
1319 * Gets the credentials corresponding to the given user ID.
1321 * @param user_id the user ID
1322 * @param credentials credentials to fill in
1323 * @returns #TRUE if the username existed and we got some credentials
1326 _dbus_credentials_from_user_id (unsigned long user_id,
1327 DBusCredentials *credentials)
1329 return get_user_info (NULL, user_id, credentials, NULL, NULL);
1332 _DBUS_DEFINE_GLOBAL_LOCK (user_info);
1338 DBusCredentials creds;
1342 shutdown_user_info (void *data)
1346 _dbus_string_free (&u->name);
1347 _dbus_string_free (&u->dir);
1351 * Gets information about the user running this process.
1353 * @param username return location for username or #NULL
1354 * @param homedir return location for home directory or #NULL
1355 * @param credentials return location for credentials or #NULL
1356 * @returns #TRUE on success
1359 _dbus_user_info_from_current_process (const DBusString **username,
1360 const DBusString **homedir,
1361 const DBusCredentials **credentials)
1364 static int initialized_generation = 0;
1366 if (!_DBUS_LOCK (user_info))
1369 if (initialized_generation != _dbus_current_generation)
1371 if (!_dbus_string_init (&u.name))
1373 _DBUS_UNLOCK (user_info);
1377 if (!_dbus_string_init (&u.dir))
1379 _dbus_string_free (&u.name);
1380 _DBUS_UNLOCK (user_info);
1388 if (!get_user_info (NULL, getuid (),
1389 &u.creds, &u.dir, &u.name))
1392 if (!_dbus_register_shutdown_func (shutdown_user_info,
1396 initialized_generation = _dbus_current_generation;
1398 if (initialized_generation != _dbus_current_generation)
1400 _dbus_string_free (&u.name);
1401 _dbus_string_free (&u.dir);
1402 _DBUS_UNLOCK (user_info);
1408 *username = &u.name;
1412 *credentials = &u.creds;
1414 _DBUS_UNLOCK (user_info);
1420 * Gets the home directory for the given user.
1422 * @param username the username
1423 * @param homedir string to append home directory to
1424 * @returns #TRUE if user existed and we appended their homedir
1427 _dbus_homedir_from_username (const DBusString *username,
1428 DBusString *homedir)
1430 return get_user_info (username, -1, NULL, homedir, NULL);
1434 * Gets credentials from a UID string. (Parses a string to a UID
1435 * and converts to a DBusCredentials.)
1437 * @param uid_str the UID in string form
1438 * @param credentials credentials to fill in
1439 * @returns #TRUE if successfully filled in some credentials
1442 _dbus_credentials_from_uid_string (const DBusString *uid_str,
1443 DBusCredentials *credentials)
1448 credentials->pid = -1;
1449 credentials->uid = -1;
1450 credentials->gid = -1;
1452 if (_dbus_string_get_length (uid_str) == 0)
1454 _dbus_verbose ("UID string was zero length\n");
1460 if (!_dbus_string_parse_int (uid_str, 0, &uid,
1463 _dbus_verbose ("could not parse string as a UID\n");
1467 if (end != _dbus_string_get_length (uid_str))
1469 _dbus_verbose ("string contained trailing stuff after UID\n");
1473 credentials->uid = uid;
1479 * Gets the credentials of the current process.
1481 * @param credentials credentials to fill in.
1484 _dbus_credentials_from_current_process (DBusCredentials *credentials)
1486 /* The POSIX spec certainly doesn't promise this, but
1487 * we need these assertions to fail as soon as we're wrong about
1488 * it so we can do the porting fixups
1490 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
1491 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
1492 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
1494 credentials->pid = getpid ();
1495 credentials->uid = getuid ();
1496 credentials->gid = getgid ();
1500 * Checks whether the provided_credentials are allowed to log in
1501 * as the expected_credentials.
1503 * @param expected_credentials credentials we're trying to log in as
1504 * @param provided_credentials credentials we have
1505 * @returns #TRUE if we can log in
1508 _dbus_credentials_match (const DBusCredentials *expected_credentials,
1509 const DBusCredentials *provided_credentials)
1511 if (provided_credentials->uid < 0)
1513 else if (expected_credentials->uid < 0)
1515 else if (provided_credentials->uid == 0)
1517 else if (provided_credentials->uid == expected_credentials->uid)
1524 * Gets group ID from group name.
1526 * @param group_name name of the group
1527 * @param gid location to store group ID
1528 * @returns #TRUE if group was known
1531 _dbus_get_group_id (const DBusString *group_name,
1534 const char *group_c_str;
1536 group_c_str = _dbus_string_get_const_data (group_name);
1538 /* For now assuming that the getgrnam() and getgrgid() flavors
1539 * always correspond to the pwnam flavors, if not we have
1540 * to add more configure checks.
1543 #if defined (HAVE_POSIX_GETPWNAME_R) || defined (HAVE_NONPOSIX_GETPWNAME_R)
1551 #ifdef HAVE_POSIX_GETPWNAME_R
1553 result = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf),
1556 p = getgrnam_r (group_c_str, &g_str, buf, sizeof (buf));
1558 #endif /* !HAVE_POSIX_GETPWNAME_R */
1559 if (result == 0 && g == &g_str)
1566 _dbus_verbose ("Group %s unknown\n", group_c_str);
1570 #else /* ! HAVE_GETPWNAM_R */
1572 /* I guess we're screwed on thread safety here */
1575 g = getgrnam (group_c_str);
1584 _dbus_verbose ("Group %s unknown\n", group_c_str);
1588 #endif /* ! HAVE_GETPWNAM_R */
1592 * Gets all groups for a particular user. Returns #FALSE
1593 * if no memory, or user isn't known, but always initializes
1594 * group_ids to a NULL array.
1596 * @todo failing to distinguish "out of memory" from
1597 * "unknown user" is kind of bogus and would probably
1598 * result in a failure in a comprehensive test suite.
1600 * @param uid the user ID
1601 * @param group_ids return location for array of group IDs
1602 * @param n_group_ids return location for length of returned array
1603 * @returns #TRUE on success
1606 _dbus_get_groups (unsigned long uid,
1607 unsigned long **group_ids,
1610 DBusCredentials creds;
1611 DBusString username;
1612 const char *username_c;
1620 if (!_dbus_string_init (&username))
1623 if (!get_user_info (NULL, uid, &creds,
1628 username_c = _dbus_string_get_const_data (&username);
1630 #ifdef HAVE_GETGROUPLIST
1637 buf = dbus_new (gid_t, buf_count);
1641 if (getgrouplist (username_c,
1643 buf, &buf_count) < 0)
1645 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1654 getgrouplist (username_c, creds.gid, buf, &buf_count);
1657 *group_ids = dbus_new (unsigned long, buf_count);
1658 if (*group_ids == NULL)
1664 for (i = 0; i < buf_count; ++i)
1665 (*group_ids)[i] = buf[i];
1667 *n_group_ids = buf_count;
1671 #else /* HAVE_GETGROUPLIST */
1673 /* We just get the one group ID */
1674 *group_ids = dbus_new (unsigned long, 1);
1675 if (*group_ids == NULL)
1680 (*group_ids)[0] = creds.gid;
1682 #endif /* HAVE_GETGROUPLIST */
1687 _dbus_string_free (&username);
1692 * Appends the uid of the current process to the given string.
1694 * @param str the string to append to
1695 * @returns #TRUE on success
1698 _dbus_string_append_our_uid (DBusString *str)
1700 return _dbus_string_append_int (str, getuid ());
1704 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
1707 * Atomically increments an integer
1709 * @param atomic pointer to the integer to increment
1710 * @returns the value after incrementing
1712 * @todo implement arch-specific faster atomic ops
1715 _dbus_atomic_inc (dbus_atomic_t *atomic)
1719 _DBUS_LOCK (atomic);
1722 _DBUS_UNLOCK (atomic);
1727 * Atomically decrement an integer
1729 * @param atomic pointer to the integer to decrement
1730 * @returns the value after decrementing
1732 * @todo implement arch-specific faster atomic ops
1735 _dbus_atomic_dec (dbus_atomic_t *atomic)
1739 _DBUS_LOCK (atomic);
1742 _DBUS_UNLOCK (atomic);
1747 * Wrapper for poll().
1749 * @todo need a fallback implementation using select()
1751 * @param fds the file descriptors to poll
1752 * @param n_fds number of descriptors in the array
1753 * @param timeout_milliseconds timeout or -1 for infinite
1754 * @returns numbers of fds with revents, or <0 on error
1757 _dbus_poll (DBusPollFD *fds,
1759 int timeout_milliseconds)
1762 /* This big thing is a constant expression and should get optimized
1763 * out of existence. So it's more robust than a configure check at
1766 if (_DBUS_POLLIN == POLLIN &&
1767 _DBUS_POLLPRI == POLLPRI &&
1768 _DBUS_POLLOUT == POLLOUT &&
1769 _DBUS_POLLERR == POLLERR &&
1770 _DBUS_POLLHUP == POLLHUP &&
1771 _DBUS_POLLNVAL == POLLNVAL &&
1772 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
1773 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
1774 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
1775 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
1776 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
1777 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
1778 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
1780 return poll ((struct pollfd*) fds,
1782 timeout_milliseconds);
1786 /* We have to convert the DBusPollFD to an array of
1787 * struct pollfd, poll, and convert back.
1789 _dbus_warn ("didn't implement poll() properly for this system yet\n");
1792 #else /* ! HAVE_POLL */
1794 fd_set read_set, write_set, err_set;
1800 FD_ZERO (&read_set);
1801 FD_ZERO (&write_set);
1804 for (i = 0; i < n_fds; i++)
1806 DBusPollFD f = fds[i];
1808 if (f.events & _DBUS_POLLIN)
1809 FD_SET (f.fd, &read_set);
1811 if (f.events & _DBUS_POLLOUT)
1812 FD_SET (f.fd, &write_set);
1814 FD_SET (f.fd, &err_set);
1816 max_fd = MAX (max_fd, f.fd);
1819 tv.tv_sec = timeout_milliseconds / 1000;
1820 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
1822 ready = select (max_fd + 1, &read_set, &write_set, &err_set, &tv);
1826 for (i = 0; i < n_fds; i++)
1828 DBusPollFD f = fds[i];
1832 if (FD_ISSET (f.fd, &read_set))
1833 f.revents |= _DBUS_POLLIN;
1835 if (FD_ISSET (f.fd, &write_set))
1836 f.revents |= _DBUS_POLLOUT;
1838 if (FD_ISSET (f.fd, &err_set))
1839 f.revents |= _DBUS_POLLERR;
1847 /** nanoseconds in a second */
1848 #define NANOSECONDS_PER_SECOND 1000000000
1849 /** microseconds in a second */
1850 #define MICROSECONDS_PER_SECOND 1000000
1851 /** milliseconds in a second */
1852 #define MILLISECONDS_PER_SECOND 1000
1853 /** nanoseconds in a millisecond */
1854 #define NANOSECONDS_PER_MILLISECOND 1000000
1855 /** microseconds in a millisecond */
1856 #define MICROSECONDS_PER_MILLISECOND 1000
1859 * Sleeps the given number of milliseconds.
1860 * @param milliseconds number of milliseconds
1863 _dbus_sleep_milliseconds (int milliseconds)
1865 #ifdef HAVE_NANOSLEEP
1866 struct timespec req;
1867 struct timespec rem;
1869 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
1870 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
1874 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
1876 #elif defined (HAVE_USLEEP)
1877 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
1878 #else /* ! HAVE_USLEEP */
1879 sleep (MAX (milliseconds / 1000, 1));
1884 * Get current time, as in gettimeofday().
1886 * @param tv_sec return location for number of seconds
1887 * @param tv_usec return location for number of microseconds (thousandths)
1890 _dbus_get_current_time (long *tv_sec,
1895 gettimeofday (&t, NULL);
1900 *tv_usec = t.tv_usec;
1904 * Appends the contents of the given file to the string,
1905 * returning error code. At the moment, won't open a file
1906 * more than a megabyte in size.
1908 * @param str the string to append to
1909 * @param filename filename to load
1910 * @param error place to set an error
1911 * @returns #FALSE if error was set
1914 _dbus_file_get_contents (DBusString *str,
1915 const DBusString *filename,
1922 const char *filename_c;
1924 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1926 filename_c = _dbus_string_get_const_data (filename);
1928 /* O_BINARY useful on Cygwin */
1929 fd = open (filename_c, O_RDONLY | O_BINARY);
1932 dbus_set_error (error, _dbus_error_from_errno (errno),
1933 "Failed to open \"%s\": %s",
1935 _dbus_strerror (errno));
1939 if (fstat (fd, &sb) < 0)
1941 dbus_set_error (error, _dbus_error_from_errno (errno),
1942 "Failed to stat \"%s\": %s",
1944 _dbus_strerror (errno));
1946 _dbus_verbose ("fstat() failed: %s",
1947 _dbus_strerror (errno));
1954 if (sb.st_size > _DBUS_ONE_MEGABYTE)
1956 dbus_set_error (error, DBUS_ERROR_FAILED,
1957 "File size %lu of \"%s\" is too large.",
1958 filename_c, (unsigned long) sb.st_size);
1964 orig_len = _dbus_string_get_length (str);
1965 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
1969 while (total < (int) sb.st_size)
1971 bytes_read = _dbus_read (fd, str,
1972 sb.st_size - total);
1973 if (bytes_read <= 0)
1975 dbus_set_error (error, _dbus_error_from_errno (errno),
1976 "Error reading \"%s\": %s",
1978 _dbus_strerror (errno));
1980 _dbus_verbose ("read() failed: %s",
1981 _dbus_strerror (errno));
1984 _dbus_string_set_length (str, orig_len);
1988 total += bytes_read;
1994 else if (sb.st_size != 0)
1996 _dbus_verbose ("Can only open regular files at the moment.\n");
1997 dbus_set_error (error, DBUS_ERROR_FAILED,
1998 "\"%s\" is not a regular file",
2011 * Writes a string out to a file. If the file exists,
2012 * it will be atomically overwritten by the new data.
2014 * @param str the string to write out
2015 * @param filename the file to save string to
2016 * @param error error to be filled in on failure
2017 * @returns #FALSE on failure
2020 _dbus_string_save_to_file (const DBusString *str,
2021 const DBusString *filename,
2026 const char *filename_c;
2027 DBusString tmp_filename;
2028 const char *tmp_filename_c;
2030 dbus_bool_t need_unlink;
2033 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2037 need_unlink = FALSE;
2039 if (!_dbus_string_init (&tmp_filename))
2041 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2045 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2047 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2051 if (!_dbus_string_append (&tmp_filename, "."))
2053 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2057 #define N_TMP_FILENAME_RANDOM_BYTES 8
2058 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
2060 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2064 filename_c = _dbus_string_get_const_data (filename);
2065 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2067 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2071 dbus_set_error (error, _dbus_error_from_errno (errno),
2072 "Could not create %s: %s", tmp_filename_c,
2073 _dbus_strerror (errno));
2080 bytes_to_write = _dbus_string_get_length (str);
2082 while (total < bytes_to_write)
2086 bytes_written = _dbus_write (fd, str, total,
2087 bytes_to_write - total);
2089 if (bytes_written <= 0)
2091 dbus_set_error (error, _dbus_error_from_errno (errno),
2092 "Could not write to %s: %s", tmp_filename_c,
2093 _dbus_strerror (errno));
2098 total += bytes_written;
2103 dbus_set_error (error, _dbus_error_from_errno (errno),
2104 "Could not close file %s: %s",
2105 tmp_filename_c, _dbus_strerror (errno));
2112 if (rename (tmp_filename_c, filename_c) < 0)
2114 dbus_set_error (error, _dbus_error_from_errno (errno),
2115 "Could not rename %s to %s: %s",
2116 tmp_filename_c, filename_c,
2117 _dbus_strerror (errno));
2122 need_unlink = FALSE;
2127 /* close first, then unlink, to prevent ".nfs34234235" garbage
2134 if (need_unlink && unlink (tmp_filename_c) < 0)
2135 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2136 tmp_filename_c, _dbus_strerror (errno));
2138 _dbus_string_free (&tmp_filename);
2141 _DBUS_ASSERT_ERROR_IS_SET (error);
2146 /** Creates the given file, failing if the file already exists.
2148 * @param filename the filename
2149 * @param error error location
2150 * @returns #TRUE if we created the file and it didn't exist
2153 _dbus_create_file_exclusively (const DBusString *filename,
2157 const char *filename_c;
2159 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2161 filename_c = _dbus_string_get_const_data (filename);
2163 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2167 dbus_set_error (error,
2169 "Could not create file %s: %s\n",
2171 _dbus_strerror (errno));
2177 dbus_set_error (error,
2179 "Could not close file %s: %s\n",
2181 _dbus_strerror (errno));
2189 * Deletes the given file.
2191 * @param filename the filename
2192 * @param error error location
2194 * @returns #TRUE if unlink() succeeded
2197 _dbus_delete_file (const DBusString *filename,
2200 const char *filename_c;
2202 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2204 filename_c = _dbus_string_get_const_data (filename);
2206 if (unlink (filename_c) < 0)
2208 dbus_set_error (error, DBUS_ERROR_FAILED,
2209 "Failed to delete file %s: %s\n",
2210 filename_c, _dbus_strerror (errno));
2218 * Creates a directory; succeeds if the directory
2219 * is created or already existed.
2221 * @param filename directory filename
2222 * @param error initialized error object
2223 * @returns #TRUE on success
2226 _dbus_create_directory (const DBusString *filename,
2229 const char *filename_c;
2231 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2233 filename_c = _dbus_string_get_const_data (filename);
2235 if (mkdir (filename_c, 0700) < 0)
2237 if (errno == EEXIST)
2240 dbus_set_error (error, DBUS_ERROR_FAILED,
2241 "Failed to create directory %s: %s\n",
2242 filename_c, _dbus_strerror (errno));
2250 * Appends the given filename to the given directory.
2252 * @todo it might be cute to collapse multiple '/' such as "foo//"
2255 * @param dir the directory name
2256 * @param next_component the filename
2257 * @returns #TRUE on success
2260 _dbus_concat_dir_and_file (DBusString *dir,
2261 const DBusString *next_component)
2263 dbus_bool_t dir_ends_in_slash;
2264 dbus_bool_t file_starts_with_slash;
2266 if (_dbus_string_get_length (dir) == 0 ||
2267 _dbus_string_get_length (next_component) == 0)
2270 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2271 _dbus_string_get_length (dir) - 1);
2273 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2275 if (dir_ends_in_slash && file_starts_with_slash)
2277 _dbus_string_shorten (dir, 1);
2279 else if (!(dir_ends_in_slash || file_starts_with_slash))
2281 if (!_dbus_string_append_byte (dir, '/'))
2285 return _dbus_string_copy (next_component, 0, dir,
2286 _dbus_string_get_length (dir));
2290 * Get the directory name from a complete filename
2291 * @param filename the filename
2292 * @param dirname string to append directory name to
2293 * @returns #FALSE if no memory
2296 _dbus_string_get_dirname (const DBusString *filename,
2297 DBusString *dirname)
2301 _dbus_assert (filename != dirname);
2302 _dbus_assert (filename != NULL);
2303 _dbus_assert (dirname != NULL);
2305 /* Ignore any separators on the end */
2306 sep = _dbus_string_get_length (filename);
2308 return _dbus_string_append (dirname, "."); /* empty string passed in */
2310 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
2313 _dbus_assert (sep >= 0);
2316 return _dbus_string_append (dirname, "/");
2318 /* Now find the previous separator */
2319 _dbus_string_find_byte_backward (filename, sep, '/', &sep);
2321 return _dbus_string_append (dirname, ".");
2323 /* skip multiple separators */
2324 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
2327 _dbus_assert (sep >= 0);
2330 _dbus_string_get_byte (filename, 0) == '/')
2331 return _dbus_string_append (dirname, "/");
2333 return _dbus_string_copy_len (filename, 0, sep - 0,
2334 dirname, _dbus_string_get_length (dirname));
2338 * Checks whether the filename is an absolute path
2340 * @param filename the filename
2341 * @returns #TRUE if an absolute path
2344 _dbus_path_is_absolute (const DBusString *filename)
2346 if (_dbus_string_get_length (filename) > 0)
2347 return _dbus_string_get_byte (filename, 0) == '/';
2359 * Open a directory to iterate over.
2361 * @param filename the directory name
2362 * @param error exception return object or #NULL
2363 * @returns new iterator, or #NULL on error
2366 _dbus_directory_open (const DBusString *filename,
2371 const char *filename_c;
2373 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2375 filename_c = _dbus_string_get_const_data (filename);
2377 d = opendir (filename_c);
2380 dbus_set_error (error, _dbus_error_from_errno (errno),
2381 "Failed to read directory \"%s\": %s",
2383 _dbus_strerror (errno));
2386 iter = dbus_new0 (DBusDirIter, 1);
2390 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
2391 "Could not allocate memory for directory iterator");
2401 * Get next file in the directory. Will not return "." or ".." on
2402 * UNIX. If an error occurs, the contents of "filename" are
2403 * undefined. The error is never set if the function succeeds.
2405 * @todo for thread safety, I think we have to use
2406 * readdir_r(). (GLib has the same issue, should file a bug.)
2408 * @param iter the iterator
2409 * @param filename string to be set to the next file in the dir
2410 * @param error return location for error
2411 * @returns #TRUE if filename was filled in with a new filename
2414 _dbus_directory_get_next_file (DBusDirIter *iter,
2415 DBusString *filename,
2420 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2424 ent = readdir (iter->d);
2428 dbus_set_error (error,
2429 _dbus_error_from_errno (errno),
2430 "%s", _dbus_strerror (errno));
2433 else if (ent->d_name[0] == '.' &&
2434 (ent->d_name[1] == '\0' ||
2435 (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
2439 _dbus_string_set_length (filename, 0);
2440 if (!_dbus_string_append (filename, ent->d_name))
2442 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
2443 "No memory to read directory entry");
2452 * Closes a directory iteration.
2455 _dbus_directory_close (DBusDirIter *iter)
2462 pseudorandom_generate_random_bytes (DBusString *str,
2466 unsigned long tv_usec;
2469 old_len = _dbus_string_get_length (str);
2471 /* fall back to pseudorandom */
2472 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
2475 _dbus_get_current_time (NULL, &tv_usec);
2485 b = (r / (double) RAND_MAX) * 255.0;
2487 if (!_dbus_string_append_byte (str, b))
2496 _dbus_string_set_length (str, old_len);
2501 * Generates the given number of random bytes,
2502 * using the best mechanism we can come up with.
2504 * @param str the string
2505 * @param n_bytes the number of random bytes to append to string
2506 * @returns #TRUE on success, #FALSE if no memory
2509 _dbus_generate_random_bytes (DBusString *str,
2515 /* FALSE return means "no memory", if it could
2516 * mean something else then we'd need to return
2517 * a DBusError. So we always fall back to pseudorandom
2521 old_len = _dbus_string_get_length (str);
2524 /* note, urandom on linux will fall back to pseudorandom */
2525 fd = open ("/dev/urandom", O_RDONLY);
2527 return pseudorandom_generate_random_bytes (str, n_bytes);
2529 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2532 _dbus_string_set_length (str, old_len);
2533 return pseudorandom_generate_random_bytes (str, n_bytes);
2536 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2545 * Generates the given number of random bytes, where the bytes are
2546 * chosen from the alphanumeric ASCII subset.
2548 * @param str the string
2549 * @param n_bytes the number of random ASCII bytes to append to string
2550 * @returns #TRUE on success, #FALSE if no memory or other failure
2553 _dbus_generate_random_ascii (DBusString *str,
2556 static const char letters[] =
2557 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
2561 if (!_dbus_generate_random_bytes (str, n_bytes))
2564 len = _dbus_string_get_length (str);
2568 _dbus_string_set_byte (str, i,
2569 letters[_dbus_string_get_byte (str, i) %
2570 (sizeof (letters) - 1)]);
2575 _dbus_assert (_dbus_string_validate_ascii (str, len - n_bytes,
2582 * A wrapper around strerror() because some platforms
2583 * may be lame and not have strerror().
2585 * @param error_number errno.
2586 * @returns error description.
2589 _dbus_strerror (int error_number)
2593 msg = strerror (error_number);
2601 * signal (SIGPIPE, SIG_IGN);
2604 _dbus_disable_sigpipe (void)
2606 signal (SIGPIPE, SIG_IGN);
2610 * Sets the file descriptor to be close
2611 * on exec. Should be called for all file
2612 * descriptors in D-BUS code.
2614 * @param fd the file descriptor
2617 _dbus_fd_set_close_on_exec (int fd)
2621 val = fcntl (fd, F_GETFD, 0);
2628 fcntl (fd, F_SETFD, val);
2632 * Converts a UNIX errno into a #DBusError name.
2634 * @todo should cover more errnos, specifically those
2637 * @param error_number the errno.
2638 * @returns an error name
2641 _dbus_error_from_errno (int error_number)
2643 switch (error_number)
2646 return DBUS_ERROR_FAILED;
2648 #ifdef EPROTONOSUPPORT
2649 case EPROTONOSUPPORT:
2650 return DBUS_ERROR_NOT_SUPPORTED;
2654 return DBUS_ERROR_NOT_SUPPORTED;
2658 return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
2662 return DBUS_ERROR_LIMITS_EXCEEDED;
2666 return DBUS_ERROR_ACCESS_DENIED;
2670 return DBUS_ERROR_ACCESS_DENIED;
2674 return DBUS_ERROR_NO_MEMORY;
2678 return DBUS_ERROR_NO_MEMORY;
2682 return DBUS_ERROR_FAILED;
2686 return DBUS_ERROR_FAILED;
2690 return DBUS_ERROR_FAILED;
2694 return DBUS_ERROR_FAILED;
2698 return DBUS_ERROR_FAILED;
2702 return DBUS_ERROR_NO_SERVER;
2706 return DBUS_ERROR_TIMEOUT;
2710 return DBUS_ERROR_NO_NETWORK;
2714 return DBUS_ERROR_ADDRESS_IN_USE;
2718 return DBUS_ERROR_FILE_NOT_FOUND;
2722 return DBUS_ERROR_FILE_NOT_FOUND;
2726 return DBUS_ERROR_FAILED;
2730 * Exit the process, returning the given value.
2732 * @param code the exit code
2735 _dbus_exit (int code)
2743 * @param filename the filename to stat
2744 * @param statbuf the stat info to fill in
2745 * @param error return location for error
2746 * @returns #FALSE if error was set
2749 _dbus_stat (const DBusString *filename,
2753 const char *filename_c;
2756 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2758 filename_c = _dbus_string_get_const_data (filename);
2760 if (stat (filename_c, &sb) < 0)
2762 dbus_set_error (error, _dbus_error_from_errno (errno),
2763 "%s", _dbus_strerror (errno));
2767 statbuf->mode = sb.st_mode;
2768 statbuf->nlink = sb.st_nlink;
2769 statbuf->uid = sb.st_uid;
2770 statbuf->gid = sb.st_gid;
2771 statbuf->size = sb.st_size;
2772 statbuf->atime = sb.st_atime;
2773 statbuf->mtime = sb.st_mtime;
2774 statbuf->ctime = sb.st_ctime;
2780 * Creates a full-duplex pipe (as in socketpair()).
2781 * Sets both ends of the pipe nonblocking.
2783 * @param fd1 return location for one end
2784 * @param fd2 return location for the other end
2785 * @param blocking #TRUE if pipe should be blocking
2786 * @param error error return
2787 * @returns #FALSE on failure (if error is set)
2790 _dbus_full_duplex_pipe (int *fd1,
2792 dbus_bool_t blocking,
2795 #ifdef HAVE_SOCKETPAIR
2798 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2800 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2802 dbus_set_error (error, _dbus_error_from_errno (errno),
2803 "Could not create full-duplex pipe");
2808 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2809 !_dbus_set_fd_nonblocking (fds[1], NULL)))
2811 dbus_set_error (error, _dbus_error_from_errno (errno),
2812 "Could not set full-duplex pipe nonblocking");
2825 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2826 dbus_set_error (error, DBUS_ERROR_FAILED,
2827 "_dbus_full_duplex_pipe() not implemented on this OS");
2833 * Closes a file descriptor.
2835 * @param fd the file descriptor
2836 * @param error error object
2837 * @returns #FALSE if error set
2840 _dbus_close (int fd,
2843 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2851 dbus_set_error (error, _dbus_error_from_errno (errno),
2852 "Could not close fd %d", fd);
2860 * Sets a file descriptor to be nonblocking.
2862 * @param fd the file descriptor.
2863 * @param error address of error location.
2864 * @returns #TRUE on success.
2867 _dbus_set_fd_nonblocking (int fd,
2872 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2874 val = fcntl (fd, F_GETFL, 0);
2877 dbus_set_error (error, _dbus_error_from_errno (errno),
2878 "Failed to get flags from file descriptor %d: %s",
2879 fd, _dbus_strerror (errno));
2880 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2881 _dbus_strerror (errno));
2885 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2887 dbus_set_error (error, _dbus_error_from_errno (errno),
2888 "Failed to set nonblocking flag of file descriptor %d: %s",
2889 fd, _dbus_strerror (errno));
2890 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2891 fd, _dbus_strerror (errno));
2900 * On GNU libc systems, print a crude backtrace to the verbose log.
2901 * On other systems, print "no backtrace support"
2905 _dbus_print_backtrace (void)
2907 #if defined (HAVE_BACKTRACE) && defined (DBUS_ENABLE_VERBOSE_MODE)
2913 bt_size = backtrace (bt, 500);
2915 syms = backtrace_symbols (bt, bt_size);
2920 _dbus_verbose (" %s\n", syms[i]);
2926 _dbus_verbose (" D-BUS not compiled with backtrace support\n");
2931 * Does the chdir, fork, setsid, etc. to become a daemon process.
2933 * @param error return location for errors
2934 * @returns #FALSE on failure
2937 _dbus_become_daemon (DBusError *error)
2941 /* This is so we don't prevent unmounting of devices. We divert
2942 * all messages to syslog
2944 if (chdir ("/") < 0)
2946 dbus_set_error (error, DBUS_ERROR_FAILED,
2947 "Could not chdir() to root directory");
2951 s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
2952 if (s == NULL || *s == '\0')
2956 /* silently ignore failures here, if someone
2957 * doesn't have /dev/null we may as well try
2958 * to continue anyhow
2961 dev_null_fd = open ("/dev/null", O_RDWR);
2962 if (dev_null_fd >= 0)
2964 dup2 (dev_null_fd, 0);
2965 dup2 (dev_null_fd, 1);
2966 dup2 (dev_null_fd, 2);
2970 /* Get a predictable umask */
2976 dbus_set_error (error, _dbus_error_from_errno (errno),
2977 "Failed to fork daemon: %s", _dbus_strerror (errno));
2989 if (setsid () == -1)
2990 _dbus_assert_not_reached ("setsid() failed");
2996 * Changes the user and group the bus is running as.
2998 * @param uid the new user ID
2999 * @param gid the new group ID
3000 * @param error return location for errors
3001 * @returns #FALSE on failure
3004 _dbus_change_identity (unsigned long uid,
3008 /* Set GID first, or the setuid may remove our permission
3011 if (setgid (gid) < 0)
3013 dbus_set_error (error, _dbus_error_from_errno (errno),
3014 "Failed to set GID to %lu: %s", gid,
3015 _dbus_strerror (errno));
3019 if (setuid (uid) < 0)
3021 dbus_set_error (error, _dbus_error_from_errno (errno),
3022 "Failed to set UID to %lu: %s", uid,
3023 _dbus_strerror (errno));
3030 /** Installs a UNIX signal handler
3032 * @param sig the signal to handle
3033 * @param handler the handler
3036 _dbus_set_signal_handler (int sig,
3037 DBusSignalHandler handler)
3039 struct sigaction act;
3040 sigset_t empty_mask;
3042 sigemptyset (&empty_mask);
3043 act.sa_handler = handler;
3044 act.sa_mask = empty_mask;
3046 sigaction (sig, &act, 0);
3050 #ifdef DBUS_BUILD_TESTS
3053 check_dirname (const char *filename,
3054 const char *dirname)
3058 _dbus_string_init_const (&f, filename);
3060 if (!_dbus_string_init (&d))
3061 _dbus_assert_not_reached ("no memory");
3063 if (!_dbus_string_get_dirname (&f, &d))
3064 _dbus_assert_not_reached ("no memory");
3066 if (!_dbus_string_equal_c_str (&d, dirname))
3068 _dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"\n",
3070 _dbus_string_get_const_data (&d),
3075 _dbus_string_free (&d);
3079 check_path_absolute (const char *path,
3080 dbus_bool_t expected)
3084 _dbus_string_init_const (&p, path);
3086 if (_dbus_path_is_absolute (&p) != expected)
3088 _dbus_warn ("For path \"%s\" expected absolute = %d got %d\n",
3089 path, expected, _dbus_path_is_absolute (&p));
3095 * Unit test for dbus-sysdeps.c.
3097 * @returns #TRUE on success.
3100 _dbus_sysdeps_test (void)
3102 check_dirname ("foo", ".");
3103 check_dirname ("foo/bar", "foo");
3104 check_dirname ("foo//bar", "foo");
3105 check_dirname ("foo///bar", "foo");
3106 check_dirname ("foo/bar/", "foo");
3107 check_dirname ("foo//bar/", "foo");
3108 check_dirname ("foo///bar/", "foo");
3109 check_dirname ("foo/bar//", "foo");
3110 check_dirname ("foo//bar////", "foo");
3111 check_dirname ("foo///bar///////", "foo");
3112 check_dirname ("/foo", "/");
3113 check_dirname ("////foo", "/");
3114 check_dirname ("/foo/bar", "/foo");
3115 check_dirname ("/foo//bar", "/foo");
3116 check_dirname ("/foo///bar", "/foo");
3117 check_dirname ("/", "/");
3118 check_dirname ("///", "/");
3119 check_dirname ("", ".");
3121 check_path_absolute ("/", TRUE);
3122 check_path_absolute ("/foo", TRUE);
3123 check_path_absolute ("", FALSE);
3124 check_path_absolute ("foo", FALSE);
3125 check_path_absolute ("foo/bar", FALSE);
3129 #endif /* DBUS_BUILD_TESTS */
3131 /** @} end of sysdeps */