[gnio] Handle EINTR where it can happend and auto restart



commit 3a9da67aea429717a2e103e8aaa8b31192f2e1df
Author: Alexander Larsson <alexl redhat com>
Date:   Mon Apr 27 21:24:02 2009 +0200

    Handle EINTR where it can happend and auto restart
---
 gio/gsocket.c |  166 +++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 110 insertions(+), 56 deletions(-)

diff --git a/gio/gsocket.c b/gio/gsocket.c
index 1577741..df8e4ef 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -111,21 +111,21 @@ g_socket_details_from_fd (GSocket *socket)
 
   if G_UNLIKELY (result < 0)
     {
-      gint saved_errno = errno;
+      gint errsv = errno;
 
-      switch (saved_errno)
+      switch (errsv)
         {
          case ENOTSOCK:
          case EBADF:
           /* programmer error */
           g_error ("creating GSocket from fd %d: %s\n",
-                   fd, g_strerror (saved_errno));
+                   fd, g_strerror (errsv));
 
          default:
           g_set_error (&socket->priv->construct_error, G_IO_ERROR,
-                       g_io_error_from_errno (saved_errno),
+                       g_io_error_from_errno (errsv),
                        "creating GSocket from fd: %s",
-                       g_strerror (saved_errno));
+                       g_strerror (errsv));
         }
 
       return;
@@ -156,12 +156,12 @@ g_socket_details_from_fd (GSocket *socket)
 
   if G_UNLIKELY (result < 0)
     {
-      gint saved_errno = errno;
+      gint errsv = errno;
 
       g_set_error (&socket->priv->construct_error, G_IO_ERROR,
-                   g_io_error_from_errno (saved_errno),
+                   g_io_error_from_errno (errsv),
                    "creating GSocket from fd: %s",
-                   g_strerror (saved_errno));
+                   g_strerror (errsv));
 
       return;
     }
@@ -197,11 +197,11 @@ g_socket_details_from_fd (GSocket *socket)
 
   if G_UNLIKELY (result < 0)
     {
-      gint saved_errno = errno;
+      gint errsv = errno;
 
       g_error ("fcntl failed while constructing a GSocket from fd (%s).  "
                "This is really quite unexpected.  Please file a bug.",
-               g_strerror (saved_errno));
+               g_strerror (errsv));
     }
 
   socket->priv->blocking = !(result & O_NONBLOCK);
@@ -243,10 +243,10 @@ g_socket_create_socket (GSocketFamily   family,
 
   if (fd < 0)
     {
-      gint saved_errno = errno;
+      gint errsv = errno;
 
-      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (saved_errno),
-                   "unable to create socket: %s", g_strerror (saved_errno));
+      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+                   "unable to create socket: %s", g_strerror (errsv));
     }
 
   return fd;
@@ -633,7 +633,10 @@ g_socket_listen (GSocket  *socket,
 
   if (listen (socket->priv->fd, socket->priv->backlog) < 0)
     {
-      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), "could not listen: %s", g_strerror (errno));
+      int errsv = errno;
+
+      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+		   "could not listen: %s", g_strerror (errsv));
       return FALSE;
     }
 
@@ -683,12 +686,21 @@ g_socket_accept (GSocket       *socket,
   if (!check_socket (socket, error))
     return NULL;
 
-  if ((ret = accept (socket->priv->fd, NULL, 0)) < 0)
+  while (1)
     {
-      g_set_error (error, G_IO_ERROR,
-		   g_io_error_from_errno (errno),
-		   "error accepting connection: %s", g_strerror (errno));
-      return NULL;
+      if ((ret = accept (socket->priv->fd, NULL, 0)) < 0)
+	{
+	  int errsv = errno;
+
+	  if (errsv == EINTR)
+	    continue;
+
+	  g_set_error (error, G_IO_ERROR,
+		       g_io_error_from_errno (errsv),
+		       "error accepting connection: %s", g_strerror (errsv));
+	  return NULL;
+	}
+      break;
     }
 
   return g_socket_new_from_fd (ret);
@@ -708,21 +720,31 @@ g_socket_connect (GSocket         *socket,
 
   g_socket_address_to_native (address, buffer, sizeof buffer);
 
-  if (connect (socket->priv->fd, (struct sockaddr *) buffer, g_socket_address_get_native_size (address)) < 0)
+  while (1)
     {
+      if (connect (socket->priv->fd, (struct sockaddr *) buffer,
+		   g_socket_address_get_native_size (address)) < 0)
+	{
+	  int errsv = errno;
+
+	  if (errsv == EINTR)
+	    continue;
+
 #ifndef G_OS_WIN32
-      if (errno == EINPROGRESS)
+	  if (errsv == EINPROGRESS)
 #else
-      if (errno == WSAEINPROGRESS)
+	    if (errsv == WSAEINPROGRESS)
 #endif
-	g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
-		     "connection in progress");
-      else
-	g_set_error (error, G_IO_ERROR,
-		     g_io_error_from_errno (errno),
-		     "error connecting: %s", g_strerror (errno));
-
-      return FALSE;
+	      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
+			   "connection in progress");
+	    else
+	      g_set_error (error, G_IO_ERROR,
+			   g_io_error_from_errno (errsv),
+			   "error connecting: %s", g_strerror (errsv));
+
+	  return FALSE;
+	}
+      break;
     }
 
   socket->priv->remote_address = g_object_ref_sink (address);
