From 1e598600a16d885a3ca859fe951a5bdd198fd6e7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 24 Oct 2012 14:25:01 +0200 Subject: [PATCH] Return correct value for g_socket_get_available_bytes() on Windows and OSX https://bugzilla.gnome.org/show_bug.cgi?id=686786 --- gio/gsocket.c | 15 +++++++++++---- gio/tests/socket.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/gio/gsocket.c b/gio/gsocket.c index 13dff46..1a8ed50 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -2368,7 +2368,10 @@ g_socket_check_connect_result (GSocket *socket, * g_socket_get_available_bytes: * @socket: a #GSocket * - * Get the amount of data pending in the OS input buffer. + * Get the amount of data that can be read from the socket without + * blocking. In the case of datagram sockets this returns the size + * of the first datagram and not the sum of the sizes of all currently + * queued datagrams. * * Returns: the number of bytes that can be read from the socket * without blocking or -1 on error. @@ -2382,15 +2385,19 @@ g_socket_get_available_bytes (GSocket *socket) gulong avail = 0; #else gint avail = 0; + gsize avail_len = sizeof (avail); #endif g_return_val_if_fail (G_IS_SOCKET (socket), -1); -#ifndef G_OS_WIN32 - if (ioctl (socket->priv->fd, FIONREAD, &avail) < 0) +#if defined(G_OS_WIN32) + if (WSAIoctl (socket->priv->fd, FIONREAD, NULL, 0, &avail, sizeof (avail), 0, 0) == SOCKET_ERROR) + return -1; +#elif defined(SO_NREAD) + if (getsockopt (socket->priv->fd, SOL_SOCKET, SO_NREAD, &avail, &avail_len) < 0) return -1; #else - if (ioctlsocket (socket->priv->fd, FIONREAD, &avail) == SOCKET_ERROR) + if (ioctl (socket->priv->fd, FIONREAD, &avail) < 0) return -1; #endif diff --git a/gio/tests/socket.c b/gio/tests/socket.c index e96e792..5ff5c5e 100644 --- a/gio/tests/socket.c +++ b/gio/tests/socket.c @@ -813,6 +813,58 @@ test_unix_connection_ancillary_data (void) } #endif /* G_OS_UNIX */ +static void +test_datagram_get_available (void) +{ + GError *err = NULL; + GSocket *server, *client; + GInetAddress *addr; + GSocketAddress *saddr; + gchar data[] = "0123456789abcdef"; + + server = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (server)); + + client = g_socket_new (G_SOCKET_FAMILY_IPV4, + G_SOCKET_TYPE_DATAGRAM, + G_SOCKET_PROTOCOL_DEFAULT, + &err); + g_assert_no_error (err); + g_assert (G_IS_SOCKET (client)); + + addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4); + saddr = g_inet_socket_address_new (addr, 0); + + g_socket_bind (server, saddr, TRUE, &err); + g_assert_no_error (err); + g_object_unref (saddr); + g_object_unref (addr); + + saddr = g_socket_get_local_address (server, &err); + g_assert_no_error (err); + + g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err); + g_assert_no_error (err); + + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + + g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err); + g_assert_no_error (err); + + g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data)); + + g_socket_close (server, &err); + g_assert_no_error (err); + + g_object_unref (saddr); + g_object_unref (server); + g_object_unref (client); +} + int main (int argc, char *argv[]) @@ -834,6 +886,7 @@ main (int argc, 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 + g_test_add_func ("/socket/datagram_get_available", test_datagram_get_available); return g_test_run(); } -- 2.7.4