From ded479fda43da9dbe5780d0a2b287b5b1dcac64e Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 18 Jun 2007 18:05:21 +0000 Subject: 2007-06-18 Havoc Pennington * dbus/dbus-sysdeps-unix.c (_dbus_read_credentials_socket): clean this up a little bit, to try and understand why telnet'ing to a server and sending a non-nul byte didn't disconnect immediately; now it seems that it does disconnect immediately as it should, though I don't understand what has changed. --- dbus/dbus-sysdeps-unix.c | 32 ++++++++++++++++++++++++-------- dbus/dbus-transport-socket.c | 8 +++++++- 2 files changed, 31 insertions(+), 9 deletions(-) (limited to 'dbus') diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index ea8abcff..69abab00 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -991,20 +991,21 @@ _dbus_read_credentials_socket (int client_fd, char buf; dbus_uid_t uid_read; dbus_pid_t pid_read; - + int bytes_read; + uid_read = DBUS_UID_UNSET; pid_read = DBUS_PID_UNSET; #ifdef HAVE_CMSGCRED struct { - struct cmsghdr hdr; - struct cmsgcred cred; + struct cmsghdr hdr; + struct cmsgcred cred; } cmsg; #elif defined(LOCAL_CREDS) struct { - struct cmsghdr hdr; - struct sockcred cred; + struct cmsghdr hdr; + struct sockcred cred; } cmsg; #endif @@ -1040,18 +1041,33 @@ _dbus_read_credentials_socket (int client_fd, #endif again: - if (recvmsg (client_fd, &msg, 0) < 0) + bytes_read = recvmsg (client_fd, &msg, 0); + + if (bytes_read < 0) { if (errno == EINTR) goto again; + /* EAGAIN or EWOULDBLOCK would be unexpected here since we would + * normally only call read_credentials if the socket was ready + * for reading + */ + dbus_set_error (error, _dbus_error_from_errno (errno), "Failed to read credentials byte: %s", _dbus_strerror (errno)); return FALSE; } - - if (buf != '\0') + else if (bytes_read == 0) + { + /* this should not happen unless we are using recvmsg wrong, + * so is essentially here for paranoia + */ + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to read credentials byte (zero-length read)"); + return FALSE; + } + else if (buf != '\0') { dbus_set_error (error, DBUS_ERROR_FAILED, "Credentials byte was not nul"); diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c index 5ef4e8bf..4a713c80 100644 --- a/dbus/dbus-transport-socket.c +++ b/dbus/dbus-transport-socket.c @@ -361,7 +361,13 @@ exchange_credentials (DBusTransport *transport, if (do_reading && transport->receive_credentials_pending) { - /* FIXME this can fail due to IO error _or_ OOM, broken */ + /* FIXME this can fail due to IO error _or_ OOM, broken + * (somewhat tricky to fix since the OOM error can be set after + * we already read the credentials byte, so basically we need to + * separate reading the byte and storing it in the + * transport->credentials). Does not really matter for now + * because storing in credentials never actually fails on unix. + */ if (_dbus_read_credentials_socket (socket_transport->fd, transport->credentials, &error)) -- cgit