@@ -743,12 +765,21 @@ g_socket_receive (GSocket       *socket,
   if (!check_socket (socket, error))
     return -1;
 
-  if ((ret = recv (socket->priv->fd, buffer, size, 0)) < 0)
+  while (1)
     {
-      g_set_error (error, G_IO_ERROR,
-		   g_io_error_from_errno (errno),
-		   "error receiving data: %s", g_strerror (errno));
-      return -1;
+      if ((ret = recv (socket->priv->fd, buffer, size, 0)) < 0)
+	{
+	  int errsv = errno;
+
+	  if (errsv == EINTR)
+	    continue;
+
+	  g_set_error (error, G_IO_ERROR,
+		       g_io_error_from_errno (errsv),
+		       "error receiving data: %s", g_strerror (errsv));
+	  return -1;
+	}
+      break;
     }
 
   return ret;
@@ -767,12 +798,21 @@ g_socket_send (GSocket      *socket,
   if (!check_socket (socket, error))
     return -1;
 
-  if ((ret = send (socket->priv->fd, buffer, size, 0)) < 0)
+  while (1)
     {
-      g_set_error (error, G_IO_ERROR,
-		   g_io_error_from_errno (errno),
-		   "error sending data: %s", g_strerror (errno));
-      return -1;
+      if ((ret = send (socket->priv->fd, buffer, size, 0)) < 0)
+	{
+	  int errsv = errno;
+
+	  if (errsv == EINTR)
+	    continue;
+
+	  g_set_error (error, G_IO_ERROR,
+		       g_io_error_from_errno (errsv),
+		       "error sending data: %s", g_strerror (errsv));
+	  return -1;
+	}
+      break;
     }
 
   return ret;
@@ -1004,17 +1044,24 @@ g_socket_send_message (GSocket                *socket,
     g_assert (cmsg == NULL);
   }
 
-  result = sendmsg (socket->priv->fd, &msg, flags);
-
-  if (result < 0)
+  while (1)
     {
-      gint saved_errno = errno;
+      result = sendmsg (socket->priv->fd, &msg, flags);
+
+      if (result < 0)
+	{
+	  gint errsv = errno;
+
+	  if (errsv == EINTR)
+	    continue;
 
-      g_set_error (error, G_IO_ERROR,
-                   g_io_error_from_errno (saved_errno),
-                   "sendmsg: %s", g_strerror (saved_errno));
+	  g_set_error (error, G_IO_ERROR,
+		       g_io_error_from_errno (errsv),
+		       "sendmsg: %s", g_strerror (errsv));
 
-      return -1;
+	  return -1;
+	}
+      break;
     }
 
   return result;
@@ -1158,17 +1205,24 @@ g_socket_receive_message (GSocket                 *socket,
   }
 
   /* do it */
-  result = recvmsg (socket->priv->fd, &msg, msg.msg_flags);
-
-  if (result < 0)
+  while (1)
     {
-      gint saved_errno = errno;
+      result = recvmsg (socket->priv->fd, &msg, msg.msg_flags);
 
-      g_set_error (error, G_IO_ERROR,
-                   g_io_error_from_errno (saved_errno),
-                   "recvmsg: %s", g_strerror (saved_errno));
+      if (result < 0)
+	{
+	  gint errsv = errno;
 
-      return -1;
+	  if (errsv == EINTR)
+	    continue;
+
+	  g_set_error (error, G_IO_ERROR,
+		       g_io_error_from_errno (errsv),
+		       "recvmsg: %s", g_strerror (errsv));
+
+	  return -1;
+	}
+      break;
     }
 
   /* decode address */



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