Make g_unix_connection_send_fd() work as expected.

https://bugzilla.gnome.org/show_bug.cgi?id=637696
This commit is contained in:
Daiki Ueno 2011-01-11 11:33:21 +09:00 committed by Dan Winship
parent 634e9e43cf
commit c0208940c5
2 changed files with 106 additions and 1 deletions

View File

@ -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;
}

View File

@ -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();