[PATCH] Move Unix FD passing into the header

Christian Dywan christian.dywan at lanedo.com
Tue Jun 15 09:07:09 PDT 2010


---
 bus/dispatch.c           |   22 +++---
 dbus/dbus-message-util.c |   12 ++-
 dbus/dbus-message.c      |  170 +++++++++++++++++++++++++---------------------
 dbus/dbus-message.h      |    8 ++
 dbus/dbus-signature.c    |    2 +-
 5 files changed, 120 insertions(+), 94 deletions(-)

diff --git a/bus/dispatch.c b/bus/dispatch.c
index cd3f2a2..0b46156 100644
--- a/bus/dispatch.c
+++ b/bus/dispatch.c
@@ -4822,12 +4822,11 @@ bus_unix_fds_passing_test(const DBusString *test_data_dir)
   if (!(_dbus_full_duplex_pipe(two, two+1, TRUE, &error)))
     _dbus_assert_not_reached("Failed to allocate pipe #2");
 
-  if (!dbus_message_append_args(m,
-                                DBUS_TYPE_UNIX_FD, one,
-                                DBUS_TYPE_UNIX_FD, two,
-                                DBUS_TYPE_UNIX_FD, two,
-                                DBUS_TYPE_INVALID))
+  if (! (dbus_message_append_unix_fd (m, one[0])
+      && dbus_message_append_unix_fd (m, two[0])
+      && dbus_message_append_unix_fd (m, two[0])))
     _dbus_assert_not_reached("Failed to attach fds.");
+  _dbus_assert (dbus_message_get_n_unix_fds (m) == 3);
 
   if (!_dbus_close(one[0], &error))
     _dbus_assert_not_reached("Failed to close pipe #1 ");
@@ -4867,13 +4866,12 @@ bus_unix_fds_passing_test(const DBusString *test_data_dir)
   if (!dbus_message_is_signal(m, "a.b.c", "d"))
     _dbus_assert_not_reached("bogus message received");
 
-  if (!dbus_message_get_args(m,
-                             &error,
-                             DBUS_TYPE_UNIX_FD, &x,
-                             DBUS_TYPE_UNIX_FD, &y,
-                             DBUS_TYPE_UNIX_FD, &z,
-                             DBUS_TYPE_INVALID))
-    _dbus_assert_not_reached("Failed to parse fds.");
+  x = dbus_message_get_unix_fd (m, 0);
+  y = dbus_message_get_unix_fd (m, 1);
+  z = dbus_message_get_unix_fd (m, 2);
+
+  if (x < 0 || y < 0 || z < 0)
+    _dbus_assert_not_reached ("Failed to parse fds.");
 
   dbus_message_unref(m);
 
diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c
index 94219f6..802a1b9 100644
--- a/dbus/dbus-message-util.c
+++ b/dbus/dbus-message-util.c
@@ -1192,10 +1192,7 @@ _dbus_message_test (const char *test_data_dir)
   message_without_unix_fds = dbus_message_copy(message);
   _dbus_assert(message_without_unix_fds);
 #ifdef HAVE_UNIX_FD_PASSING
-  dbus_message_append_args (message,
-                            DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
-			    DBUS_TYPE_INVALID);
-  sig[i++] = DBUS_TYPE_UNIX_FD;
+  dbus_message_append_unix_fd (message, v_UNIX_FD);
 #endif
   sig[i++] = DBUS_TYPE_INVALID;
 
@@ -1278,6 +1275,7 @@ _dbus_message_test (const char *test_data_dir)
   {
     int *unix_fds;
     unsigned n_unix_fds;
+    int fd0;
     /* Write unix fd */
     _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds);
     _dbus_assert(n_unix_fds > 0);
@@ -1285,6 +1283,12 @@ _dbus_message_test (const char *test_data_dir)
     unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL);
     _dbus_assert(unix_fds[0] >= 0);
     _dbus_message_loader_return_unix_fds(loader, unix_fds, 1);
