Add g_socket_shutdown
authorAlexander Larsson <alexl@redhat.com>
Tue, 19 May 2009 09:52:33 +0000 (11:52 +0200)
committerAlexander Larsson <alexl@redhat.com>
Tue, 19 May 2009 09:52:33 +0000 (11:52 +0200)
docs/reference/gio/gio-sections.txt
gio/gio.symbols
gio/gsocket.c
gio/gsocket.h

index f595a2f2efd16964b984457c2821cee8aa9be645..581eda6bc7d0672951989af26a0b4654765ca7a8 100644 (file)
@@ -1649,6 +1649,7 @@ g_socket_send_to
 g_socket_send_message
 g_socket_close
 g_socket_is_closed
+g_socket_shutdown
 g_socket_is_connected
 g_socket_create_source
 g_socket_condition_check
index 454440b7f2376deaa1c4b2ed0714e17c8a84fee6..6cf24930fc01845ac29f137168341a7c138b5fb4 100644 (file)
@@ -1067,6 +1067,7 @@ g_socket_accept
 g_socket_bind
 g_socket_check_connect_result
 g_socket_close
+g_socket_shutdown
 g_socket_condition_check
 g_socket_condition_wait
 g_socket_connect
index d7e6ea2b60bf87d7508451e2d427a38282335d4e..1201be70cf77bbe783ea3ff0b30b32a205949a9d 100644 (file)
@@ -1838,6 +1838,79 @@ g_socket_send_to (GSocket      *socket,
                                0, error);
 }
 
+/**
+ * g_socket_shutdown:
+ * @socket: a #GSocket
+ * @shutdown_read: whether to shut down the read side
+ * @shutdown_write: whether to shut down the write side
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Shut down part of a full-duplex connection.
+ *
+ * If @shutdown_read is %TRUE then the recieving side of the connection
+ * is shut down, and further reading is disallowed.
+ *
+ * If @shutdown_write is %TRUE then the sending side of the connection
+ * is shut down, and further writing is disallowed.
+ *
+ * It is allowed for both @shutdown_read and @shutdown_write to be %TRUE.
+ *
+ * One example where this is used is graceful disconnect for TCP connections
+ * where you close the sending side, then wait for the other side to close
+ * the connection, thus ensuring that the other side saw all sent data.
+ *
+ * Returns: %TRUE on success, %FALSE on error
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_socket_shutdown (GSocket *socket,
+                  gboolean shutdown_read,
+                  gboolean shutdown_write,
+                  GError **error)
+{
+  int res;
+  int how;
+
+  g_return_val_if_fail (G_IS_SOCKET (socket), TRUE);
+
+  if (!check_socket (socket, NULL))
+    return FALSE;
+
+  /* Do nothing? */
+  if (!shutdown_read && !shutdown_write)
+    return TRUE;
+
+#ifndef G_OS_WIN32
+  if (shutdown_read && shutdown_write)
+    how = SHUT_RDWR;
+  else if (shutdown_read)
+    how = SHUT_RD;
+  else
+    how = SHUT_WR;
+#else
+  if (shutdown_read && shutdown_write)
+    how = SD_BOTH;
+  else if (shutdown_read)
+    how = SD_RECEIVE;
+  else
+    how = SD_SEND;
+#endif
+
+  if (shutdown (socket->priv->fd, how) != 0)
+    {
+      int errsv = get_socket_errno ();
+      g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
+                  _("Unable to create socket: %s"), socket_strerror (errsv));
+      return FALSE;
+    }
+
+  if (shutdown_read && shutdown_write)
+    socket->priv->connected = FALSE;
+
+  return TRUE;
+}
+
 /**
  * g_socket_close:
  * @socket: a #GSocket
index 207f1689dd6f59dedce0eca0b1f0acd09521d473..7d5d0d48ec28a6db4e0bf1e133fc6521be30c633 100644 (file)
@@ -154,6 +154,10 @@ gssize                 g_socket_send_message            (GSocket
                                                         GError                 **error);
 gboolean               g_socket_close                   (GSocket                 *socket,
                                                         GError                 **error);
+gboolean               g_socket_shutdown                (GSocket                 *socket,
+                                                        gboolean                 shutdown_read,
+                                                        gboolean                 shutdown_write,
+                                                        GError                 **error);
 gboolean               g_socket_is_closed               (GSocket                 *socket);
 GSource *              g_socket_create_source           (GSocket                 *socket,
                                                         GIOCondition             condition,