2007-06-18 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Mon, 18 Jun 2007 18:05:21 +0000 (18:05 +0000)
committerHavoc Pennington <hp@redhat.com>
Mon, 18 Jun 2007 18:05:21 +0000 (18:05 +0000)
* 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
dbus/dbus-sysdeps-unix.c
dbus/dbus-transport-socket.c

index 1af3af7e12142fab0cef9a80fb06feb1dd56570d..84edb8bfd83c79740615cf75eea11c4ec96ef5cf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-06-18  Havoc Pennington  <hp@redhat.com>
+       
+       * 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  <hp@redhat.com>
 
        * dbus/dbus-watch.c (dbus_watch_get_socket)
index ea8abcff91e55860019aa3c01400bcac7526c118..69abab004ea7670c6af69cb539bef65c5a81440b 100644 (file)
@@ -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");
index 5ef4e8bf6f1f68e403ad470b3726af17a79d4c79..4a713c80e1eecbbb698b3691a8a43fb0724fa12f 100644 (file)
@@ -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))