1
0
mirror of https://gitlab.gnome.org/GNOME/glib.git synced 2025-07-23 18:37:50 +02:00
Files
.gitlab-ci
docs
fuzzing
gio
completion
fam
gdbus-2.0
gvdb
inotify
kqueue
tests
win32
xdgmime
data-to-c.py
dbus-daemon.xml
gaction.c
gaction.h
gactiongroup.c
gactiongroup.h
gactiongroupexporter.c
gactiongroupexporter.h
gactionmap.c
gactionmap.h
gappinfo.c
gappinfo.h
gappinfoprivate.h
gapplication-tool.c
gapplication.c
gapplication.h
gapplicationcommandline.c
gapplicationcommandline.h
gapplicationimpl-dbus.c
gapplicationimpl.h
gasynchelper.c
gasynchelper.h
gasyncinitable.c
gasyncinitable.h
gasyncresult.c
gasyncresult.h
gbufferedinputstream.c
gbufferedinputstream.h
gbufferedoutputstream.c
gbufferedoutputstream.h
gbytesicon.c
gbytesicon.h
gcancellable.c
gcancellable.h
gcharsetconverter.c
gcharsetconverter.h
gcocoanotificationbackend.m
gcontenttype-win32.c
gcontenttype.c
gcontenttype.h
gcontenttypeprivate.h
gcontextspecificgroup.c
gcontextspecificgroup.h
gconverter.c
gconverter.h
gconverterinputstream.c
gconverterinputstream.h
gconverteroutputstream.c
gconverteroutputstream.h
gcredentials.c
gcredentials.h
gcredentialsprivate.h
gdatagrambased.c
gdatagrambased.h
gdatainputstream.c
gdatainputstream.h
gdataoutputstream.c
gdataoutputstream.h
gdbus-tool.c
gdbusactiongroup-private.h
gdbusactiongroup.c
gdbusactiongroup.h
gdbusaddress.c
gdbusaddress.h
gdbusauth.c
gdbusauth.h
gdbusauthmechanism.c
gdbusauthmechanism.h
gdbusauthmechanismanon.c
gdbusauthmechanismanon.h
gdbusauthmechanismexternal.c
gdbusauthmechanismexternal.h
gdbusauthmechanismsha1.c
gdbusauthmechanismsha1.h
gdbusauthobserver.c
gdbusauthobserver.h
gdbusconnection.c
gdbusconnection.h
gdbusdaemon.c
gdbusdaemon.h
gdbuserror.c
gdbuserror.h
gdbusinterface.c
gdbusinterface.h
gdbusinterfaceskeleton.c
gdbusinterfaceskeleton.h
gdbusintrospection.c
gdbusintrospection.h
gdbusmenumodel.c
gdbusmenumodel.h
gdbusmessage.c
gdbusmessage.h
gdbusmethodinvocation.c
gdbusmethodinvocation.h
gdbusnameowning.c
gdbusnameowning.h
gdbusnamewatching.c
gdbusnamewatching.h
gdbusobject.c
gdbusobject.h
gdbusobjectmanager.c
gdbusobjectmanager.h
gdbusobjectmanagerclient.c
gdbusobjectmanagerclient.h
gdbusobjectmanagerserver.c
gdbusobjectmanagerserver.h
gdbusobjectproxy.c
gdbusobjectproxy.h
gdbusobjectskeleton.c
gdbusobjectskeleton.h
gdbusprivate.c
gdbusprivate.h
gdbusproxy.c
gdbusproxy.h
gdbusserver.c
gdbusserver.h
gdbusutils.c
gdbusutils.h
gdelayedsettingsbackend.c
gdelayedsettingsbackend.h
gdesktopappinfo.c
gdesktopappinfo.h
gdocumentportal.c
gdocumentportal.h
gdrive.c
gdrive.h
gdtlsclientconnection.c
gdtlsclientconnection.h
gdtlsconnection.c
gdtlsconnection.h
gdtlsserverconnection.c
gdtlsserverconnection.h
gdummyfile.c
gdummyfile.h
gdummyproxyresolver.c
gdummyproxyresolver.h
gdummytlsbackend.c
gdummytlsbackend.h
gemblem.c
gemblem.h
gemblemedicon.c
gemblemedicon.h
gfdonotificationbackend.c
gfile.c
gfile.h
gfileattribute-priv.h
gfileattribute.c
gfileattribute.h
gfiledescriptorbased.c
gfiledescriptorbased.h
gfileenumerator.c
gfileenumerator.h
gfileicon.c
gfileicon.h
gfileinfo-priv.h
gfileinfo.c
gfileinfo.h
gfileinputstream.c
gfileinputstream.h
gfileiostream.c
gfileiostream.h
gfilemonitor.c
gfilemonitor.h
gfilenamecompleter.c
gfilenamecompleter.h
gfileoutputstream.c
gfileoutputstream.h
gfilterinputstream.c
gfilterinputstream.h
gfilteroutputstream.c
gfilteroutputstream.h
ggtknotificationbackend.c
ghttpproxy.c
ghttpproxy.h
gicon.c
gicon.h
ginetaddress.c
ginetaddress.h
ginetaddressmask.c
ginetaddressmask.h
ginetsocketaddress.c
ginetsocketaddress.h
ginitable.c
ginitable.h
ginputstream.c
ginputstream.h
gio-autocleanups.h
gio-launch-desktop.c
gio-querymodules-wrapper.py
gio-querymodules.c
gio-tool-cat.c
gio-tool-copy.c
gio-tool-info.c
gio-tool-list.c
gio-tool-mime.c
gio-tool-mkdir.c
gio-tool-monitor.c
gio-tool-mount.c
gio-tool-move.c
gio-tool-open.c
gio-tool-remove.c
gio-tool-rename.c
gio-tool-save.c
gio-tool-set.c
gio-tool-trash.c
gio-tool-tree.c
gio-tool.c
gio-tool.h
gio.h
gio.rc.in
gio.stp.in
gio_probes.d
gio_trace.h
gioenums.h
gioenumtypes.c.template
gioenumtypes.h.template
gioerror.c
gioerror.h
giomodule-priv.c
giomodule-priv.h
giomodule.c
giomodule.h
gioprivate.h
gioscheduler.c
gioscheduler.h
giostream.c
giostream.h
giotypes.h
giowin32-priv.h
gkeyfilesettingsbackend.c
glib-compile-resources.c
glib-compile-schemas.c
glistmodel.c
glistmodel.h
gliststore.c
gliststore.h
gloadableicon.c
gloadableicon.h
glocalfile.c
glocalfile.h
glocalfileenumerator.c
glocalfileenumerator.h
glocalfileinfo.c
glocalfileinfo.h
glocalfileinputstream.c
glocalfileinputstream.h
glocalfileiostream.c
glocalfileiostream.h
glocalfilemonitor.c
glocalfilemonitor.h
glocalfileoutputstream.c
glocalfileoutputstream.h
glocalfileprivate.h
glocalvfs.c
glocalvfs.h
gmarshal-internal.c
gmarshal-internal.h
gmarshal-internal.list
gmemoryinputstream.c
gmemoryinputstream.h
gmemorymonitor.c
gmemorymonitor.h
gmemorymonitordbus.c
gmemorymonitordbus.h
gmemorymonitorportal.c
gmemorymonitorportal.h
gmemoryoutputstream.c
gmemoryoutputstream.h
gmemorysettingsbackend.c
gmenu.c
gmenu.h
gmenuexporter.c
gmenuexporter.h
gmenumodel.c
gmenumodel.h
gmount.c
gmount.h
gmountoperation.c
gmountoperation.h
gmountprivate.h
gnativesocketaddress.c
gnativesocketaddress.h
gnativevolumemonitor.c
gnativevolumemonitor.h
gnetworkaddress.c
gnetworkaddress.h
gnetworking.c
gnetworking.h.in
gnetworkingprivate.h
gnetworkmonitor.c
gnetworkmonitor.h
gnetworkmonitorbase.c
gnetworkmonitorbase.h
gnetworkmonitornetlink.c
gnetworkmonitornetlink.h
gnetworkmonitornm.c
gnetworkmonitornm.h
gnetworkmonitorportal.c
gnetworkmonitorportal.h
gnetworkservice.c
gnetworkservice.h
gnextstepsettingsbackend.m
gnotification-private.h
gnotification.c
gnotification.h
gnotificationbackend.c
gnotificationbackend.h
gnullsettingsbackend.c
gopenuriportal.c
gopenuriportal.h
gosxappinfo.h
gosxappinfo.m
gosxcontenttype.m
goutputstream.c
goutputstream.h
gpermission.c
gpermission.h
gpollableinputstream.c
gpollableinputstream.h
gpollableoutputstream.c
gpollableoutputstream.h
gpollableutils.c
gpollableutils.h
gpollfilemonitor.c
gpollfilemonitor.h
gportalnotificationbackend.c
gportalsupport.c
gportalsupport.h
gpropertyaction.c
gpropertyaction.h
gproxy.c
gproxy.h
gproxyaddress.c
gproxyaddress.h
gproxyaddressenumerator.c
gproxyaddressenumerator.h
gproxyresolver.c
gproxyresolver.h
gproxyresolverportal.c
gproxyresolverportal.h
gregistrysettingsbackend.c
gregistrysettingsbackend.h
gremoteactiongroup.c
gremoteactiongroup.h
gresolver.c
gresolver.h
gresource-tool.c
gresource.c
gresource.h
gresourcefile.c
gresourcefile.h
gschema.dtd
gschema.its
gschema.loc
gseekable.c
gseekable.h
gsettings-mapping.c
gsettings-mapping.h
gsettings-tool.c
gsettings.c
gsettings.h
gsettingsbackend.c
gsettingsbackend.h
gsettingsbackendinternal.h
gsettingsschema-internal.h
gsettingsschema.c
gsettingsschema.h
gsimpleaction.c
gsimpleaction.h
gsimpleactiongroup.c
gsimpleactiongroup.h
gsimpleasyncresult.c
gsimpleasyncresult.h
gsimpleiostream.c
gsimpleiostream.h
gsimplepermission.c
gsimplepermission.h
gsimpleproxyresolver.c
gsimpleproxyresolver.h
gsocket.c
gsocket.h
gsocketaddress.c
gsocketaddress.h
gsocketaddressenumerator.c
gsocketaddressenumerator.h
gsocketclient.c
gsocketclient.h
gsocketconnectable.c
gsocketconnectable.h
gsocketconnection.c
gsocketconnection.h
gsocketcontrolmessage.c
gsocketcontrolmessage.h
gsocketinputstream.c
gsocketinputstream.h
gsocketlistener.c
gsocketlistener.h
gsocketoutputstream.c
gsocketoutputstream.h
gsocketservice.c
gsocketservice.h
gsocks4aproxy.c
gsocks4aproxy.h
gsocks4proxy.c
gsocks4proxy.h
gsocks5proxy.c
gsocks5proxy.h
gsrvtarget.c
gsrvtarget.h
gsubprocess.c
gsubprocess.h
gsubprocesslauncher-private.h
gsubprocesslauncher.c
gsubprocesslauncher.h
gtask.c
gtask.h
gtcpconnection.c
gtcpconnection.h
gtcpwrapperconnection.c
gtcpwrapperconnection.h
gtestdbus.c
gtestdbus.h
gthemedicon.c
gthemedicon.h
gthreadedresolver.c
gthreadedresolver.h
gthreadedsocketservice.c
gthreadedsocketservice.h
gtlsbackend.c
gtlsbackend.h
gtlscertificate.c
gtlscertificate.h
gtlsclientconnection.c
gtlsclientconnection.h
gtlsconnection.c
gtlsconnection.h
gtlsdatabase.c
gtlsdatabase.h
gtlsfiledatabase.c
gtlsfiledatabase.h
gtlsinteraction.c
gtlsinteraction.h
gtlspassword.c
gtlspassword.h
gtlsserverconnection.c
gtlsserverconnection.h
gtrashportal.c
gtrashportal.h
gunionvolumemonitor.c
gunionvolumemonitor.h
gunixconnection.c
gunixconnection.h
gunixcredentialsmessage.c
gunixcredentialsmessage.h
gunixfdlist.c
gunixfdlist.h
gunixfdmessage.c
gunixfdmessage.h
gunixinputstream.c
gunixinputstream.h
gunixmount.c
gunixmount.h
gunixmounts.c
gunixmounts.h
gunixoutputstream.c
gunixoutputstream.h
gunixsocketaddress.c
gunixsocketaddress.h
gunixvolume.c
gunixvolume.h
gunixvolumemonitor.c
gunixvolumemonitor.h
gvfs.c
gvfs.h
gvolume.c
gvolume.h
gvolumemonitor.c
gvolumemonitor.h
gwin32appinfo.c
gwin32appinfo.h
gwin32inputstream.c
gwin32inputstream.h
gwin32mount.c
gwin32mount.h
gwin32networking.h
gwin32networkmonitor.c
gwin32networkmonitor.h
gwin32notificationbackend.c
gwin32outputstream.c
gwin32outputstream.h
gwin32registrykey.c
gwin32registrykey.h
gwin32volumemonitor.c
gwin32volumemonitor.h
gzlibcompressor.c
gzlibcompressor.h
gzlibdecompressor.c
gzlibdecompressor.h
meson.build
org.freedesktop.portal.Documents.xml
org.freedesktop.portal.OpenURI.xml
org.freedesktop.portal.ProxyResolver.xml
org.freedesktop.portal.Trash.xml
strinfo.c
thumbnail-verify.c
thumbnail-verify.h
glib
gmodule
gobject
gthread
m4macros
po
subprojects
tests
.clang-format
.dir-locals.el
.gitattributes
.gitignore
.gitlab-ci.yml
AUTHORS
CONTRIBUTING.md
COPYING
HACKING
INSTALL.in
NEWS
NEWS.pre-1-3
README
README.md
README.rationale
README.win32
README.win32.md
check-abis.sh
clang-format-diff.py
glib-gettextize.in
glib.doap
glib.supp
meson.build
meson_options.txt
msvc_recommended_pragmas.h
sanity_check
template-tap.test.in
template.test.in
glib/gio/gtcpconnection.c

