From 0ffe7221934623f60e07d3b733d170ce94d26dd5 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 19 May 2009 11:52:33 +0200 Subject: [PATCH] Add g_socket_shutdown --- docs/reference/gio/gio-sections.txt | 1 + gio/gio.symbols | 1 + gio/gsocket.c | 73 +++++++++++++++++++++++++++++ gio/gsocket.h | 4 ++ 4 files changed, 79 insertions(+) diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt index f595a2f2e..581eda6bc 100644 --- a/docs/reference/gio/gio-sections.txt +++ b/docs/reference/gio/gio-sections.txt @@ -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 diff --git a/gio/gio.symbols b/gio/gio.symbols index 454440b7f..6cf24930f 100644 --- a/gio/gio.symbols +++ b/gio/gio.symbols @@ -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 diff --git a/gio/gsocket.c b/gio/gsocket.c index d7e6ea2b6..1201be70c 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -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 diff --git a/gio/gsocket.h b/gio/gsocket.h index 207f1689d..7d5d0d48e 100644 --- a/gio/gsocket.h +++ b/gio/gsocket.h @@ -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,