[glib] gsocket: add G_IO_ERROR_CONNECTION_CLOSED



commit 967fedc0ae04fab3162f25715c6d7bde73d22d57
Author: Dan Winship <danw gnome org>
Date:   Fri Aug 19 10:23:12 2011 -0400

    gsocket: add G_IO_ERROR_CONNECTION_CLOSED
    
    Add G_IO_ERROR_CONNECTION_CLOSED as an alias for
    G_IO_ERROR_BROKEN_PIPE, and also return it on ECONNRESET.
    
    It doesn't really make sense to try to distinguish EPIPE and
    ECONNRESET at the GLib level, since the exact choice of which error
    gets returned in what conditions depends on the OS. Given that, we
    ought to map the two errors to the same value, and since we're already
    mapping EPIPE to G_IO_ERROR_BROKEN_PIPE, we need to map ECONNRESET to
    that too. But the existing name doesn't really make sense for sockets,
    so we add a new name.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=728928

 gio/gioenums.h     |   10 ++++++++--
 gio/gioerror.c     |    9 +++++++++
 gio/tests/socket.c |   38 ++++++++++++++++++++++++++++++++------
 3 files changed, 49 insertions(+), 8 deletions(-)
---
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 1ca5be5..90cc9dd 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -470,12 +470,17 @@ 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. Note that this
+ *     is the same code as %G_IO_ERROR_BROKEN_PIPE; before 2.44 some
+ *     "connection closed" errors returned %G_IO_ERROR_BROKEN_PIPE, but others
+ *     returned %G_IO_ERROR_FAILED. Now they should all return the same
+ *     value, which has this more logical name. Since 2.44.
  *
  * Error codes returned by GIO functions.
  *
  * Note that this domain may be extended in future GLib releases. In
  * general, new error codes either only apply to new APIs, or else
- * replace #G_IO_ERROR_FAILED in cases that were not explicitly
+ * replace %G_IO_ERROR_FAILED in cases that were not explicitly
  * distinguished before. You should therefore avoid writing code like
  * |[<!-- language="C" -->
  * if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED))
@@ -532,7 +537,8 @@ typedef enum {
   G_IO_ERROR_PROXY_AUTH_FAILED,
   G_IO_ERROR_PROXY_NEED_AUTH,
   G_IO_ERROR_PROXY_NOT_ALLOWED,
-  G_IO_ERROR_BROKEN_PIPE
+  G_IO_ERROR_BROKEN_PIPE,
+  G_IO_ERROR_CONNECTION_CLOSED = G_IO_ERROR_BROKEN_PIPE
 } GIOErrorEnum;
 
 
diff --git a/gio/gioerror.c b/gio/gioerror.c
index fbae67d..52c9b72 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,9 @@ g_io_error_from_win32_error (gint error_code)
     case WSAEAFNOSUPPORT:
       return G_IO_ERROR_NOT_SUPPORTED;
 
+    case WSAECONNRESET:
+      return G_IO_ERROR_CONNECTION_CLOSED;
+
     default:
       return G_IO_ERROR_FAILED;
     }
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index f4c23f8..fb8821e 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -317,9 +317,23 @@ test_ip_async (GSocketFamily family)
 
   g_thread_join (data->thread);
 
-  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. */
+      len = g_socket_receive_with_blocking (client, buf, sizeof (buf),
+                                           TRUE, NULL, &error);
+      g_assert_no_error (error);
+      g_assert_cmpint (len, ==, 0);
+    }
+  else
+    {
+      /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */
+      len = g_socket_send_with_blocking (client, testbuf, strlen (testbuf) + 1,
+                                        TRUE, NULL, &error);
+      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+      g_assert_cmpint (len, ==, -1);
+      g_clear_error (&error);
+    }
 
   g_socket_close (client, &error);
   g_assert_no_error (error);
@@ -406,9 +420,21 @@ test_ip_sync (GSocketFamily family)
 
   g_thread_join (data->thread);
 
-  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. */
+      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 CONNECTION_CLOSED. */
+      len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
+      g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
+      g_assert_cmpint (len, ==, -1);
+      g_clear_error (&error);
+    }
 
   g_socket_close (client, &error);
   g_assert_no_error (error);


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