333 lines
9.0 KiB
C
Raw Normal View History

/* GIO - GLib Input, Output and Streaming Library
*
* Copyright © 2008, 2009 Codethink Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
/**
* SECTION:gtcpconnection
* @title: GTcpConnection
2010-11-28 23:55:43 -05:00
* @short_description: A TCP GSocketConnection
2014-01-07 22:55:43 -05:00
* @include: gio/gio.h
* @see_also: #GSocketConnection.
*
* This is the subclass of #GSocketConnection that is created
* for TCP/IP sockets.
*
* Since: 2.22
*/
#include "config.h"
#include "gtcpconnection.h"
#include "gasyncresult.h"
#include "gtask.h"
#include "giostream.h"
#include "glibintl.h"
struct _GTcpConnectionPrivate
{
guint graceful_disconnect : 1;
};
G_DEFINE_TYPE_WITH_CODE (GTcpConnection, g_tcp_connection,
G_TYPE_SOCKET_CONNECTION,
G_ADD_PRIVATE (GTcpConnection)
g_socket_connection_factory_register_type (g_define_type_id,
G_SOCKET_FAMILY_IPV4,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT);
g_socket_connection_factory_register_type (g_define_type_id,
G_SOCKET_FAMILY_IPV6,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_DEFAULT);
g_socket_connection_factory_register_type (g_define_type_id,
G_SOCKET_FAMILY_IPV4,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_TCP);
g_socket_connection_factory_register_type (g_define_type_id,
G_SOCKET_FAMILY_IPV6,
G_SOCKET_TYPE_STREAM,
G_SOCKET_PROTOCOL_TCP);
);
static gboolean g_tcp_connection_close (GIOStream *stream,
GCancellable *cancellable,
GError **error);
static void g_tcp_connection_close_async (GIOStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
enum
{
PROP_0,
PROP_GRACEFUL_DISCONNECT
};
static void
g_tcp_connection_init (GTcpConnection *connection)
{
connection->priv = g_tcp_connection_get_instance_private (connection);
connection->priv->graceful_disconnect = FALSE;
}
static void
g_tcp_connection_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GTcpConnection *connection = G_TCP_CONNECTION (object);
switch (prop_id)
{
case PROP_GRACEFUL_DISCONNECT:
g_value_set_boolean (value, connection->priv->graceful_disconnect);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
g_tcp_connection_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GTcpConnection *connection = G_TCP_CONNECTION (object);
switch (prop_id)
{
case PROP_GRACEFUL_DISCONNECT:
g_tcp_connection_set_graceful_disconnect (connection,
g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
g_tcp_connection_class_init (GTcpConnectionClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GIOStreamClass *stream_class = G_IO_STREAM_CLASS (class);
gobject_class->set_property = g_tcp_connection_set_property;
gobject_class->get_property = g_tcp_connection_get_property;
stream_class->close_fn = g_tcp_connection_close;
stream_class->close_async = g_tcp_connection_close_async;
g_object_class_install_property (gobject_class, PROP_GRACEFUL_DISCONNECT,
g_param_spec_boolean ("graceful-disconnect",
P_("Graceful Disconnect"),
P_("Whether or not close does a graceful disconnect"),
FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static gboolean
g_tcp_connection_close (GIOStream *stream,
GCancellable *cancellable,
GError **error)
{
GTcpConnection *connection = G_TCP_CONNECTION (stream);
GSocket *socket;
char buffer[1024];
gssize ret;
gboolean had_error;
socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream));
had_error = FALSE;
if (connection->priv->graceful_disconnect &&
!g_cancellable_is_cancelled (cancellable) /* Cancelled -> close fast */)
{
if (!g_socket_shutdown (socket, FALSE, TRUE, error))
{
error = NULL; /* Ignore further errors */
had_error = TRUE;
}
else
{
while (TRUE)
{
ret = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer),
TRUE, cancellable, error);
if (ret < 0)
{
had_error = TRUE;
error = NULL;
break;
}
if (ret == 0)
break;
}
}
}
return G_IO_STREAM_CLASS (g_tcp_connection_parent_class)
->close_fn (stream, cancellable, error) && !had_error;
}
/* consumes @error */
static void
async_close_finish (GTask *task,
GError *error)
{
GIOStreamClass *parent = G_IO_STREAM_CLASS (g_tcp_connection_parent_class);
GIOStream *stream = g_task_get_source_object (task);
GCancellable *cancellable = g_task_get_cancellable (task);
/* Close underlying stream, ignoring further errors if we already
* have one.
*/
if (error)
parent->close_fn (stream, cancellable, NULL);
else
parent->close_fn (stream, cancellable, &error);
if (error)
g_task_return_error (task, error);
else
g_task_return_boolean (task, TRUE);
}
static gboolean
close_read_ready (GSocket *socket,
GIOCondition condition,
GTask *task)
{
GError *error = NULL;
char buffer[1024];
gssize ret;
ret = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer),
FALSE, g_task_get_cancellable (task),
&error);
if (ret < 0)
{
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
{
g_error_free (error);
return TRUE;
}
else
{
async_close_finish (task, error);
g_object_unref (task);
return FALSE;
}
}
if (ret == 0)
{
async_close_finish (task, NULL);
return FALSE;
}
return TRUE;
}
static void
g_tcp_connection_close_async (GIOStream *stream,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTcpConnection *connection = G_TCP_CONNECTION (stream);
GSocket *socket;
GSource *source;
GError *error;
GTask *task;
if (connection->priv->graceful_disconnect &&
!g_cancellable_is_cancelled (cancellable) /* Cancelled -> close fast */)
{
task = g_task_new (stream, cancellable, callback, user_data);
g_task_set_source_tag (task, g_tcp_connection_close_async);
g_task_set_priority (task, io_priority);
socket = g_socket_connection_get_socket (G_SOCKET_CONNECTION (stream));
error = NULL;
if (!g_socket_shutdown (socket, FALSE, TRUE, &error))
{
g_task_return_error (task, error);
g_object_unref (task);
return;
}
source = g_socket_create_source (socket, G_IO_IN, cancellable);
g_task_attach_source (task, source, (GSourceFunc) close_read_ready);
g_source_unref (source);
return;
}
2009-07-30 11:18:35 -04:00
G_IO_STREAM_CLASS (g_tcp_connection_parent_class)
->close_async (stream, io_priority, cancellable, callback, user_data);
}
/**
* g_tcp_connection_set_graceful_disconnect:
* @connection: a #GTcpConnection
* @graceful_disconnect: Whether to do graceful disconnects or not
*
2014-10-20 19:05:26 -05:00
* This enables graceful disconnects on close. A graceful disconnect
2011-04-20 19:08:06 +02:00
* means that we signal the receiving end that the connection is terminated
* and wait for it to close the connection before closing the connection.
*
* A graceful disconnect means that we can be sure that we successfully sent
* all the outstanding data to the other end, or get an error reported.
* However, it also means we have to wait for all the data to reach the
* other side and for it to acknowledge this by closing the socket, which may
* take a while. For this reason it is disabled by default.
*
* Since: 2.22
*/
void
g_tcp_connection_set_graceful_disconnect (GTcpConnection *connection,
gboolean graceful_disconnect)
{
graceful_disconnect = !!graceful_disconnect;
if (graceful_disconnect != connection->priv->graceful_disconnect)
{
connection->priv->graceful_disconnect = graceful_disconnect;
g_object_notify (G_OBJECT (connection), "graceful-disconnect");
}
}
/**
* g_tcp_connection_get_graceful_disconnect:
* @connection: a #GTcpConnection
*
* Checks if graceful disconnects are used. See
* g_tcp_connection_set_graceful_disconnect().
*
* Returns: %TRUE if graceful disconnect is used on close, %FALSE otherwise
*
* Since: 2.22
*/
gboolean
g_tcp_connection_get_graceful_disconnect (GTcpConnection *connection)
{
return connection->priv->graceful_disconnect;
}