$NetBSD: patch-ab,v 1.21 2013/05/26 18:06:04 wiz Exp $ _dbus_poll: Set the timeout value argument to poll to -1 whenever it is less than -1 to avoid kde4 session start hang --- dbus/dbus-sysdeps-unix.c.orig 2013-04-22 14:10:32.000000000 +0000 +++ dbus/dbus-sysdeps-unix.c @@ -22,6 +22,8 @@ * */ +#define _NETBSD_SOURCE + #include #include "dbus-internals.h" @@ -75,6 +77,10 @@ #include #endif +#ifdef __NetBSD__ +#include +#endif + #ifdef HAVE_ADT #include #endif @@ -125,6 +131,32 @@ #endif /* Solaris */ +#ifdef LOCAL_PEEREID +static dbus_bool_t +dbus_nb_getpeereid(int fd, pid_t *pid, uid_t *uid, gid_t *gid) +{ + struct unpcbid cred; + socklen_t len = sizeof(cred); + + _dbus_verbose ("dbus_nb_getpeereid: enter, fd=%d\n"); + if (getsockopt (fd, 0, LOCAL_PEEREID, &cred, &len) < 0) + { + _dbus_verbose ("dbus_nb_getpeereid: getsockopt LOCAL_PEEREID failed: %s\n", strerror(errno)); + return FALSE; + } + if (pid) + *pid = cred.unp_pid; + if (uid) + *uid = cred.unp_euid; + if (gid) + *gid = cred.unp_egid; + + _dbus_verbose ("dbus_nb_getpeereid: returning TRUE, pid=%d uid=%d gid=%d\n", + cred.unp_pid, cred.unp_euid, cred.unp_egid); + return TRUE; +} +#endif + static dbus_bool_t _dbus_open_socket (int *fd_p, int domain, @@ -972,7 +1004,7 @@ _dbus_set_local_creds (int fd, dbus_bool { dbus_bool_t retval = TRUE; -#if defined(HAVE_CMSGCRED) +#if defined(HAVE_CMSGCRED) || defined(LOCAL_PEEREID) /* NOOP just to make sure only one codepath is used * and to prefer CMSGCRED */ @@ -1677,6 +1709,11 @@ _dbus_read_credentials_socket (int char cred[CMSG_SPACE (sizeof (struct cmsgcred))]; } cmsg; +#elif defined(LOCAL_PEEREID) + pid_t sockpid; + uid_t sockuid; + gid_t sockgid; + #elif defined(LOCAL_CREDS) struct { struct cmsghdr hdr; @@ -1712,10 +1749,15 @@ _dbus_read_credentials_socket (int msg.msg_iov = &iov; msg.msg_iovlen = 1; -#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) +#if (defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)) && !defined(LOCAL_PEEREID) _DBUS_ZERO(cmsg); +#ifdef HAVE_CMSGCRED msg.msg_control = (caddr_t) &cmsg; msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred)); +#else /* defined(LOCAL_CREDS) */ + msg.msg_control = &cmsg; + msg.msg_controllen = sizeof (cmsg); +#endif #endif again: @@ -1752,9 +1794,13 @@ _dbus_read_credentials_socket (int return FALSE; } -#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS) +#if (defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)) && !defined(LOCAL_PEEREID) +#ifdef HAVE_CMSGCRED if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred)) || cmsg.hdr.cmsg_type != SCM_CREDS) +#else /* defined(LOCAL_CREDS) */ + if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS) +#endif { dbus_set_error (error, DBUS_ERROR_FAILED, "Message from recvmsg() was not SCM_CREDS"); @@ -1790,6 +1836,16 @@ _dbus_read_credentials_socket (int cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr); pid_read = cred->cmcred_pid; uid_read = cred->cmcred_euid; +#elif defined(LOCAL_PEEREID) + if (dbus_nb_getpeereid(client_fd, &sockpid, &sockuid, &sockgid) == TRUE) + { + pid_read = sockpid; + uid_read = sockuid; + } + else + { + _dbus_verbose ("Failed to dbus_nb_getpeereid() credentials: %s\n", _dbus_strerror (errno)); + } #elif defined(LOCAL_CREDS) pid_read = DBUS_PID_UNSET; uid_read = cmsg.cred.sc_uid; @@ -1851,7 +1907,7 @@ _dbus_read_credentials_socket (int } if (ucred != NULL) ucred_free (ucred); -#else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */ +#else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED && !LOCAL_PEEREID */ _dbus_verbose ("Socket credentials not supported on this OS\n"); #endif } @@ -2528,6 +2584,10 @@ _dbus_poll (DBusPollFD *fds, _DBUS_STRUCT_OFFSET (DBusPollFD, revents) == _DBUS_STRUCT_OFFSET (struct pollfd, revents)) { + if (timeout_milliseconds < -1) { + _dbus_warn("_dbus_poll: timeout = %d (fixed)\n", timeout_milliseconds); + timeout_milliseconds = -1; + } return poll ((struct pollfd*) fds, n_fds, timeout_milliseconds);