[gnio] Make g_socket_close() return an error



commit 6ebb722eb44576a1fbd73c16101fa8e2ddd5e8c2
Author: Alexander Larsson <alexl redhat com>
Date:   Mon Apr 27 17:17:04 2009 +0200

    Make g_socket_close() return an error
    
    Similar to streams, multiple closes isn't an error. Also, we set
    is_closed even on error (as there isn't much the user can do about it
    other than suck it up).
    Also handles EINTR from close.
---
 gio/gsocket.c           |   40 ++++++++++++++++++++++++++++++++--------
 gio/gsocket.h           |    3 ++-
 gio/gsocketconnection.c |   10 ++++++----
 gio/gsocketconnection.h |    3 ++-
 4 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/gio/gsocket.c b/gio/gsocket.c
index 88f65fe..1577741 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -89,7 +89,7 @@ check_socket (GSocket *socket,
   if (socket->priv->closed)
     {
       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
-                           "Stream is already closed");
+                           "Socket is already closed");
       return FALSE;
     }
   return TRUE;
@@ -363,7 +363,7 @@ g_socket_finalize (GObject *object)
 
   if (socket->priv->fd != -1 &&
       !socket->priv->closed)
-    g_socket_close (socket);
+    g_socket_close (socket, NULL);
 
   if (G_OBJECT_CLASS (g_socket_parent_class)->finalize)
     (*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object);
@@ -778,21 +778,45 @@ g_socket_send (GSocket      *socket,
   return ret;
 }
 
-void
-g_socket_close (GSocket *socket)
+gboolean
+g_socket_close (GSocket *socket,
+		GError **error)
 {
-  g_return_if_fail (G_IS_SOCKET (socket));
+  int res;
+
+  g_return_val_if_fail (G_IS_SOCKET (socket), TRUE);
 
   if (socket->priv->closed)
-    return;
+    return TRUE; /* Multiple close not an error */
 
+  if (!check_socket (socket, NULL))
+    return FALSE;
+
+  while (1)
+    {
 #ifdef G_OS_WIN32
-  closesocket (socket->priv->fd);
+      res = closesocket (socket->priv->fd);
 #else
-  close (socket->priv->fd);
+      res = close (socket->priv->fd);
 #endif
+      if (res == -1)
+	{
+	  int errsv = errno;
+
+	  if (errsv == EINTR)
+	    continue;
+
+	  g_set_error (error, G_IO_ERROR,
+		       g_io_error_from_errno (errsv),
+		       "Error closing sockete: %s",
+		       g_strerror (errsv));
+	}
+      break;
+    }
 
   socket->priv->closed = TRUE;
+
+  return res != -1;
 }
 
 GSource *
diff --git a/gio/gsocket.h b/gio/gsocket.h
index 51bb14d..a9a7837 100644
--- a/gio/gsocket.h
+++ b/gio/gsocket.h
@@ -170,7 +170,8 @@ gssize                  g_socket_send_message                           (GSocket
                                                                          gint                     flags,
                                                                          GError                 **error);
 
-void                    g_socket_close                                  (GSocket                 *socket);
+gboolean                g_socket_close                                  (GSocket                 *socket,
+                                                                         GError                 **error);
 
 GSource *               g_socket_create_source                          (GSocket                 *socket,
                                                                          GIOCondition             condition,
diff --git a/gio/gsocketconnection.c b/gio/gsocketconnection.c
index 729c246..bbdd3fb 100644
--- a/gio/gsocketconnection.c
+++ b/gio/gsocketconnection.c
@@ -177,12 +177,14 @@ g_socket_connection_init (GSocketConnection *connection)
                                                   GSocketConnectionPrivate);
 }
 
-void
-g_socket_connection_close (GSocketConnection *connection)
+gboolean
+g_socket_connection_close (GSocketConnection *connection,
+			   GError **error)
 {
-  g_return_if_fail (G_IS_SOCKET_CONNECTION (connection));
+  g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), TRUE);
 
-  g_socket_close (connection->priv->socket);
+  return g_socket_close (connection->priv->socket,
+			 error);
 }
 
 static void
diff --git a/gio/gsocketconnection.h b/gio/gsocketconnection.h
index dc2512c..40ed737 100644
--- a/gio/gsocketconnection.h
+++ b/gio/gsocketconnection.h
@@ -54,7 +54,8 @@ struct _GSocketConnection
 
 GType                   g_socket_connection_get_type                    (void);
 
-void                    g_socket_connection_close                       (GSocketConnection *connection);
+gboolean                g_socket_connection_close                       (GSocketConnection *connection,
+									 GError **error);
 
 G_END_DECLS
 



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