[glib] Make g_unix_connection_send_fd() work as expected.



commit c0208940c569b2d2a7e0e86f93d97cfbaf2b3fc7
Author: Daiki Ueno <ueno unixuser org>
Date:   Tue Jan 11 11:33:21 2011 +0900

    Make g_unix_connection_send_fd() work as expected.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=637696

 gio/gunixfdmessage.c |    2 +-
 gio/tests/socket.c   |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+), 1 deletions(-)
---
diff --git a/gio/gunixfdmessage.c b/gio/gunixfdmessage.c
index aaf749b..21e52e3 100644
--- a/gio/gunixfdmessage.c
+++ b/gio/gunixfdmessage.c
@@ -318,5 +318,5 @@ g_unix_fd_message_append_fd (GUnixFDMessage  *message,
 {
   g_return_val_if_fail (G_UNIX_FD_MESSAGE (message), FALSE);
 
-  return g_unix_fd_list_append (message->priv->list, fd, error) > 0;
+  return g_unix_fd_list_append (message->priv->list, fd, error) >= 0;
 }
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index 9c4c0d6..00e9598 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -23,8 +23,12 @@
 #include <gio/gio.h>
 
 #ifdef G_OS_UNIX
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/wait.h>
+#include <string.h>
+#include <stdlib.h>
 #include <gio/gunixconnection.h>
 #endif
 
@@ -67,6 +71,106 @@ test_unix_connection (void)
   g_object_unref (c);
   g_object_unref (s);
 }
+
+static GSocketConnection *
+create_connection_for_fd (int fd)
+{
+  GError *err = NULL;
+  GSocket *socket;
+  GSocketConnection *connection;
+
+  socket = g_socket_new_from_fd (fd, &err);
+  g_assert_no_error (err);
+  g_assert (G_IS_SOCKET (socket));
+  connection = g_socket_connection_factory_create_connection (socket);
+  g_assert (G_IS_UNIX_CONNECTION (connection));
+  g_object_unref (socket);
+  return connection;
+}
+
+#define TEST_DATA "failure to say failure to say 'i love gnome-panel!'."
+
+static void
+test_unix_connection_ancillary_data (void)
+{
+  GError *err = NULL;
+  gint pv[2], sv[3];
+  gint status, fd, len;
+  char buffer[1024];
+  pid_t pid;
+
+  status = pipe (pv);
+  g_assert_cmpint (status, ==, 0);
+
+  status = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
+  g_assert_cmpint (status, ==, 0);
+
+  pid = fork ();
+  g_assert_cmpint (pid, >=, 0);
+
+  /* Child: close its copy of the write end of the pipe, receive it
+   * again from the parent over the socket, and write some text to it.
+   *
+   * Parent: send the write end of the pipe (still open for the
+   * parent) over the socket, close it, and read some text from the
+   * read end of the pipe.
+   */
+  if (pid == 0)
+    {
+      GSocketConnection *connection;
+
+      close (sv[1]);
+      connection = create_connection_for_fd (sv[0]);
+
+      status = close (pv[1]);
+      g_assert_cmpint (status, ==, 0);
+
+      err = NULL;
+      fd = g_unix_connection_receive_fd (G_UNIX_CONNECTION (connection), NULL,
+					 &err);
+      g_assert_no_error (err);
+      g_assert_cmpint (fd, >, -1);
+      g_object_unref (connection);
+
+      do
+	len = write (fd, TEST_DATA, sizeof (TEST_DATA));
+      while (len == -1 && errno == EINTR);
+      g_assert_cmpint (len, ==, sizeof (TEST_DATA));
+      exit (0);
+    }
+  else
+    {
+      GSocketConnection *connection;
+
+      close (sv[0]);
+      connection = create_connection_for_fd (sv[1]);
+
+      err = NULL;
+      g_unix_connection_send_fd (G_UNIX_CONNECTION (connection), pv[1], NULL,
+				 &err);
+      g_assert_no_error (err);
+      g_object_unref (connection);
+
+      status = close (pv[1]);
+      g_assert_cmpint (status, ==, 0);
+
+      memset (buffer, 0xff, sizeof buffer);
+      do
+	len = read (pv[0], buffer, sizeof buffer);
+      while (len == -1 && errno == EINTR);
+
+      g_assert_cmpint (len, ==, sizeof (TEST_DATA));
+      g_assert_cmpstr (buffer, ==, TEST_DATA);
+
+      waitpid (pid, &status, 0);
+      g_assert (WIFEXITED (status));
+      g_assert_cmpint (WEXITSTATUS (status), ==, 0);
+    }
+
+  /* TODO: add test for g_unix_connection_send_credentials() and
+   * g_unix_connection_receive_credentials().
+   */
+}
 #endif /* G_OS_UNIX */
 
 int
@@ -79,6 +183,7 @@ main (int   argc,
 #ifdef G_OS_UNIX
   g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
   g_test_add_func ("/socket/unix-connection", test_unix_connection);
+  g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
 #endif
 
   return g_test_run();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]