+    /* Use public API this time */
+    _dbus_assert (dbus_message_contains_unix_fds (message));
+    _dbus_assert (dbus_message_get_n_unix_fds (message) == 1);
+    fd0 = dbus_message_get_unix_fd (message, 0);
+    _dbus_assert (fd0 > -1);
+    _dbus_close (fd0, NULL);
   }
 #endif
 
diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c
index b19697e..b3aa647 100644
--- a/dbus/dbus-message.c
+++ b/dbus/dbus-message.c
@@ -748,39 +748,7 @@ _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
 
           goto out;
 	}
-
-      if (spec_type == DBUS_TYPE_UNIX_FD)
-        {
-#ifdef HAVE_UNIX_FD_PASSING
-          DBusBasicValue idx;
-          int *pfd, nfd;
-
-          pfd = va_arg (var_args, int*);
-          _dbus_assert(pfd);
-
-          _dbus_type_reader_read_basic(&real->u.reader, &idx);
-
-          if (idx.u32 >= real->message->n_unix_fds)
-            {
-              dbus_set_error (error, DBUS_ERROR_INCONSISTENT_MESSAGE,
-                              "Message refers to file descriptor at index %i,"
-                              "but has only %i descriptors attached.\n",
-                              idx.u32,
-                              real->message->n_unix_fds);
-              goto out;
-            }
-
-          if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
-            goto out;
-
-          *pfd = nfd;
-#else
-          dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
-                          "Platform does not support file desciptor passing.\n");
-          goto out;
-#endif
-        }
-      else if (dbus_type_is_basic (spec_type))
+      if (dbus_type_is_basic (spec_type))
         {
           DBusBasicValue *ptr;
 
@@ -2518,50 +2486,7 @@ dbus_message_iter_append_basic (DBusMessageIter *iter,
   if (!_dbus_message_iter_open_signature (real))
     return FALSE;
 
-  if (type == DBUS_TYPE_UNIX_FD)
-    {
-#ifdef HAVE_UNIX_FD_PASSING
-      int *fds;
-      dbus_uint32_t u;
-
-      /* First step, include the fd in the fd list of this message */
-      if (!(fds = expand_fd_array(real->message, 1)))
-        return FALSE;
-
-      *fds = _dbus_dup(*(int*) value, NULL);
-      if (*fds < 0)
-        return FALSE;
-
-      u = real->message->n_unix_fds;
-
-      /* Second step, write the index to the fd */
-      if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
-        _dbus_close(*fds, NULL);
-        return FALSE;
-      }
-
-      real->message->n_unix_fds += 1;
-      u += 1;
-
-      /* Final step, update the header accordingly */
-      ret = _dbus_header_set_field_basic (&real->message->header,
-                                          DBUS_HEADER_FIELD_UNIX_FDS,
-                                          DBUS_TYPE_UINT32,
-                                          &u);
-
-      /* If any of these operations fail the message is
-         hosed. However, no memory or fds should be leaked since what
-         has been added to message has been added to the message, and
-         can hence be accounted for when the message is being
-         freed. */
-#else
-      ret = FALSE;
-#endif
-    }
-  else
-    {
-      ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
-    }
+  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
 
   if (!_dbus_message_iter_close_signature (real))
     ret = FALSE;
@@ -3622,6 +3547,51 @@ dbus_set_error_from_message (DBusError   *error,
 }
 
 /**
+ * Appends a file descriptor to the message. The
+ * descriptor can later be looked up by its index
+ * in insertion order with dbus_message_get_unix_fd().
+ *
+ * @param message the message
+ * @param fd a unix file descriptor
+ * @returns #TRUE if the message contains unix fds
+ */
+dbus_bool_t
+dbus_message_append_unix_fd (DBusMessage *message,
+                             int          fd)
+{
+  _dbus_assert (message != NULL);
+  _dbus_assert (fd > -1);
+
+#ifdef HAVE_UNIX_FD_PASSING
+  {
+    int *fds;
+    dbus_uint32_t u;
+
+    if (!(fds = expand_fd_array (message, 1)))
+      return FALSE;
+
+    *fds = _dbus_dup (fd, NULL);
+    if (*fds < 0)
+      return FALSE;
+
+    message->n_unix_fds += 1;
+    u = message->n_unix_fds;
+    return _dbus_header_set_field_basic (&message->header,
+                                         DBUS_HEADER_FIELD_UNIX_FDS,
+                                         DBUS_TYPE_UINT32,
+                                         &u);
+
+    /* If any of these operations fail the message is
+       hosed. However, no memory or fds should be leaked since what
+       has been added to message has been added to the message, and
+       can hence be accounted for when the message is being
+       freed. */
+  }
+#endif
+  return FALSE;
+}
+
+/**
  * Checks whether a message contains unix fds
  *
  * @param message the message
@@ -3639,6 +3609,52 @@ dbus_message_contains_unix_fds(DBusMessage *message)
 #endif
 }
 
+/**
+ * Determines the number of unix fds in the message
+ *
+ * @param message the message
+ * @returns the number of unix fds
+ */
+int
+dbus_message_get_n_unix_fds(DBusMessage *message)
+{
+#ifdef HAVE_UNIX_FD_PASSING
+  _dbus_assert(message);
+
+  return message->n_unix_fds;
+#else
+  return 0;
+#endif
+}
+
+/**
+ * Obtains a unix fd from the message by its index. It is
+ * an error to lookup non-existing file descriptors.
+ *
+ * The unix fd is duplicated, it must be closed by the caller.
+ *
+ * @param message the message
+ * @param index the index of a file descriptor
+ * @returns a unix file descriptior
+ */
+int
+dbus_message_get_unix_fd (DBusMessage *message,
+                          int          index)
+{
+  _dbus_assert (message);
+  _dbus_assert (index > -1);
+
+#ifdef HAVE_UNIX_FD_PASSING
+  _dbus_assert (message->n_unix_fds > 0);
+  _dbus_assert (message->unix_fds != NULL);
+  _dbus_assert (index < message->n_unix_fds);
+
+  return _dbus_dup (message->unix_fds[index], NULL);
+#else
+  return -1;
+#endif
+}
+
 /** @} */
 
 /**
diff --git a/dbus/dbus-message.h b/dbus/dbus-message.h
index 5500492..9bbeb42 100644
--- a/dbus/dbus-message.h
+++ b/dbus/dbus-message.h
@@ -205,7 +205,15 @@ dbus_bool_t dbus_message_get_args_valist      (DBusMessage     *message,
 					       va_list          var_args);
 
 DBUS_EXPORT
+dbus_bool_t dbus_message_append_unix_fd       (DBusMessage *message,
+                                               int          fd);
+DBUS_EXPORT
 dbus_bool_t dbus_message_contains_unix_fds    (DBusMessage *message);
+DBUS_EXPORT
+int         dbus_message_get_n_unix_fds       (DBusMessage *message);
+DBUS_EXPORT
+int         dbus_message_get_unix_fd          (DBusMessage *message,
+                                               int          index);
 
 DBUS_EXPORT
 dbus_bool_t dbus_message_iter_init             (DBusMessage     *message,
diff --git a/dbus/dbus-signature.c b/dbus/dbus-signature.c
index ddc0bcc..a223740 100644
--- a/dbus/dbus-signature.c
+++ b/dbus/dbus-signature.c
@@ -318,7 +318,7 @@ dbus_type_is_basic (int typecode)
 			    FALSE);
 
   /* everything that isn't invalid or a container */
-  return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode));
+  return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode) || typecode == DBUS_TYPE_UNIX_FD);
 }
 
 /**
-- 
1.7.1


--MP_//V3kHCGpI6uzy3hbOTZB0FM--


More information about the dbus mailing list