00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "dbus-internals.h"
00026 #include "dbus-sysdeps.h"
00027 #include "dbus-threads.h"
00028 #include "dbus-protocol.h"
00029 #include "dbus-string.h"
00030 #include <sys/types.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033 #include <signal.h>
00034 #include <unistd.h>
00035 #include <stdio.h>
00036 #include <fcntl.h>
00037 #include <sys/socket.h>
00038 #include <dirent.h>
00039 #include <sys/un.h>
00040 #include <pwd.h>
00041 #include <time.h>
00042 #include <locale.h>
00043 #include <sys/time.h>
00044 #include <sys/stat.h>
00045 #include <sys/wait.h>
00046 #include <netinet/in.h>
00047 #include <netdb.h>
00048 #include <grp.h>
00049
00050 #ifdef HAVE_ERRNO_H
00051 #include <errno.h>
00052 #endif
00053 #ifdef HAVE_WRITEV
00054 #include <sys/uio.h>
00055 #endif
00056 #ifdef HAVE_POLL
00057 #include <sys/poll.h>
00058 #endif
00059 #ifdef HAVE_BACKTRACE
00060 #include <execinfo.h>
00061 #endif
00062 #ifdef HAVE_GETPEERUCRED
00063 #include <ucred.h>
00064 #endif
00065
00066 #ifndef O_BINARY
00067 #define O_BINARY 0
00068 #endif
00069
00070 #ifndef HAVE_SOCKLEN_T
00071 #define socklen_t int
00072 #endif
00073
00092 int
00093 _dbus_read (int fd,
00094 DBusString *buffer,
00095 int count)
00096 {
00097 int bytes_read;
00098 int start;
00099 char *data;
00100
00101 _dbus_assert (count >= 0);
00102
00103 start = _dbus_string_get_length (buffer);
00104
00105 if (!_dbus_string_lengthen (buffer, count))
00106 {
00107 errno = ENOMEM;
00108 return -1;
00109 }
00110
00111 data = _dbus_string_get_data_len (buffer, start, count);
00112
00113 again:
00114
00115 bytes_read = read (fd, data, count);
00116
00117 if (bytes_read < 0)
00118 {
00119 if (errno == EINTR)
00120 goto again;
00121 else
00122 {
00123
00124 _dbus_string_set_length (buffer, start);
00125 return -1;
00126 }
00127 }
00128 else
00129 {
00130
00131 _dbus_string_set_length (buffer, start + bytes_read);
00132
00133 #if 0
00134 if (bytes_read > 0)
00135 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00136 #endif
00137
00138 return bytes_read;
00139 }
00140 }
00141
00152 int
00153 _dbus_write (int fd,
00154 const DBusString *buffer,
00155 int start,
00156 int len)
00157 {
00158 const char *data;
00159 int bytes_written;
00160
00161 data = _dbus_string_get_const_data_len (buffer, start, len);
00162
00163 again:
00164
00165 bytes_written = write (fd, data, len);
00166
00167 if (bytes_written < 0 && errno == EINTR)
00168 goto again;
00169
00170 #if 0
00171 if (bytes_written > 0)
00172 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00173 #endif
00174
00175 return bytes_written;
00176 }
00177
00198 int
00199 _dbus_write_two (int fd,
00200 const DBusString *buffer1,
00201 int start1,
00202 int len1,
00203 const DBusString *buffer2,
00204 int start2,
00205 int len2)
00206 {
00207 _dbus_assert (buffer1 != NULL);
00208 _dbus_assert (start1 >= 0);
00209 _dbus_assert (start2 >= 0);
00210 _dbus_assert (len1 >= 0);
00211 _dbus_assert (len2 >= 0);
00212
00213 #ifdef HAVE_WRITEV
00214 {
00215 struct iovec vectors[2];
00216 const char *data1;
00217 const char *data2;
00218 int bytes_written;
00219
00220 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00221
00222 if (buffer2 != NULL)
00223 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00224 else
00225 {
00226 data2 = NULL;
00227 start2 = 0;
00228 len2 = 0;
00229 }
00230
00231 vectors[0].iov_base = (char*) data1;
00232 vectors[0].iov_len = len1;
00233 vectors[1].iov_base = (char*) data2;
00234 vectors[1].iov_len = len2;
00235
00236 again:
00237
00238 bytes_written = writev (fd,
00239 vectors,
00240 data2 ? 2 : 1);
00241
00242 if (bytes_written < 0 && errno == EINTR)
00243 goto again;
00244
00245 return bytes_written;
00246 }
00247 #else
00248 {
00249 int ret1;
00250
00251 ret1 = _dbus_write (fd, buffer1, start1, len1);
00252 if (ret1 == len1 && buffer2 != NULL)
00253 {
00254 ret2 = _dbus_write (fd, buffer2, start2, len2);
00255 if (ret2 < 0)
00256 ret2 = 0;
00257
00258 return ret1 + ret2;
00259 }
00260 else
00261 return ret1;
00262 }
00263 #endif
00264 }
00265
00266 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00267
00295 int
00296 _dbus_connect_unix_socket (const char *path,
00297 dbus_bool_t abstract,
00298 DBusError *error)
00299 {
00300 int fd;
00301 size_t path_len;
00302 struct sockaddr_un addr;
00303
00304 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00305
00306 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00307 path, abstract);
00308
00309 fd = socket (PF_UNIX, SOCK_STREAM, 0);
00310
00311 if (fd < 0)
00312 {
00313 dbus_set_error (error,
00314 _dbus_error_from_errno (errno),
00315 "Failed to create socket: %s",
00316 _dbus_strerror (errno));
00317
00318 return -1;
00319 }
00320
00321 _DBUS_ZERO (addr);
00322 addr.sun_family = AF_UNIX;
00323 path_len = strlen (path);
00324
00325 if (abstract)
00326 {
00327 #ifdef HAVE_ABSTRACT_SOCKETS
00328 addr.sun_path[0] = '\0';
00329 path_len++;
00330
00331 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00332 {
00333 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00334 "Abstract socket name too long\n");
00335 _dbus_close (fd, NULL);
00336 return -1;
00337 }
00338
00339 strncpy (&addr.sun_path[1], path, path_len);
00340
00341 #else
00342 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00343 "Operating system does not support abstract socket namespace\n");
00344 _dbus_close (fd, NULL);
00345 return -1;
00346 #endif
00347 }
00348 else
00349 {
00350 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00351 {
00352 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00353 "Socket name too long\n");
00354 _dbus_close (fd, NULL);
00355 return -1;
00356 }
00357
00358 strncpy (addr.sun_path, path, path_len);
00359 }
00360
00361 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00362 {
00363 dbus_set_error (error,
00364 _dbus_error_from_errno (errno),
00365 "Failed to connect to socket %s: %s",
00366 path, _dbus_strerror (errno));
00367
00368 _dbus_close (fd, NULL);
00369 fd = -1;
00370
00371 return -1;
00372 }
00373
00374 if (!_dbus_set_fd_nonblocking (fd, error))
00375 {
00376 _DBUS_ASSERT_ERROR_IS_SET (error);
00377
00378 _dbus_close (fd, NULL);
00379 fd = -1;
00380
00381 return -1;
00382 }
00383
00384 return fd;
00385 }
00386
00396 static dbus_bool_t
00397 _dbus_set_local_creds (int fd, dbus_bool_t on)
00398 {
00399 dbus_bool_t retval = TRUE;
00400
00401 #if defined(LOCAL_CREDS) && !defined(HAVE_CMSGCRED)
00402 int val = on ? 1 : 0;
00403 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00404 {
00405 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00406 retval = FALSE;
00407 }
00408 else
00409 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00410 on ? "enabled" : "disabled", fd);
00411 #endif
00412
00413 return retval;
00414 }
00415
00431 int
00432 _dbus_listen_unix_socket (const char *path,
00433 dbus_bool_t abstract,
00434 DBusError *error)
00435 {
00436 int listen_fd;
00437 struct sockaddr_un addr;
00438 size_t path_len;
00439
00440 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00441
00442 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00443 path, abstract);
00444
00445 listen_fd = socket (PF_UNIX, SOCK_STREAM, 0);
00446
00447 if (listen_fd < 0)
00448 {
00449 dbus_set_error (error, _dbus_error_from_errno (errno),
00450 "Failed to create socket \"%s\": %s",
00451 path, _dbus_strerror (errno));
00452 return -1;
00453 }
00454
00455 _DBUS_ZERO (addr);
00456 addr.sun_family = AF_UNIX;
00457 path_len = strlen (path);
00458
00459 if (abstract)
00460 {
00461 #ifdef HAVE_ABSTRACT_SOCKETS
00462
00463
00464
00465 addr.sun_path[0] = '\0';
00466 path_len++;
00467
00468 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00469 {
00470 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00471 "Abstract socket name too long\n");
00472 _dbus_close (listen_fd, NULL);
00473 return -1;
00474 }
00475
00476 strncpy (&addr.sun_path[1], path, path_len);
00477
00478 #else
00479 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00480 "Operating system does not support abstract socket namespace\n");
00481 _dbus_close (listen_fd, NULL);
00482 return -1;
00483 #endif
00484 }
00485 else
00486 {
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 {
00498 struct stat sb;
00499
00500 if (stat (path, &sb) == 0 &&
00501 S_ISSOCK (sb.st_mode))
00502 unlink (path);
00503 }
00504
00505 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00506 {
00507 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00508 "Abstract socket name too long\n");
00509 _dbus_close (listen_fd, NULL);
00510 return -1;
00511 }
00512
00513 strncpy (addr.sun_path, path, path_len);
00514 }
00515
00516 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00517 {
00518 dbus_set_error (error, _dbus_error_from_errno (errno),
00519 "Failed to bind socket \"%s\": %s",
00520 path, _dbus_strerror (errno));
00521 _dbus_close (listen_fd, NULL);
00522 return -1;
00523 }
00524
00525 if (listen (listen_fd, 30 ) < 0)
00526 {
00527 dbus_set_error (error, _dbus_error_from_errno (errno),
00528 "Failed to listen on socket \"%s\": %s",
00529 path, _dbus_strerror (errno));
00530 _dbus_close (listen_fd, NULL);
00531 return -1;
00532 }
00533
00534 if (!_dbus_set_local_creds (listen_fd, TRUE))
00535 {
00536 dbus_set_error (error, _dbus_error_from_errno (errno),
00537 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
00538 path, _dbus_strerror (errno));
00539 close (listen_fd);
00540 return -1;
00541 }
00542
00543 if (!_dbus_set_fd_nonblocking (listen_fd, error))
00544 {
00545 _DBUS_ASSERT_ERROR_IS_SET (error);
00546 _dbus_close (listen_fd, NULL);
00547 return -1;
00548 }
00549
00550
00551
00552
00553 if (!abstract && chmod (path, 0777) < 0)
00554 _dbus_warn ("Could not set mode 0777 on socket %s\n",
00555 path);
00556
00557 return listen_fd;
00558 }
00559
00570 int
00571 _dbus_connect_tcp_socket (const char *host,
00572 dbus_uint32_t port,
00573 DBusError *error)
00574 {
00575 int fd;
00576 struct sockaddr_in addr;
00577 struct hostent *he;
00578 struct in_addr *haddr;
00579
00580 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00581
00582 fd = socket (AF_INET, SOCK_STREAM, 0);
00583
00584 if (fd < 0)
00585 {
00586 dbus_set_error (error,
00587 _dbus_error_from_errno (errno),
00588 "Failed to create socket: %s",
00589 _dbus_strerror (errno));
00590
00591 return -1;
00592 }
00593
00594 if (host == NULL)
00595 host = "localhost";
00596
00597 he = gethostbyname (host);
00598 if (he == NULL)
00599 {
00600 dbus_set_error (error,
00601 _dbus_error_from_errno (errno),
00602 "Failed to lookup hostname: %s",
00603 host);
00604 _dbus_close (fd, NULL);
00605 return -1;
00606 }
00607
00608 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
00609
00610 _DBUS_ZERO (addr);
00611 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
00612 addr.sin_family = AF_INET;
00613 addr.sin_port = htons (port);
00614
00615 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
00616 {
00617 dbus_set_error (error,
00618 _dbus_error_from_errno (errno),
00619 "Failed to connect to socket %s:%d %s",
00620 host, port, _dbus_strerror (errno));
00621
00622 _dbus_close (fd, NULL);
00623 fd = -1;
00624
00625 return -1;
00626 }
00627
00628 if (!_dbus_set_fd_nonblocking (fd, error))
00629 {
00630 _dbus_close (fd, NULL);
00631 fd = -1;
00632
00633 return -1;
00634 }
00635
00636 return fd;
00637 }
00638
00649 int
00650 _dbus_listen_tcp_socket (const char *host,
00651 dbus_uint32_t port,
00652 DBusError *error)
00653 {
00654 int listen_fd;
00655 struct sockaddr_in addr;
00656 struct hostent *he;
00657 struct in_addr *haddr;
00658
00659 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00660
00661 listen_fd = socket (AF_INET, SOCK_STREAM, 0);
00662
00663 if (listen_fd < 0)
00664 {
00665 dbus_set_error (error, _dbus_error_from_errno (errno),
00666 "Failed to create socket \"%s:%d\": %s",
00667 host, port, _dbus_strerror (errno));
00668 return -1;
00669 }
00670
00671 he = gethostbyname (host);
00672 if (he == NULL)
00673 {
00674 dbus_set_error (error,
00675 _dbus_error_from_errno (errno),
00676 "Failed to lookup hostname: %s",
00677 host);
00678 _dbus_close (listen_fd, NULL);
00679 return -1;
00680 }
00681
00682 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
00683
00684 _DBUS_ZERO (addr);
00685 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
00686 addr.sin_family = AF_INET;
00687 addr.sin_port = htons (port);
00688
00689 if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
00690 {
00691 dbus_set_error (error, _dbus_error_from_errno (errno),
00692 "Failed to bind socket \"%s:%d\": %s",
00693 host, port, _dbus_strerror (errno));
00694 _dbus_close (listen_fd, NULL);
00695 return -1;
00696 }
00697
00698 if (listen (listen_fd, 30 ) < 0)
00699 {
00700 dbus_set_error (error, _dbus_error_from_errno (errno),
00701 "Failed to listen on socket \"%s:%d\": %s",
00702 host, port, _dbus_strerror (errno));
00703 _dbus_close (listen_fd, NULL);
00704 return -1;
00705 }
00706
00707 if (!_dbus_set_fd_nonblocking (listen_fd, error))
00708 {
00709 _dbus_close (listen_fd, NULL);
00710 return -1;
00711 }
00712
00713 return listen_fd;
00714 }
00715
00716 static dbus_bool_t
00717 write_credentials_byte (int server_fd,
00718 DBusError *error)
00719 {
00720 int bytes_written;
00721 char buf[1] = { '\0' };
00722 #if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
00723 struct {
00724 struct cmsghdr hdr;
00725 struct cmsgcred cred;
00726 } cmsg;
00727 struct iovec iov;
00728 struct msghdr msg;
00729 #endif
00730
00731 #if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
00732 iov.iov_base = buf;
00733 iov.iov_len = 1;
00734
00735 memset (&msg, 0, sizeof (msg));
00736 msg.msg_iov = &iov;
00737 msg.msg_iovlen = 1;
00738
00739 msg.msg_control = &cmsg;
00740 msg.msg_controllen = sizeof (cmsg);
00741 memset (&cmsg, 0, sizeof (cmsg));
00742 cmsg.hdr.cmsg_len = sizeof (cmsg);
00743 cmsg.hdr.cmsg_level = SOL_SOCKET;
00744 cmsg.hdr.cmsg_type = SCM_CREDS;
00745 #endif
00746
00747 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00748
00749 again:
00750
00751 #if defined(HAVE_CMSGCRED) && !defined(LOCAL_CREDS)
00752 bytes_written = sendmsg (server_fd, &msg, 0);
00753 #else
00754 bytes_written = write (server_fd, buf, 1);
00755 #endif
00756
00757 if (bytes_written < 0 && errno == EINTR)
00758 goto again;
00759
00760 if (bytes_written < 0)
00761 {
00762 dbus_set_error (error, _dbus_error_from_errno (errno),
00763 "Failed to write credentials byte: %s",
00764 _dbus_strerror (errno));
00765 return FALSE;
00766 }
00767 else if (bytes_written == 0)
00768 {
00769 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
00770 "wrote zero bytes writing credentials byte");
00771 return FALSE;
00772 }
00773 else
00774 {
00775 _dbus_assert (bytes_written == 1);
00776 _dbus_verbose ("wrote credentials byte\n");
00777 return TRUE;
00778 }
00779 }
00780
00799 dbus_bool_t
00800 _dbus_read_credentials_unix_socket (int client_fd,
00801 DBusCredentials *credentials,
00802 DBusError *error)
00803 {
00804 struct msghdr msg;
00805 struct iovec iov;
00806 char buf;
00807
00808 #ifdef HAVE_CMSGCRED
00809 struct {
00810 struct cmsghdr hdr;
00811 struct cmsgcred cred;
00812 } cmsg;
00813
00814 #elif defined(LOCAL_CREDS)
00815 struct {
00816 struct cmsghdr hdr;
00817 struct sockcred cred;
00818 } cmsg;
00819 #endif
00820
00821 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00822
00823
00824
00825
00826
00827 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
00828 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
00829 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
00830
00831 _dbus_credentials_clear (credentials);
00832
00833
00834
00835
00836
00837
00838
00839 iov.iov_base = &buf;
00840 iov.iov_len = 1;
00841
00842 memset (&msg, 0, sizeof (msg));
00843 msg.msg_iov = &iov;
00844 msg.msg_iovlen = 1;
00845
00846 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
00847 memset (&cmsg, 0, sizeof (cmsg));
00848 msg.msg_control = &cmsg;
00849 msg.msg_controllen = sizeof (cmsg);
00850 #endif
00851
00852 again:
00853 if (recvmsg (client_fd, &msg, 0) < 0)
00854 {
00855 if (errno == EINTR)
00856 goto again;
00857
00858 dbus_set_error (error, _dbus_error_from_errno (errno),
00859 "Failed to read credentials byte: %s",
00860 _dbus_strerror (errno));
00861 return FALSE;
00862 }
00863
00864 if (buf != '\0')
00865 {
00866 dbus_set_error (error, DBUS_ERROR_FAILED,
00867 "Credentials byte was not nul");
00868 return FALSE;
00869 }
00870
00871 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
00872 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
00873 {
00874 dbus_set_error (error, DBUS_ERROR_FAILED,
00875 "Message from recvmsg() was not SCM_CREDS");
00876 return FALSE;
00877 }
00878 #endif
00879
00880 _dbus_verbose ("read credentials byte\n");
00881
00882 {
00883 #ifdef SO_PEERCRED
00884 struct ucred cr;
00885 int cr_len = sizeof (cr);
00886
00887 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
00888 cr_len == sizeof (cr))
00889 {
00890 credentials->pid = cr.pid;
00891 credentials->uid = cr.uid;
00892 credentials->gid = cr.gid;
00893 }
00894 else
00895 {
00896 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
00897 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
00898 }
00899 #elif defined(HAVE_CMSGCRED)
00900 credentials->pid = cmsg.cred.cmcred_pid;
00901 credentials->uid = cmsg.cred.cmcred_euid;
00902 credentials->gid = cmsg.cred.cmcred_groups[0];
00903 #elif defined(LOCAL_CREDS)
00904 credentials->pid = DBUS_PID_UNSET;
00905 credentials->uid = cmsg.cred.sc_uid;
00906 credentials->gid = cmsg.cred.sc_gid;
00907
00908
00909 _dbus_set_local_creds (client_fd, FALSE);
00910 #elif defined(HAVE_GETPEEREID)
00911 uid_t euid;
00912 gid_t egid;
00913 if (getpeereid (client_fd, &euid, &egid) == 0)
00914 {
00915 credentials->uid = euid;
00916 credentials->gid = egid;
00917 }
00918 else
00919 {
00920 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
00921 }
00922 #elif defined(HAVE_GETPEERUCRED)
00923 ucred_t * ucred = NULL;
00924 if (getpeerucred (client_fd, &ucred) == 0)
00925 {
00926 credentials->pid = ucred_getpid (ucred);
00927 credentials->uid = ucred_geteuid (ucred);
00928 credentials->gid = ucred_getegid (ucred);
00929 }
00930 else
00931 {
00932 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
00933 }
00934 if (ucred != NULL)
00935 ucred_free (ucred);
00936 #else
00937 _dbus_verbose ("Socket credentials not supported on this OS\n");
00938 #endif
00939 }
00940
00941 _dbus_verbose ("Credentials:"
00942 " pid "DBUS_PID_FORMAT
00943 " uid "DBUS_UID_FORMAT
00944 " gid "DBUS_GID_FORMAT"\n",
00945 credentials->pid,
00946 credentials->uid,
00947 credentials->gid);
00948
00949 return TRUE;
00950 }
00951
00969 dbus_bool_t
00970 _dbus_send_credentials_unix_socket (int server_fd,
00971 DBusError *error)
00972 {
00973 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00974
00975 if (write_credentials_byte (server_fd, error))
00976 return TRUE;
00977 else
00978 return FALSE;
00979 }
00980
00988 int
00989 _dbus_accept (int listen_fd)
00990 {
00991 int client_fd;
00992 struct sockaddr addr;
00993 socklen_t addrlen;
00994
00995 addrlen = sizeof (addr);
00996
00997 retry:
00998 client_fd = accept (listen_fd, &addr, &addrlen);
00999
01000 if (client_fd < 0)
01001 {
01002 if (errno == EINTR)
01003 goto retry;
01004 }
01005
01006 return client_fd;
01007 }
01008
01017 dbus_bool_t
01018 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01019 {
01020 const char *directory;
01021 struct stat sb;
01022
01023 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01024
01025 directory = _dbus_string_get_const_data (dir);
01026
01027 if (stat (directory, &sb) < 0)
01028 {
01029 dbus_set_error (error, _dbus_error_from_errno (errno),
01030 "%s", _dbus_strerror (errno));
01031
01032 return FALSE;
01033 }
01034
01035 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01036 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01037 {
01038 dbus_set_error (error, DBUS_ERROR_FAILED,
01039 "%s directory is not private to the user", directory);
01040 return FALSE;
01041 }
01042
01043 return TRUE;
01044 }
01045
01046 static dbus_bool_t
01047 fill_user_info_from_passwd (struct passwd *p,
01048 DBusUserInfo *info,
01049 DBusError *error)
01050 {
01051 _dbus_assert (p->pw_name != NULL);
01052 _dbus_assert (p->pw_dir != NULL);
01053
01054 info->uid = p->pw_uid;
01055 info->primary_gid = p->pw_gid;
01056 info->username = _dbus_strdup (p->pw_name);
01057 info->homedir = _dbus_strdup (p->pw_dir);
01058
01059 if (info->username == NULL ||
01060 info->homedir == NULL)
01061 {
01062 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01063 return FALSE;
01064 }
01065
01066 return TRUE;
01067 }
01068
01069 static dbus_bool_t
01070 fill_user_info (DBusUserInfo *info,
01071 dbus_uid_t uid,
01072 const DBusString *username,
01073 DBusError *error)
01074 {
01075 const char *username_c;
01076
01077
01078 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01079 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01080
01081 info->uid = DBUS_UID_UNSET;
01082 info->primary_gid = DBUS_GID_UNSET;
01083 info->group_ids = NULL;
01084 info->n_group_ids = 0;
01085 info->username = NULL;
01086 info->homedir = NULL;
01087
01088 if (username != NULL)
01089 username_c = _dbus_string_get_const_data (username);
01090 else
01091 username_c = NULL;
01092
01093
01094
01095
01096
01097
01098 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01099 {
01100 struct passwd *p;
01101 int result;
01102 char buf[1024];
01103 struct passwd p_str;
01104
01105 p = NULL;
01106 #ifdef HAVE_POSIX_GETPWNAM_R
01107 if (uid != DBUS_UID_UNSET)
01108 result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
01109 &p);
01110 else
01111 result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
01112 &p);
01113 #else
01114 if (uid != DBUS_UID_UNSET)
01115 p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
01116 else
01117 p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
01118 result = 0;
01119 #endif
01120 if (result == 0 && p == &p_str)
01121 {
01122 if (!fill_user_info_from_passwd (p, info, error))
01123 return FALSE;
01124 }
01125 else
01126 {
01127 dbus_set_error (error, _dbus_error_from_errno (errno),
01128 "User \"%s\" unknown or no memory to allocate password entry\n",
01129 username_c ? username_c : "???");
01130 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01131 return FALSE;
01132 }
01133 }
01134 #else
01135 {
01136
01137 struct passwd *p;
01138
01139 if (uid != DBUS_UID_UNSET)
01140 p = getpwuid (uid);
01141 else
01142 p = getpwnam (username_c);
01143
01144 if (p != NULL)
01145 {
01146 if (!fill_user_info_from_passwd (p, info, error))
01147 return FALSE;
01148 }
01149 else
01150 {
01151 dbus_set_error (error, _dbus_error_from_errno (errno),
01152 "User \"%s\" unknown or no memory to allocate password entry\n",
01153 username_c ? username_c : "???");
01154 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
01155 return FALSE;
01156 }
01157 }
01158 #endif
01159
01160
01161 username_c = info->username;
01162
01163 #ifdef HAVE_GETGROUPLIST
01164 {
01165 gid_t *buf;
01166 int buf_count;
01167 int i;
01168
01169 buf_count = 17;
01170 buf = dbus_new (gid_t, buf_count);
01171 if (buf == NULL)
01172 {
01173 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01174 goto failed;
01175 }
01176
01177 if (getgrouplist (username_c,
01178 info->primary_gid,
01179 buf, &buf_count) < 0)
01180 {
01181 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
01182 if (new == NULL)
01183 {
01184 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01185 dbus_free (buf);
01186 goto failed;
01187 }
01188
01189 buf = new;
01190
01191 errno = 0;
01192 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
01193 {
01194 dbus_set_error (error,
01195 _dbus_error_from_errno (errno),
01196 "Failed to get groups for username \"%s\" primary GID "
01197 DBUS_GID_FORMAT ": %s\n",
01198 username_c, info->primary_gid,
01199 _dbus_strerror (errno));
01200 dbus_free (buf);
01201 goto failed;
01202 }
01203 }
01204
01205 info->group_ids = dbus_new (dbus_gid_t, buf_count);
01206 if (info->group_ids == NULL)
01207 {
01208 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01209 dbus_free (buf);
01210 goto failed;
01211 }
01212
01213 for (i = 0; i < buf_count; ++i)
01214 info->group_ids[i] = buf[i];
01215
01216 info->n_group_ids = buf_count;
01217
01218 dbus_free (buf);
01219 }
01220 #else
01221 {
01222
01223 info->group_ids = dbus_new (dbus_gid_t, 1);
01224 if (info->group_ids == NULL)
01225 {
01226 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01227 goto failed;
01228 }
01229
01230 info->n_group_ids = 1;
01231
01232 (info->group_ids)[0] = info->primary_gid;
01233 }
01234 #endif
01235
01236 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01237
01238 return TRUE;
01239
01240 failed:
01241 _DBUS_ASSERT_ERROR_IS_SET (error);
01242 return FALSE;
01243 }
01244
01253 dbus_bool_t
01254 _dbus_user_info_fill (DBusUserInfo *info,
01255 const DBusString *username,
01256 DBusError *error)
01257 {
01258 return fill_user_info (info, DBUS_UID_UNSET,
01259 username, error);
01260 }
01261
01270 dbus_bool_t
01271 _dbus_user_info_fill_uid (DBusUserInfo *info,
01272 dbus_uid_t uid,
01273 DBusError *error)
01274 {
01275 return fill_user_info (info, uid,
01276 NULL, error);
01277 }
01278
01284 void
01285 _dbus_credentials_from_current_process (DBusCredentials *credentials)
01286 {
01287
01288
01289
01290
01291 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
01292 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
01293 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
01294
01295 credentials->pid = getpid ();
01296 credentials->uid = getuid ();
01297 credentials->gid = getgid ();
01298 }
01299
01304 unsigned long
01305 _dbus_getpid (void)
01306 {
01307 return getpid ();
01308 }
01309
01313 dbus_uid_t
01314 _dbus_getuid (void)
01315 {
01316 return getuid ();
01317 }
01318
01319 #ifdef DBUS_BUILD_TESTS
01320
01323 dbus_gid_t
01324 _dbus_getgid (void)
01325 {
01326 return getgid ();
01327 }
01328 #endif
01329
01338 int
01339 _dbus_poll (DBusPollFD *fds,
01340 int n_fds,
01341 int timeout_milliseconds)
01342 {
01343 #ifdef HAVE_POLL
01344
01345
01346
01347
01348 if (_DBUS_POLLIN == POLLIN &&
01349 _DBUS_POLLPRI == POLLPRI &&
01350 _DBUS_POLLOUT == POLLOUT &&
01351 _DBUS_POLLERR == POLLERR &&
01352 _DBUS_POLLHUP == POLLHUP &&
01353 _DBUS_POLLNVAL == POLLNVAL &&
01354 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
01355 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
01356 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
01357 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
01358 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
01359 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
01360 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
01361 {
01362 return poll ((struct pollfd*) fds,
01363 n_fds,
01364 timeout_milliseconds);
01365 }
01366 else
01367 {
01368
01369
01370
01371 _dbus_warn ("didn't implement poll() properly for this system yet\n");
01372 return -1;
01373 }
01374 #else
01375
01376 fd_set read_set, write_set, err_set;
01377 int max_fd = 0;
01378 int i;
01379 struct timeval tv;
01380 int ready;
01381
01382 FD_ZERO (&read_set);
01383 FD_ZERO (&write_set);
01384 FD_ZERO (&err_set);
01385
01386 for (i = 0; i < n_fds; i++)
01387 {
01388 DBusPollFD *fdp = &fds[i];
01389
01390 if (fdp->events & _DBUS_POLLIN)
01391 FD_SET (fdp->fd, &read_set);
01392
01393 if (fdp->events & _DBUS_POLLOUT)
01394 FD_SET (fdp->fd, &write_set);
01395
01396 FD_SET (fdp->fd, &err_set);
01397
01398 max_fd = MAX (max_fd, fdp->fd);
01399 }
01400
01401 tv.tv_sec = timeout_milliseconds / 1000;
01402 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
01403
01404 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
01405 timeout_milliseconds < 0 ? NULL : &tv);
01406
01407 if (ready > 0)
01408 {
01409 for (i = 0; i < n_fds; i++)
01410 {
01411 DBusPollFD *fdp = &fds[i];
01412
01413 fdp->revents = 0;
01414
01415 if (FD_ISSET (fdp->fd, &read_set))
01416 fdp->revents |= _DBUS_POLLIN;
01417
01418 if (FD_ISSET (fdp->fd, &write_set))
01419 fdp->revents |= _DBUS_POLLOUT;
01420
01421 if (FD_ISSET (fdp->fd, &err_set))
01422 fdp->revents |= _DBUS_POLLERR;
01423 }
01424 }
01425
01426 return ready;
01427 #endif
01428 }
01429
01436 void
01437 _dbus_get_current_time (long *tv_sec,
01438 long *tv_usec)
01439 {
01440 struct timeval t;
01441
01442 gettimeofday (&t, NULL);
01443
01444 if (tv_sec)
01445 *tv_sec = t.tv_sec;
01446 if (tv_usec)
01447 *tv_usec = t.tv_usec;
01448 }
01449
01460 dbus_bool_t
01461 _dbus_file_get_contents (DBusString *str,
01462 const DBusString *filename,
01463 DBusError *error)
01464 {
01465 int fd;
01466 struct stat sb;
01467 int orig_len;
01468 int total;
01469 const char *filename_c;
01470
01471 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01472
01473 filename_c = _dbus_string_get_const_data (filename);
01474
01475
01476 fd = open (filename_c, O_RDONLY | O_BINARY);
01477 if (fd < 0)
01478 {
01479 dbus_set_error (error, _dbus_error_from_errno (errno),
01480 "Failed to open \"%s\": %s",
01481 filename_c,
01482 _dbus_strerror (errno));
01483 return FALSE;
01484 }
01485
01486 if (fstat (fd, &sb) < 0)
01487 {
01488 dbus_set_error (error, _dbus_error_from_errno (errno),
01489 "Failed to stat \"%s\": %s",
01490 filename_c,
01491 _dbus_strerror (errno));
01492
01493 _dbus_verbose ("fstat() failed: %s",
01494 _dbus_strerror (errno));
01495
01496 _dbus_close (fd, NULL);
01497
01498 return FALSE;
01499 }
01500
01501 if (sb.st_size > _DBUS_ONE_MEGABYTE)
01502 {
01503 dbus_set_error (error, DBUS_ERROR_FAILED,
01504 "File size %lu of \"%s\" is too large.",
01505 (unsigned long) sb.st_size, filename_c);
01506 _dbus_close (fd, NULL);
01507 return FALSE;
01508 }
01509
01510 total = 0;
01511 orig_len = _dbus_string_get_length (str);
01512 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
01513 {
01514 int bytes_read;
01515
01516 while (total < (int) sb.st_size)
01517 {
01518 bytes_read = _dbus_read (fd, str,
01519 sb.st_size - total);
01520 if (bytes_read <= 0)
01521 {
01522 dbus_set_error (error, _dbus_error_from_errno (errno),
01523 "Error reading \"%s\": %s",
01524 filename_c,
01525 _dbus_strerror (errno));
01526
01527 _dbus_verbose ("read() failed: %s",
01528 _dbus_strerror (errno));
01529
01530 _dbus_close (fd, NULL);
01531 _dbus_string_set_length (str, orig_len);
01532 return FALSE;
01533 }
01534 else
01535 total += bytes_read;
01536 }
01537
01538 _dbus_close (fd, NULL);
01539 return TRUE;
01540 }
01541 else if (sb.st_size != 0)
01542 {
01543 _dbus_verbose ("Can only open regular files at the moment.\n");
01544 dbus_set_error (error, DBUS_ERROR_FAILED,
01545 "\"%s\" is not a regular file",
01546 filename_c);
01547 _dbus_close (fd, NULL);
01548 return FALSE;
01549 }
01550 else
01551 {
01552 _dbus_close (fd, NULL);
01553 return TRUE;
01554 }
01555 }
01556
01566 dbus_bool_t
01567 _dbus_string_save_to_file (const DBusString *str,
01568 const DBusString *filename,
01569 DBusError *error)
01570 {
01571 int fd;
01572 int bytes_to_write;
01573 const char *filename_c;
01574 DBusString tmp_filename;
01575 const char *tmp_filename_c;
01576 int total;
01577 dbus_bool_t need_unlink;
01578 dbus_bool_t retval;
01579
01580 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01581
01582 fd = -1;
01583 retval = FALSE;
01584 need_unlink = FALSE;
01585
01586 if (!_dbus_string_init (&tmp_filename))
01587 {
01588 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01589 return FALSE;
01590 }
01591
01592 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
01593 {
01594 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01595 _dbus_string_free (&tmp_filename);
01596 return FALSE;
01597 }
01598
01599 if (!_dbus_string_append (&tmp_filename, "."))
01600 {
01601 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01602 _dbus_string_free (&tmp_filename);
01603 return FALSE;
01604 }
01605
01606 #define N_TMP_FILENAME_RANDOM_BYTES 8
01607 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
01608 {
01609 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01610 _dbus_string_free (&tmp_filename);
01611 return FALSE;
01612 }
01613
01614 filename_c = _dbus_string_get_const_data (filename);
01615 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
01616
01617 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
01618 0600);
01619 if (fd < 0)
01620 {
01621 dbus_set_error (error, _dbus_error_from_errno (errno),
01622 "Could not create %s: %s", tmp_filename_c,
01623 _dbus_strerror (errno));
01624 goto out;
01625 }
01626
01627 need_unlink = TRUE;
01628
01629 total = 0;
01630 bytes_to_write = _dbus_string_get_length (str);
01631
01632 while (total < bytes_to_write)
01633 {
01634 int bytes_written;
01635
01636 bytes_written = _dbus_write (fd, str, total,
01637 bytes_to_write - total);
01638
01639 if (bytes_written <= 0)
01640 {
01641 dbus_set_error (error, _dbus_error_from_errno (errno),
01642 "Could not write to %s: %s", tmp_filename_c,
01643 _dbus_strerror (errno));
01644
01645 goto out;
01646 }
01647
01648 total += bytes_written;
01649 }
01650
01651 if (!_dbus_close (fd, NULL))
01652 {
01653 dbus_set_error (error, _dbus_error_from_errno (errno),
01654 "Could not close file %s: %s",
01655 tmp_filename_c, _dbus_strerror (errno));
01656
01657 goto out;
01658 }
01659
01660 fd = -1;
01661
01662 if (rename (tmp_filename_c, filename_c) < 0)
01663 {
01664 dbus_set_error (error, _dbus_error_from_errno (errno),
01665 "Could not rename %s to %s: %s",
01666 tmp_filename_c, filename_c,
01667 _dbus_strerror (errno));
01668
01669 goto out;
01670 }
01671
01672 need_unlink = FALSE;
01673
01674 retval = TRUE;
01675
01676 out:
01677
01678
01679
01680
01681 if (fd >= 0)
01682 _dbus_close (fd, NULL);
01683
01684 if (need_unlink && unlink (tmp_filename_c) < 0)
01685 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
01686 tmp_filename_c, _dbus_strerror (errno));
01687
01688 _dbus_string_free (&tmp_filename);
01689
01690 if (!retval)
01691 _DBUS_ASSERT_ERROR_IS_SET (error);
01692
01693 return retval;
01694 }
01695
01702 dbus_bool_t
01703 _dbus_create_file_exclusively (const DBusString *filename,
01704 DBusError *error)
01705 {
01706 int fd;
01707 const char *filename_c;
01708
01709 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01710
01711 filename_c = _dbus_string_get_const_data (filename);
01712
01713 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
01714 0600);
01715 if (fd < 0)
01716 {
01717 dbus_set_error (error,
01718 DBUS_ERROR_FAILED,
01719 "Could not create file %s: %s\n",
01720 filename_c,
01721 _dbus_strerror (errno));
01722 return FALSE;
01723 }
01724
01725 if (!_dbus_close (fd, NULL))
01726 {
01727 dbus_set_error (error,
01728 DBUS_ERROR_FAILED,
01729 "Could not close file %s: %s\n",
01730 filename_c,
01731 _dbus_strerror (errno));
01732 return FALSE;
01733 }
01734
01735 return TRUE;
01736 }
01737
01746 dbus_bool_t
01747 _dbus_delete_file (const DBusString *filename,
01748 DBusError *error)
01749 {
01750 const char *filename_c;
01751
01752 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01753
01754 filename_c = _dbus_string_get_const_data (filename);
01755
01756 if (unlink (filename_c) < 0)
01757 {
01758 dbus_set_error (error, DBUS_ERROR_FAILED,
01759 "Failed to delete file %s: %s\n",
01760 filename_c, _dbus_strerror (errno));
01761 return FALSE;
01762 }
01763 else
01764 return TRUE;
01765 }
01766
01775 dbus_bool_t
01776 _dbus_create_directory (const DBusString *filename,
01777 DBusError *error)
01778 {
01779 const char *filename_c;
01780
01781 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01782
01783 filename_c = _dbus_string_get_const_data (filename);
01784
01785 if (mkdir (filename_c, 0700) < 0)
01786 {
01787 if (errno == EEXIST)
01788 return TRUE;
01789
01790 dbus_set_error (error, DBUS_ERROR_FAILED,
01791 "Failed to create directory %s: %s\n",
01792 filename_c, _dbus_strerror (errno));
01793 return FALSE;
01794 }
01795 else
01796 return TRUE;
01797 }
01798
01809 dbus_bool_t
01810 _dbus_concat_dir_and_file (DBusString *dir,
01811 const DBusString *next_component)
01812 {
01813 dbus_bool_t dir_ends_in_slash;
01814 dbus_bool_t file_starts_with_slash;
01815
01816 if (_dbus_string_get_length (dir) == 0 ||
01817 _dbus_string_get_length (next_component) == 0)
01818 return TRUE;
01819
01820 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
01821 _dbus_string_get_length (dir) - 1);
01822
01823 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
01824
01825 if (dir_ends_in_slash && file_starts_with_slash)
01826 {
01827 _dbus_string_shorten (dir, 1);
01828 }
01829 else if (!(dir_ends_in_slash || file_starts_with_slash))
01830 {
01831 if (!_dbus_string_append_byte (dir, '/'))
01832 return FALSE;
01833 }
01834
01835 return _dbus_string_copy (next_component, 0, dir,
01836 _dbus_string_get_length (dir));
01837 }
01838
01840 #define NANOSECONDS_PER_SECOND 1000000000
01841
01842 #define MICROSECONDS_PER_SECOND 1000000
01843
01844 #define MILLISECONDS_PER_SECOND 1000
01845
01846 #define NANOSECONDS_PER_MILLISECOND 1000000
01847
01848 #define MICROSECONDS_PER_MILLISECOND 1000
01849
01854 void
01855 _dbus_sleep_milliseconds (int milliseconds)
01856 {
01857 #ifdef HAVE_NANOSLEEP
01858 struct timespec req;
01859 struct timespec rem;
01860
01861 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
01862 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
01863 rem.tv_sec = 0;
01864 rem.tv_nsec = 0;
01865
01866 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
01867 req = rem;
01868 #elif defined (HAVE_USLEEP)
01869 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
01870 #else
01871 sleep (MAX (milliseconds / 1000, 1));
01872 #endif
01873 }
01874
01875 static dbus_bool_t
01876 _dbus_generate_pseudorandom_bytes (DBusString *str,
01877 int n_bytes)
01878 {
01879 int old_len;
01880 char *p;
01881
01882 old_len = _dbus_string_get_length (str);
01883
01884 if (!_dbus_string_lengthen (str, n_bytes))
01885 return FALSE;
01886
01887 p = _dbus_string_get_data_len (str, old_len, n_bytes);
01888
01889 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
01890
01891 return TRUE;
01892 }
01893
01902 dbus_bool_t
01903 _dbus_generate_random_bytes (DBusString *str,
01904 int n_bytes)
01905 {
01906 int old_len;
01907 int fd;
01908
01909
01910
01911
01912
01913
01914
01915 old_len = _dbus_string_get_length (str);
01916 fd = -1;
01917
01918
01919 fd = open ("/dev/urandom", O_RDONLY);
01920 if (fd < 0)
01921 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
01922
01923 if (_dbus_read (fd, str, n_bytes) != n_bytes)
01924 {
01925 _dbus_close (fd, NULL);
01926 _dbus_string_set_length (str, old_len);
01927 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
01928 }
01929
01930 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
01931 n_bytes);
01932
01933 _dbus_close (fd, NULL);
01934
01935 return TRUE;
01936 }
01937
01943 void
01944 _dbus_exit (int code)
01945 {
01946 _exit (code);
01947 }
01948
01956 const char*
01957 _dbus_strerror (int error_number)
01958 {
01959 const char *msg;
01960
01961 msg = strerror (error_number);
01962 if (msg == NULL)
01963 msg = "unknown";
01964
01965 return msg;
01966 }
01967
01971 void
01972 _dbus_disable_sigpipe (void)
01973 {
01974 signal (SIGPIPE, SIG_IGN);
01975 }
01976
01984 void
01985 _dbus_fd_set_close_on_exec (int fd)
01986 {
01987 int val;
01988
01989 val = fcntl (fd, F_GETFD, 0);
01990
01991 if (val < 0)
01992 return;
01993
01994 val |= FD_CLOEXEC;
01995
01996 fcntl (fd, F_SETFD, val);
01997 }
01998
02006 dbus_bool_t
02007 _dbus_close (int fd,
02008 DBusError *error)
02009 {
02010 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02011
02012 again:
02013 if (close (fd) < 0)
02014 {
02015 if (errno == EINTR)
02016 goto again;
02017
02018 dbus_set_error (error, _dbus_error_from_errno (errno),
02019 "Could not close fd %d", fd);
02020 return FALSE;
02021 }
02022
02023 return TRUE;
02024 }
02025
02033 dbus_bool_t
02034 _dbus_set_fd_nonblocking (int fd,
02035 DBusError *error)
02036 {
02037 int val;
02038
02039 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02040
02041 val = fcntl (fd, F_GETFL, 0);
02042 if (val < 0)
02043 {
02044 dbus_set_error (error, _dbus_error_from_errno (errno),
02045 "Failed to get flags from file descriptor %d: %s",
02046 fd, _dbus_strerror (errno));
02047 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02048 _dbus_strerror (errno));
02049 return FALSE;
02050 }
02051
02052 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02053 {
02054 dbus_set_error (error, _dbus_error_from_errno (errno),
02055 "Failed to set nonblocking flag of file descriptor %d: %s",
02056 fd, _dbus_strerror (errno));
02057 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02058 fd, _dbus_strerror (errno));
02059
02060 return FALSE;
02061 }
02062
02063 return TRUE;
02064 }
02065
02066 #if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_BUILD_TESTS)
02067
02072 void
02073 _dbus_print_backtrace (void)
02074 {
02075 #if defined (HAVE_BACKTRACE) && defined (DBUS_ENABLE_VERBOSE_MODE)
02076 void *bt[500];
02077 int bt_size;
02078 int i;
02079 char **syms;
02080
02081 bt_size = backtrace (bt, 500);
02082
02083 syms = backtrace_symbols (bt, bt_size);
02084
02085 i = 0;
02086 while (i < bt_size)
02087 {
02088 _dbus_verbose (" %s\n", syms[i]);
02089 ++i;
02090 }
02091
02092 free (syms);
02093 #else
02094 _dbus_verbose (" D-Bus not compiled with backtrace support\n");
02095 #endif
02096 }
02097 #endif
02098
02114 dbus_bool_t
02115 _dbus_full_duplex_pipe (int *fd1,
02116 int *fd2,
02117 dbus_bool_t blocking,
02118 DBusError *error)
02119 {
02120 #ifdef HAVE_SOCKETPAIR
02121 int fds[2];
02122
02123 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02124
02125 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
02126 {
02127 dbus_set_error (error, _dbus_error_from_errno (errno),
02128 "Could not create full-duplex pipe");
02129 return FALSE;
02130 }
02131
02132 if (!blocking &&
02133 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02134 !_dbus_set_fd_nonblocking (fds[1], NULL)))
02135 {
02136 dbus_set_error (error, _dbus_error_from_errno (errno),
02137 "Could not set full-duplex pipe nonblocking");
02138
02139 _dbus_close (fds[0], NULL);
02140 _dbus_close (fds[1], NULL);
02141
02142 return FALSE;
02143 }
02144
02145 *fd1 = fds[0];
02146 *fd2 = fds[1];
02147
02148 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02149 *fd1, *fd2);
02150
02151 return TRUE;
02152 #else
02153 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02154 dbus_set_error (error, DBUS_ERROR_FAILED,
02155 "_dbus_full_duplex_pipe() not implemented on this OS");
02156 return FALSE;
02157 #endif
02158 }
02159
02160
02169 int
02170 _dbus_printf_string_upper_bound (const char *format,
02171 va_list args)
02172 {
02173 char c;
02174 return vsnprintf (&c, 1, format, args);
02175 }
02176
02183 const char*
02184 _dbus_get_tmpdir(void)
02185 {
02186 static const char* tmpdir = NULL;
02187
02188 if (tmpdir == NULL)
02189 {
02190
02191
02192
02193
02194 if (tmpdir == NULL)
02195 tmpdir = getenv("TMPDIR");
02196
02197
02198
02199
02200 if (tmpdir == NULL)
02201 tmpdir = getenv("TMP");
02202 if (tmpdir == NULL)
02203 tmpdir = getenv("TEMP");
02204
02205
02206 if (tmpdir == NULL)
02207 tmpdir = "/tmp";
02208 }
02209
02210 _dbus_assert(tmpdir != NULL);
02211
02212 return tmpdir;
02213 }
02214
02217