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 append_unique_chars (DBusString *str)
2013 static const char letters[] =
2014 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
2018 #define N_UNIQUE_CHARS 8
2020 if (!_dbus_generate_random_bytes (str, N_UNIQUE_CHARS))
2023 len = _dbus_string_get_length (str);
2024 i = len - N_UNIQUE_CHARS;
2027 _dbus_string_set_byte (str, i,
2028 letters[_dbus_string_get_byte (str, i) %
2029 (sizeof (letters) - 1)]);
2034 _dbus_assert (_dbus_string_validate_ascii (str, len - N_UNIQUE_CHARS,
2041 * Writes a string out to a file. If the file exists,
2042 * it will be atomically overwritten by the new data.
2044 * @param str the string to write out
2045 * @param filename the file to save string to
2046 * @param error error to be filled in on failure
2047 * @returns #FALSE on failure
2050 _dbus_string_save_to_file (const DBusString *str,
2051 const DBusString *filename,
2056 const char *filename_c;
2057 DBusString tmp_filename;
2058 const char *tmp_filename_c;
2060 dbus_bool_t need_unlink;
2063 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2067 need_unlink = FALSE;
2069 if (!_dbus_string_init (&tmp_filename))
2071 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2075 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
2077 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2081 if (!_dbus_string_append (&tmp_filename, "."))
2083 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2087 if (!append_unique_chars (&tmp_filename))
2089 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2093 filename_c = _dbus_string_get_const_data (filename);
2094 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
2096 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2100 dbus_set_error (error, _dbus_error_from_errno (errno),
2101 "Could not create %s: %s", tmp_filename_c,
2102 _dbus_strerror (errno));
2109 bytes_to_write = _dbus_string_get_length (str);
2111 while (total < bytes_to_write)
2115 bytes_written = _dbus_write (fd, str, total,
2116 bytes_to_write - total);
2118 if (bytes_written <= 0)
2120 dbus_set_error (error, _dbus_error_from_errno (errno),
2121 "Could not write to %s: %s", tmp_filename_c,
2122 _dbus_strerror (errno));
2127 total += bytes_written;
2132 dbus_set_error (error, _dbus_error_from_errno (errno),
2133 "Could not close file %s: %s",
2134 tmp_filename_c, _dbus_strerror (errno));
2141 if (rename (tmp_filename_c, filename_c) < 0)
2143 dbus_set_error (error, _dbus_error_from_errno (errno),
2144 "Could not rename %s to %s: %s",
2145 tmp_filename_c, filename_c,
2146 _dbus_strerror (errno));
2151 need_unlink = FALSE;
2156 /* close first, then unlink, to prevent ".nfs34234235" garbage
2163 if (need_unlink && unlink (tmp_filename_c) < 0)
2164 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
2165 tmp_filename_c, _dbus_strerror (errno));
2167 _dbus_string_free (&tmp_filename);
2170 _DBUS_ASSERT_ERROR_IS_SET (error);
2175 /** Creates the given file, failing if the file already exists.
2177 * @param filename the filename
2178 * @param error error location
2179 * @returns #TRUE if we created the file and it didn't exist
2182 _dbus_create_file_exclusively (const DBusString *filename,
2186 const char *filename_c;
2188 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2190 filename_c = _dbus_string_get_const_data (filename);
2192 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
2196 dbus_set_error (error,
2198 "Could not create file %s: %s\n",
2200 _dbus_strerror (errno));
2206 dbus_set_error (error,
2208 "Could not close file %s: %s\n",
2210 _dbus_strerror (errno));
2218 * Deletes the given file.
2220 * @param filename the filename
2221 * @param error error location
2223 * @returns #TRUE if unlink() succeeded
2226 _dbus_delete_file (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 (unlink (filename_c) < 0)
2237 dbus_set_error (error, DBUS_ERROR_FAILED,
2238 "Failed to delete file %s: %s\n",
2239 filename_c, _dbus_strerror (errno));
2247 * Creates a directory; succeeds if the directory
2248 * is created or already existed.
2250 * @param filename directory filename
2251 * @param error initialized error object
2252 * @returns #TRUE on success
2255 _dbus_create_directory (const DBusString *filename,
2258 const char *filename_c;
2260 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2262 filename_c = _dbus_string_get_const_data (filename);
2264 if (mkdir (filename_c, 0700) < 0)
2266 if (errno == EEXIST)
2269 dbus_set_error (error, DBUS_ERROR_FAILED,
2270 "Failed to create directory %s: %s\n",
2271 filename_c, _dbus_strerror (errno));
2279 * Appends the given filename to the given directory.
2281 * @todo it might be cute to collapse multiple '/' such as "foo//"
2284 * @param dir the directory name
2285 * @param next_component the filename
2286 * @returns #TRUE on success
2289 _dbus_concat_dir_and_file (DBusString *dir,
2290 const DBusString *next_component)
2292 dbus_bool_t dir_ends_in_slash;
2293 dbus_bool_t file_starts_with_slash;
2295 if (_dbus_string_get_length (dir) == 0 ||
2296 _dbus_string_get_length (next_component) == 0)
2299 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2300 _dbus_string_get_length (dir) - 1);
2302 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2304 if (dir_ends_in_slash && file_starts_with_slash)
2306 _dbus_string_shorten (dir, 1);
2308 else if (!(dir_ends_in_slash || file_starts_with_slash))
2310 if (!_dbus_string_append_byte (dir, '/'))
2314 return _dbus_string_copy (next_component, 0, dir,
2315 _dbus_string_get_length (dir));
2319 * Get the directory name from a complete filename
2320 * @param filename the filename
2321 * @param dirname string to append directory name to
2322 * @returns #FALSE if no memory
2325 _dbus_string_get_dirname (const DBusString *filename,
2326 DBusString *dirname)
2330 _dbus_assert (filename != dirname);
2331 _dbus_assert (filename != NULL);
2332 _dbus_assert (dirname != NULL);
2334 /* Ignore any separators on the end */
2335 sep = _dbus_string_get_length (filename);
2337 return _dbus_string_append (dirname, "."); /* empty string passed in */
2339 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
2342 _dbus_assert (sep >= 0);
2345 return _dbus_string_append (dirname, "/");
2347 /* Now find the previous separator */
2348 _dbus_string_find_byte_backward (filename, sep, '/', &sep);
2350 return _dbus_string_append (dirname, ".");
2352 /* skip multiple separators */
2353 while (sep > 0 && _dbus_string_get_byte (filename, sep - 1) == '/')
2356 _dbus_assert (sep >= 0);
2359 _dbus_string_get_byte (filename, 0) == '/')
2360 return _dbus_string_append (dirname, "/");
2362 return _dbus_string_copy_len (filename, 0, sep - 0,
2363 dirname, _dbus_string_get_length (dirname));
2367 * Checks whether the filename is an absolute path
2369 * @param filename the filename
2370 * @returns #TRUE if an absolute path
2373 _dbus_path_is_absolute (const DBusString *filename)
2375 if (_dbus_string_get_length (filename) > 0)
2376 return _dbus_string_get_byte (filename, 0) == '/';
2388 * Open a directory to iterate over.
2390 * @param filename the directory name
2391 * @param error exception return object or #NULL
2392 * @returns new iterator, or #NULL on error
2395 _dbus_directory_open (const DBusString *filename,
2400 const char *filename_c;
2402 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2404 filename_c = _dbus_string_get_const_data (filename);
2406 d = opendir (filename_c);
2409 dbus_set_error (error, _dbus_error_from_errno (errno),
2410 "Failed to read directory \"%s\": %s",
2412 _dbus_strerror (errno));
2415 iter = dbus_new0 (DBusDirIter, 1);
2419 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
2420 "Could not allocate memory for directory iterator");
2430 * Get next file in the directory. Will not return "." or ".." on
2431 * UNIX. If an error occurs, the contents of "filename" are
2432 * undefined. The error is never set if the function succeeds.
2434 * @todo for thread safety, I think we have to use
2435 * readdir_r(). (GLib has the same issue, should file a bug.)
2437 * @param iter the iterator
2438 * @param filename string to be set to the next file in the dir
2439 * @param error return location for error
2440 * @returns #TRUE if filename was filled in with a new filename
2443 _dbus_directory_get_next_file (DBusDirIter *iter,
2444 DBusString *filename,
2449 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2453 ent = readdir (iter->d);
2457 dbus_set_error (error,
2458 _dbus_error_from_errno (errno),
2459 "%s", _dbus_strerror (errno));
2462 else if (ent->d_name[0] == '.' &&
2463 (ent->d_name[1] == '\0' ||
2464 (ent->d_name[1] == '.' && ent->d_name[2] == '\0')))
2468 _dbus_string_set_length (filename, 0);
2469 if (!_dbus_string_append (filename, ent->d_name))
2471 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
2472 "No memory to read directory entry");
2481 * Closes a directory iteration.
2484 _dbus_directory_close (DBusDirIter *iter)
2491 * Generates the given number of random bytes,
2492 * using the best mechanism we can come up with.
2494 * @param str the string
2495 * @param n_bytes the number of random bytes to append to string
2496 * @returns #TRUE on success, #FALSE if no memory or other failure
2499 _dbus_generate_random_bytes (DBusString *str,
2505 old_len = _dbus_string_get_length (str);
2508 /* note, urandom on linux will fall back to pseudorandom */
2509 fd = open ("/dev/urandom", O_RDONLY);
2512 unsigned long tv_usec;
2515 /* fall back to pseudorandom */
2516 _dbus_verbose ("Falling back to pseudorandom for %d bytes\n",
2519 _dbus_get_current_time (NULL, &tv_usec);
2529 b = (r / (double) RAND_MAX) * 255.0;
2531 if (!_dbus_string_append_byte (str, b))
2541 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2544 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2553 _dbus_string_set_length (str, old_len);
2560 * A wrapper around strerror() because some platforms
2561 * may be lame and not have strerror().
2563 * @param error_number errno.
2564 * @returns error description.
2567 _dbus_strerror (int error_number)
2571 msg = strerror (error_number);
2579 * signal (SIGPIPE, SIG_IGN);
2582 _dbus_disable_sigpipe (void)
2584 signal (SIGPIPE, SIG_IGN);
2588 * Sets the file descriptor to be close
2589 * on exec. Should be called for all file
2590 * descriptors in D-BUS code.
2592 * @param fd the file descriptor
2595 _dbus_fd_set_close_on_exec (int fd)
2599 val = fcntl (fd, F_GETFD, 0);
2606 fcntl (fd, F_SETFD, val);
2610 * Converts a UNIX errno into a #DBusError name.
2612 * @todo should cover more errnos, specifically those
2615 * @param error_number the errno.
2616 * @returns an error name
2619 _dbus_error_from_errno (int error_number)
2621 switch (error_number)
2624 return DBUS_ERROR_FAILED;
2626 #ifdef EPROTONOSUPPORT
2627 case EPROTONOSUPPORT:
2628 return DBUS_ERROR_NOT_SUPPORTED;
2632 return DBUS_ERROR_NOT_SUPPORTED;
2636 return DBUS_ERROR_LIMITS_EXCEEDED; /* kernel out of memory */
2640 return DBUS_ERROR_LIMITS_EXCEEDED;
2644 return DBUS_ERROR_ACCESS_DENIED;
2648 return DBUS_ERROR_ACCESS_DENIED;
2652 return DBUS_ERROR_NO_MEMORY;
2656 return DBUS_ERROR_NO_MEMORY;
2660 return DBUS_ERROR_FAILED;
2664 return DBUS_ERROR_FAILED;
2668 return DBUS_ERROR_FAILED;
2672 return DBUS_ERROR_FAILED;
2676 return DBUS_ERROR_FAILED;
2680 return DBUS_ERROR_NO_SERVER;
2684 return DBUS_ERROR_TIMEOUT;
2688 return DBUS_ERROR_NO_NETWORK;
2692 return DBUS_ERROR_ADDRESS_IN_USE;
2696 return DBUS_ERROR_FILE_NOT_FOUND;
2700 return DBUS_ERROR_FILE_NOT_FOUND;
2704 return DBUS_ERROR_FAILED;
2708 * Exit the process, returning the given value.
2710 * @param code the exit code
2713 _dbus_exit (int code)
2721 * @param filename the filename to stat
2722 * @param statbuf the stat info to fill in
2723 * @param error return location for error
2724 * @returns #FALSE if error was set
2727 _dbus_stat (const DBusString *filename,
2731 const char *filename_c;
2734 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2736 filename_c = _dbus_string_get_const_data (filename);
2738 if (stat (filename_c, &sb) < 0)
2740 dbus_set_error (error, _dbus_error_from_errno (errno),
2741 "%s", _dbus_strerror (errno));
2745 statbuf->mode = sb.st_mode;
2746 statbuf->nlink = sb.st_nlink;
2747 statbuf->uid = sb.st_uid;
2748 statbuf->gid = sb.st_gid;
2749 statbuf->size = sb.st_size;
2750 statbuf->atime = sb.st_atime;
2751 statbuf->mtime = sb.st_mtime;
2752 statbuf->ctime = sb.st_ctime;
2758 * Creates a full-duplex pipe (as in socketpair()).
2759 * Sets both ends of the pipe nonblocking.
2761 * @param fd1 return location for one end
2762 * @param fd2 return location for the other end
2763 * @param blocking #TRUE if pipe should be blocking
2764 * @param error error return
2765 * @returns #FALSE on failure (if error is set)
2768 _dbus_full_duplex_pipe (int *fd1,
2770 dbus_bool_t blocking,
2773 #ifdef HAVE_SOCKETPAIR
2776 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2778 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2780 dbus_set_error (error, _dbus_error_from_errno (errno),
2781 "Could not create full-duplex pipe");
2786 !_dbus_set_fd_nonblocking (fds[0], NULL) ||
2787 !_dbus_set_fd_nonblocking (fds[1], NULL))
2789 dbus_set_error (error, _dbus_error_from_errno (errno),
2790 "Could not set full-duplex pipe nonblocking");
2803 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2804 dbus_set_error (error, DBUS_ERROR_FAILED,
2805 "_dbus_full_duplex_pipe() not implemented on this OS");
2811 * Closes a file descriptor.
2813 * @param fd the file descriptor
2814 * @param error error object
2815 * @returns #FALSE if error set
2818 _dbus_close (int fd,
2821 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2829 dbus_set_error (error, _dbus_error_from_errno (errno),
2830 "Could not close fd %d", fd);
2838 * Sets a file descriptor to be nonblocking.
2840 * @param fd the file descriptor.
2841 * @param error address of error location.
2842 * @returns #TRUE on success.
2845 _dbus_set_fd_nonblocking (int fd,
2850 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2852 val = fcntl (fd, F_GETFL, 0);
2855 dbus_set_error (error, _dbus_error_from_errno (errno),
2856 "Failed to get flags from file descriptor %d: %s",
2857 fd, _dbus_strerror (errno));
2858 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2859 _dbus_strerror (errno));
2863 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2865 dbus_set_error (error, _dbus_error_from_errno (errno),
2866 "Failed to set nonblocking flag of file descriptor %d: %s",
2867 fd, _dbus_strerror (errno));
2868 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2869 fd, _dbus_strerror (errno));
2878 * On GNU libc systems, print a crude backtrace to the verbose log.
2879 * On other systems, print "no backtrace support"
2883 _dbus_print_backtrace (void)
2885 #if defined (HAVE_BACKTRACE) && defined (DBUS_ENABLE_VERBOSE_MODE)
2891 bt_size = backtrace (bt, 500);
2893 syms = backtrace_symbols (bt, bt_size);
2898 _dbus_verbose (" %s\n", syms[i]);
2904 _dbus_verbose (" D-BUS not compiled with backtrace support\n");
2909 * Does the chdir, fork, setsid, etc. to become a daemon process.
2911 * @param error return location for errors
2912 * @returns #FALSE on failure
2915 _dbus_become_daemon (DBusError *error)
2919 /* This is so we don't prevent unmounting of devices. We divert
2920 * all messages to syslog
2922 if (chdir ("/") < 0)
2924 dbus_set_error (error, DBUS_ERROR_FAILED,
2925 "Could not chdir() to root directory");
2929 s = _dbus_getenv ("DBUS_DEBUG_OUTPUT");
2930 if (s == NULL || *s == '\0')
2934 /* silently ignore failures here, if someone
2935 * doesn't have /dev/null we may as well try
2936 * to continue anyhow
2939 dev_null_fd = open ("/dev/null", O_RDWR);
2940 if (dev_null_fd >= 0)
2942 dup2 (dev_null_fd, 0);
2943 dup2 (dev_null_fd, 1);
2944 dup2 (dev_null_fd, 2);
2948 /* Get a predictable umask */
2954 dbus_set_error (error, _dbus_error_from_errno (errno),
2955 "Failed to fork daemon: %s", _dbus_strerror (errno));
2967 if (setsid () == -1)
2968 _dbus_assert_not_reached ("setsid() failed");
2974 * Changes the user and group the bus is running as.
2976 * @param uid the new user ID
2977 * @param gid the new group ID
2978 * @param error return location for errors
2979 * @returns #FALSE on failure
2982 _dbus_change_identity (unsigned long uid,
2986 /* Set GID first, or the setuid may remove our permission
2989 if (setgid (gid) < 0)
2991 dbus_set_error (error, _dbus_error_from_errno (errno),
2992 "Failed to set GID to %lu: %s", gid,
2993 _dbus_strerror (errno));
2997 if (setuid (uid) < 0)
2999 dbus_set_error (error, _dbus_error_from_errno (errno),
3000 "Failed to set UID to %lu: %s", uid,
3001 _dbus_strerror (errno));
3008 #ifdef DBUS_BUILD_TESTS
3011 check_dirname (const char *filename,
3012 const char *dirname)
3016 _dbus_string_init_const (&f, filename);
3018 if (!_dbus_string_init (&d))
3019 _dbus_assert_not_reached ("no memory");
3021 if (!_dbus_string_get_dirname (&f, &d))
3022 _dbus_assert_not_reached ("no memory");
3024 if (!_dbus_string_equal_c_str (&d, dirname))
3026 _dbus_warn ("For filename \"%s\" got dirname \"%s\" and expected \"%s\"\n",
3028 _dbus_string_get_const_data (&d),
3033 _dbus_string_free (&d);
3037 check_path_absolute (const char *path,
3038 dbus_bool_t expected)
3042 _dbus_string_init_const (&p, path);
3044 if (_dbus_path_is_absolute (&p) != expected)
3046 _dbus_warn ("For path \"%s\" expected absolute = %d got %d\n",
3047 path, expected, _dbus_path_is_absolute (&p));
3053 * Unit test for dbus-sysdeps.c.
3055 * @returns #TRUE on success.
3058 _dbus_sysdeps_test (void)
3060 check_dirname ("foo", ".");
3061 check_dirname ("foo/bar", "foo");
3062 check_dirname ("foo//bar", "foo");
3063 check_dirname ("foo///bar", "foo");
3064 check_dirname ("foo/bar/", "foo");
3065 check_dirname ("foo//bar/", "foo");
3066 check_dirname ("foo///bar/", "foo");
3067 check_dirname ("foo/bar//", "foo");
3068 check_dirname ("foo//bar////", "foo");
3069 check_dirname ("foo///bar///////", "foo");
3070 check_dirname ("/foo", "/");
3071 check_dirname ("////foo", "/");
3072 check_dirname ("/foo/bar", "/foo");
3073 check_dirname ("/foo//bar", "/foo");
3074 check_dirname ("/foo///bar", "/foo");
3075 check_dirname ("/", "/");
3076 check_dirname ("///", "/");
3077 check_dirname ("", ".");
3079 check_path_absolute ("/", TRUE);
3080 check_path_absolute ("/foo", TRUE);
3081 check_path_absolute ("", FALSE);
3082 check_path_absolute ("foo", FALSE);
3083 check_path_absolute ("foo/bar", FALSE);
3087 #endif /* DBUS_BUILD_TESTS */
3089 /** @} end of sysdeps */