[glib/wip/danw/socket2: 3/3] wip
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/danw/socket2: 3/3] wip
- Date: Wed, 1 Oct 2014 14:04:21 +0000 (UTC)
commit c7867d4ae548d221294898e5cf2ce9bba64948f1
Author: Dan Winship <danw gnome org>
Date: Fri Aug 19 10:23:12 2011 -0400
wip
gio/gioenums.h | 1 +
gio/gioerror.c | 11 +++++++++++
gio/gsocket.c | 31 ++++++++++++++-----------------
gio/tests/socket.c | 38 ++++++++++++++++++++++++++++++++------
4 files changed, 58 insertions(+), 23 deletions(-)
---
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 1ca5be5..2d4ce2e 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -470,6 +470,7 @@ typedef enum {
* @G_IO_ERROR_PROXY_NOT_ALLOWED: Proxy connection is not allowed by ruleset.
* Since 2.26
* @G_IO_ERROR_BROKEN_PIPE: Broken pipe. Since 2.36
+ * @G_IO_ERROR_CONNECTION_CLOSED: Connection closed by peer. Since 2.36
*
* Error codes returned by GIO functions.
*
diff --git a/gio/gioerror.c b/gio/gioerror.c
index fbae67d..dbf42d6 100644
--- a/gio/gioerror.c
+++ b/gio/gioerror.c
@@ -242,6 +242,12 @@ g_io_error_from_errno (gint err_no)
break;
#endif
+#ifdef ECONNRESET
+ case ECONNRESET:
+ return G_IO_ERROR_CONNECTION_CLOSED;
+ break;
+#endif
+
default:
return G_IO_ERROR_FAILED;
break;
@@ -305,6 +311,11 @@ g_io_error_from_win32_error (gint error_code)
case WSAEAFNOSUPPORT:
return G_IO_ERROR_NOT_SUPPORTED;
+ case WSAECONNRESET:
+ case WSAECONNABORTED:
+ case WSAECONNSHUTDOWN:
+ return G_IO_ERROR_CONNECTION_CLOSED;
+
default:
return G_IO_ERROR_FAILED;
}
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 16566aa..e4720d7 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -209,7 +209,10 @@ socket_io_error_from_errno (int err)
#ifdef G_OS_WIN32
return g_io_error_from_win32_error (err);
#else
- return g_io_error_from_errno (err);
+ if (err == EPIPE)
+ return G_IO_ERROR_CONNECTION_CLOSED;
+ else
+ return g_io_error_from_errno (err);
#endif
}
@@ -2645,24 +2648,20 @@ g_socket_receive_with_blocking (GSocket *socket,
if ((ret = recv (socket->priv->fd, buffer, size, 0)) < 0)
{
int errsv = get_socket_errno ();
+ GIOErrorEnum gioerr;
if (errsv == EINTR)
continue;
- if (blocking)
- {
-#ifdef WSAEWOULDBLOCK
- if (errsv == WSAEWOULDBLOCK)
- continue;
-#else
- if (errsv == EWOULDBLOCK ||
- errsv == EAGAIN)
- continue;
-#endif
- }
+ gioerr = socket_io_error_from_errno (errsv);
+ if (blocking && gioerr == G_IO_ERROR_WOULD_BLOCK)
+ continue;
win32_unset_event_mask (socket, FD_READ);
+ if (gioerr == G_IO_ERROR_CONNECTION_CLOSED)
+ g_socket_set_connected (socket, FALSE);
+
g_set_error (error, G_IO_ERROR,
socket_io_error_from_errno (errsv),
_("Error receiving data: %s"), socket_strerror (errsv));
@@ -2674,11 +2673,9 @@ g_socket_receive_with_blocking (GSocket *socket,
break;
}
- if (ret == 0 && size != 0 && socket->priv->connected)
- {
- socket->priv->connected = FALSE;
- g_object_notify (G_OBJECT (socket), "connected");
- }
+ if (ret == 0 && size != 0)
+ g_socket_set_connected (socket, FALSE);
+
return ret;
}
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index cb8b8c8..c4bd1e4 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -355,9 +355,20 @@ test_ip_async (GSocketFamily family)
g_thread_join (data->thread);
g_assert_cmpint (data->client_connected_changed, ==, 1);
- len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
- g_assert_no_error (error);
- g_assert_cmpint (len, ==, 0);
+ if (family == G_SOCKET_FAMILY_IPV4)
+ {
+ len = g_socket_receive_with_blocking (client, buf, sizeof (buf),
+ TRUE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (len, ==, 0);
+ }
+ else
+ {
+ len = g_socket_send_with_blocking (client, testbuf, strlen (testbuf) + 1,
+ TRUE, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+ g_assert_cmpint (len, ==, -1);
+ }
g_assert_cmpint (data->client_connected_changed, ==, 2);
g_assert (!g_socket_is_connected (client));
@@ -462,9 +473,24 @@ test_ip_sync (GSocketFamily family)
g_thread_join (data->thread);
g_assert_cmpint (data->client_connected_changed, ==, 1);
- len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
- g_assert_no_error (error);
- g_assert_cmpint (len, ==, 0);
+ if (family == G_SOCKET_FAMILY_IPV4)
+ {
+ /* Test that reading on a remote-closed socket gets back
+ * 0 bytes and emits notify::connected.
+ */
+ len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (len, ==, 0);
+ }
+ else
+ {
+ /* Test that writing to a remote-closed socket gets back
+ * EPIPE and emits notify::connected.
+ */
+ len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+ g_assert_cmpint (len, ==, -1);
+ }
g_assert_cmpint (data->client_connected_changed, ==, 2);
g_assert (!g_socket_is_connected (client));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]