From ded479fda43da9dbe5780d0a2b287b5b1dcac64e Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 18 Jun 2007 18:05:21 +0000 Subject: [PATCH] 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. --- ChangeLog | 8 ++++++++ dbus/dbus-sysdeps-unix.c | 32 ++++++++++++++++++++++++-------- dbus/dbus-transport-socket.c | 8 +++++++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1af3af7e..84edb8bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +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. + 2007-06-18 Havoc Pennington * dbus/dbus-watch.c (dbus_watch_get_socket) 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)) -- 2.34.1