[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