| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | /* GIO - GLib Input, Output and Streaming Library
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima | 
					
						
							|  |  |  |  *           © 2008 codethink | 
					
						
							|  |  |  |  * Copyright © 2009 Red Hat, Inc | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * 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 | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Authors: Christian Kellner <gicmo@gnome.org> | 
					
						
							|  |  |  |  *          Samuel Cormier-Iijima <sciyoshi@gmail.com> | 
					
						
							|  |  |  |  *          Ryan Lortie <desrt@desrt.ca> | 
					
						
							|  |  |  |  *          Alexander Larsson <alexl@redhat.com> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "config.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gsocketconnection.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gsocketoutputstream.h"
 | 
					
						
							|  |  |  | #include "gsocketinputstream.h"
 | 
					
						
							| 
									
										
										
										
											2013-11-18 16:15:34 -05:00
										 |  |  | #include "gioprivate.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | #include <gio/giostream.h>
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  | #include <gio/gtask.h>
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | #include "gunixconnection.h"
 | 
					
						
							|  |  |  | #include "gtcpconnection.h"
 | 
					
						
							|  |  |  | #include "glibintl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2023-10-24 10:58:28 +01:00
										 |  |  |  * GSocketConnection: | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-10-24 10:58:28 +01:00
										 |  |  |  * `GSocketConnection` is a [class@Gio.IOStream] for a connected socket. They | 
					
						
							|  |  |  |  * can be created either by [class@Gio.SocketClient] when connecting to a host, | 
					
						
							|  |  |  |  * or by [class@Gio.SocketListener] when accepting a new client. | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-10-24 10:58:28 +01:00
										 |  |  |  * The type of the `GSocketConnection` object returned from these calls | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * depends on the type of the underlying socket that is in use. For | 
					
						
							| 
									
										
										
										
											2023-10-24 10:58:28 +01:00
										 |  |  |  * instance, for a TCP/IP connection it will be a [class@Gio.TcpConnection]. | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-04-20 19:08:06 +02:00
										 |  |  |  * Choosing what type of object to construct is done with the socket | 
					
						
							| 
									
										
										
										
											2023-10-24 10:58:28 +01:00
										 |  |  |  * connection factory, and it is possible for third parties to register | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * custom socket connection types for specific combination of socket | 
					
						
							| 
									
										
										
										
											2023-10-24 10:58:28 +01:00
										 |  |  |  * family/type/protocol using [func@Gio.SocketConnection.factory_register_type]. | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-10-24 10:58:28 +01:00
										 |  |  |  * To close a `GSocketConnection`, use [method@Gio.IOStream.close]. Closing both | 
					
						
							|  |  |  |  * substreams of the [class@Gio.IOStream] separately will not close the | 
					
						
							|  |  |  |  * underlying [class@Gio.Socket]. | 
					
						
							| 
									
										
										
										
											2014-02-13 10:58:21 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   PROP_NONE, | 
					
						
							|  |  |  |   PROP_SOCKET, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct _GSocketConnectionPrivate | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSocket       *socket; | 
					
						
							|  |  |  |   GInputStream  *input_stream; | 
					
						
							|  |  |  |   GOutputStream *output_stream; | 
					
						
							| 
									
										
										
										
											2010-04-23 08:47:18 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-18 16:15:34 -05:00
										 |  |  |   GSocketAddress *cached_remote_address; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 08:47:18 -04:00
										 |  |  |   gboolean       in_dispose; | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean g_socket_connection_close         (GIOStream            *stream, | 
					
						
							|  |  |  | 						   GCancellable         *cancellable, | 
					
						
							|  |  |  | 						   GError              **error); | 
					
						
							|  |  |  | static void     g_socket_connection_close_async   (GIOStream            *stream, | 
					
						
							|  |  |  | 						   int                   io_priority, | 
					
						
							|  |  |  | 						   GCancellable         *cancellable, | 
					
						
							|  |  |  | 						   GAsyncReadyCallback   callback, | 
					
						
							|  |  |  | 						   gpointer              user_data); | 
					
						
							|  |  |  | static gboolean g_socket_connection_close_finish  (GIOStream            *stream, | 
					
						
							|  |  |  | 						   GAsyncResult         *result, | 
					
						
							|  |  |  | 						   GError              **error); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-11 00:29:58 +01:00
										 |  |  | G_DEFINE_TYPE_WITH_PRIVATE (GSocketConnection, g_socket_connection, G_TYPE_IO_STREAM) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | static GInputStream * | 
					
						
							|  |  |  | g_socket_connection_get_input_stream (GIOStream *io_stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (connection->priv->input_stream == NULL) | 
					
						
							|  |  |  |     connection->priv->input_stream = (GInputStream *) | 
					
						
							|  |  |  |       _g_socket_input_stream_new (connection->priv->socket); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return connection->priv->input_stream; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GOutputStream * | 
					
						
							|  |  |  | g_socket_connection_get_output_stream (GIOStream *io_stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (connection->priv->output_stream == NULL) | 
					
						
							|  |  |  |     connection->priv->output_stream = (GOutputStream *) | 
					
						
							|  |  |  |       _g_socket_output_stream_new (connection->priv->socket); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return connection->priv->output_stream; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_is_connected: | 
					
						
							|  |  |  |  * @connection: a #GSocketConnection | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Checks if @connection is connected. This is equivalent to calling | 
					
						
							|  |  |  |  * g_socket_is_connected() on @connection's underlying #GSocket. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: whether @connection is connected | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_socket_connection_is_connected (GSocketConnection  *connection) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return g_socket_is_connected (connection->priv->socket); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_connect: | 
					
						
							|  |  |  |  * @connection: a #GSocketConnection | 
					
						
							|  |  |  |  * @address: a #GSocketAddress specifying the remote address. | 
					
						
							| 
									
										
										
										
											2016-10-28 18:29:02 -07:00
										 |  |  |  * @cancellable: (nullable): a %GCancellable or %NULL | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |  * @error: #GError for error reporting, or %NULL to ignore. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Connect @connection to the specified remote address. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: %TRUE if the connection succeeded, %FALSE on error | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_socket_connection_connect (GSocketConnection  *connection, | 
					
						
							|  |  |  | 			     GSocketAddress     *address, | 
					
						
							|  |  |  | 			     GCancellable       *cancellable, | 
					
						
							|  |  |  | 			     GError            **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE); | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return g_socket_connect (connection->priv->socket, address, | 
					
						
							|  |  |  | 			   cancellable, error); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean g_socket_connection_connect_callback (GSocket      *socket, | 
					
						
							|  |  |  | 						      GIOCondition  condition, | 
					
						
							|  |  |  | 						      gpointer      user_data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_connect_async: | 
					
						
							|  |  |  |  * @connection: a #GSocketConnection | 
					
						
							|  |  |  |  * @address: a #GSocketAddress specifying the remote address. | 
					
						
							| 
									
										
										
										
											2016-10-28 18:29:02 -07:00
										 |  |  |  * @cancellable: (nullable): a %GCancellable or %NULL | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |  * @callback: (scope async): a #GAsyncReadyCallback | 
					
						
							| 
									
										
										
										
											2023-02-20 14:43:02 -06:00
										 |  |  |  * @user_data: user data for the callback | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Asynchronously connect @connection to the specified remote address. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This clears the #GSocket:blocking flag on @connection's underlying | 
					
						
							|  |  |  |  * socket if it is currently set. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2023-03-23 18:35:11 +00:00
										 |  |  |  * If #GSocket:timeout is set, the operation will time out and return | 
					
						
							|  |  |  |  * %G_IO_ERROR_TIMED_OUT after that period. Otherwise, it will continue | 
					
						
							|  |  |  |  * indefinitely until operating system timeouts (if any) are hit. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |  * Use g_socket_connection_connect_finish() to retrieve the result. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | g_socket_connection_connect_async (GSocketConnection   *connection, | 
					
						
							|  |  |  | 				   GSocketAddress      *address, | 
					
						
							|  |  |  | 				   GCancellable        *cancellable, | 
					
						
							|  |  |  | 				   GAsyncReadyCallback  callback, | 
					
						
							|  |  |  | 				   gpointer             user_data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   GTask *task; | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |   GError *tmp_error = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_return_if_fail (G_IS_SOCKET_CONNECTION (connection)); | 
					
						
							|  |  |  |   g_return_if_fail (G_IS_SOCKET_ADDRESS (address)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   task = g_task_new (connection, cancellable, callback, user_data); | 
					
						
							| 
									
										
										
										
											2016-06-16 19:39:38 -04:00
										 |  |  |   g_task_set_source_tag (task, g_socket_connection_connect_async); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   g_socket_set_blocking (connection->priv->socket, FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (g_socket_connect (connection->priv->socket, address, | 
					
						
							|  |  |  | 			cancellable, &tmp_error)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       g_task_return_boolean (task, TRUE); | 
					
						
							|  |  |  |       g_object_unref (task); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |     } | 
					
						
							|  |  |  |   else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       GSource *source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       g_error_free (tmp_error); | 
					
						
							|  |  |  |       source = g_socket_create_source (connection->priv->socket, | 
					
						
							|  |  |  | 				       G_IO_OUT, cancellable); | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       g_task_attach_source (task, source, | 
					
						
							|  |  |  | 			    (GSourceFunc) g_socket_connection_connect_callback); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |       g_source_unref (source); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |       g_task_return_error (task, tmp_error); | 
					
						
							|  |  |  |       g_object_unref (task); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | g_socket_connection_connect_callback (GSocket      *socket, | 
					
						
							|  |  |  | 				      GIOCondition  condition, | 
					
						
							|  |  |  | 				      gpointer      user_data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   GTask *task = user_data; | 
					
						
							|  |  |  |   GSocketConnection *connection = g_task_get_source_object (task); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |   GError *error = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (g_socket_check_connect_result (connection->priv->socket, &error)) | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |     g_task_return_boolean (task, TRUE); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |   else | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |     g_task_return_error (task, error); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   g_object_unref (task); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_connect_finish: | 
					
						
							|  |  |  |  * @connection: a #GSocketConnection | 
					
						
							|  |  |  |  * @result: the #GAsyncResult | 
					
						
							|  |  |  |  * @error: #GError for error reporting, or %NULL to ignore. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Gets the result of a g_socket_connection_connect_async() call. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: %TRUE if the connection succeeded, %FALSE on error | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.32 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | gboolean | 
					
						
							|  |  |  | g_socket_connection_connect_finish (GSocketConnection  *connection, | 
					
						
							|  |  |  | 				    GAsyncResult       *result, | 
					
						
							|  |  |  | 				    GError            **error) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE); | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   g_return_val_if_fail (g_task_is_valid (result, connection), FALSE); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   return g_task_propagate_boolean (G_TASK (result), error); | 
					
						
							| 
									
										
										
										
											2011-06-12 16:29:04 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-18 13:02:11 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_get_socket: | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * @connection: a #GSocketConnection | 
					
						
							| 
									
										
										
										
											2009-05-18 13:02:11 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Gets the underlying #GSocket object of the connection. | 
					
						
							|  |  |  |  * This can be useful if you want to do something unusual on it | 
					
						
							|  |  |  |  * not supported by the #GSocketConnection APIs. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-04-17 10:00:50 +05:30
										 |  |  |  * Returns: (transfer none): a #GSocket or %NULL on error. | 
					
						
							| 
									
										
										
										
											2009-05-18 13:02:11 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | GSocket * | 
					
						
							|  |  |  | g_socket_connection_get_socket (GSocketConnection *connection) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return connection->priv->socket; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_get_local_address: | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * @connection: a #GSocketConnection | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * @error: #GError for error reporting, or %NULL to ignore. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Try to get the local address of a socket connection. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-09-24 18:24:41 -03:00
										 |  |  |  * Returns: (transfer full): a #GSocketAddress or %NULL on error. | 
					
						
							| 
									
										
										
										
											2009-05-19 10:40:27 +02:00
										 |  |  |  *     Free the returned object with g_object_unref(). | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | GSocketAddress * | 
					
						
							|  |  |  | g_socket_connection_get_local_address (GSocketConnection  *connection, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | 				       GError            **error) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   return g_socket_get_local_address (connection->priv->socket, error); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_get_remote_address: | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * @connection: a #GSocketConnection | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * @error: #GError for error reporting, or %NULL to ignore. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-06-08 15:29:57 +02:00
										 |  |  |  * Try to get the remote address of a socket connection. | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2013-11-18 16:15:34 -05:00
										 |  |  |  * Since GLib 2.40, when used with g_socket_client_connect() or | 
					
						
							|  |  |  |  * g_socket_client_connect_async(), during emission of | 
					
						
							|  |  |  |  * %G_SOCKET_CLIENT_CONNECTING, this function will return the remote | 
					
						
							|  |  |  |  * address that will be used for the connection.  This allows | 
					
						
							|  |  |  |  * applications to print e.g. "Connecting to example.com | 
					
						
							|  |  |  |  * (10.42.77.3)...". | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-09-24 18:24:41 -03:00
										 |  |  |  * Returns: (transfer full): a #GSocketAddress or %NULL on error. | 
					
						
							| 
									
										
										
										
											2009-05-19 10:40:27 +02:00
										 |  |  |  *     Free the returned object with g_object_unref(). | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | GSocketAddress * | 
					
						
							|  |  |  | g_socket_connection_get_remote_address (GSocketConnection  *connection, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | 					GError            **error) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-18 16:15:34 -05:00
										 |  |  |   if (!g_socket_is_connected (connection->priv->socket)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       return connection->priv->cached_remote_address ? | 
					
						
							|  |  |  |         g_object_ref (connection->priv->cached_remote_address) : NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |   return g_socket_get_remote_address (connection->priv->socket, error); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-18 16:15:34 -05:00
										 |  |  | /* Private API allowing applications to retrieve the resolved address
 | 
					
						
							|  |  |  |  * now, before we start connecting. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * https://bugzilla.gnome.org/show_bug.cgi?id=712547
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | g_socket_connection_set_cached_remote_address (GSocketConnection *connection, | 
					
						
							|  |  |  |                                                GSocketAddress    *address) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   g_clear_object (&connection->priv->cached_remote_address); | 
					
						
							|  |  |  |   connection->priv->cached_remote_address = address ? g_object_ref (address) : NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | g_socket_connection_get_property (GObject    *object, | 
					
						
							|  |  |  |                                   guint       prop_id, | 
					
						
							|  |  |  |                                   GValue     *value, | 
					
						
							|  |  |  |                                   GParamSpec *pspec) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prop_id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |      case PROP_SOCKET: | 
					
						
							|  |  |  |       g_value_set_object (value, connection->priv->socket); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | g_socket_connection_set_property (GObject      *object, | 
					
						
							|  |  |  |                                   guint         prop_id, | 
					
						
							|  |  |  |                                   const GValue *value, | 
					
						
							|  |  |  |                                   GParamSpec   *pspec) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (prop_id) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |      case PROP_SOCKET: | 
					
						
							|  |  |  |       connection->priv->socket = G_SOCKET (g_value_dup_object (value)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_socket_connection_constructed (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-05 12:22:51 +00:00
										 |  |  | #ifndef G_DISABLE_ASSERT
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (object); | 
					
						
							| 
									
										
										
										
											2019-03-05 12:22:51 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   g_assert (connection->priv->socket != NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 08:47:18 -04:00
										 |  |  | static void | 
					
						
							|  |  |  | g_socket_connection_dispose (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   connection->priv->in_dispose = TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-18 16:15:34 -05:00
										 |  |  |   g_clear_object (&connection->priv->cached_remote_address); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 08:47:18 -04:00
										 |  |  |   G_OBJECT_CLASS (g_socket_connection_parent_class) | 
					
						
							|  |  |  |     ->dispose (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   connection->priv->in_dispose = FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | static void | 
					
						
							|  |  |  | g_socket_connection_finalize (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (object); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (connection->priv->input_stream) | 
					
						
							|  |  |  |     g_object_unref (connection->priv->input_stream); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (connection->priv->output_stream) | 
					
						
							|  |  |  |     g_object_unref (connection->priv->output_stream); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_object_unref (connection->priv->socket); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_OBJECT_CLASS (g_socket_connection_parent_class) | 
					
						
							|  |  |  |     ->finalize (object); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_socket_connection_class_init (GSocketConnectionClass *klass) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | 
					
						
							|  |  |  |   GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gobject_class->set_property = g_socket_connection_set_property; | 
					
						
							|  |  |  |   gobject_class->get_property = g_socket_connection_get_property; | 
					
						
							|  |  |  |   gobject_class->constructed = g_socket_connection_constructed; | 
					
						
							|  |  |  |   gobject_class->finalize = g_socket_connection_finalize; | 
					
						
							| 
									
										
										
										
											2010-04-23 08:47:18 -04:00
										 |  |  |   gobject_class->dispose = g_socket_connection_dispose; | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |   stream_class->get_input_stream = g_socket_connection_get_input_stream; | 
					
						
							|  |  |  |   stream_class->get_output_stream = g_socket_connection_get_output_stream; | 
					
						
							|  |  |  |   stream_class->close_fn = g_socket_connection_close; | 
					
						
							|  |  |  |   stream_class->close_async = g_socket_connection_close_async; | 
					
						
							|  |  |  |   stream_class->close_finish = g_socket_connection_close_finish; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-29 13:23:09 +00:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * GSocketConnection:socket: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The underlying [class@Gio.Socket]. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Since: 2.22 | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |   g_object_class_install_property (gobject_class, | 
					
						
							|  |  |  |                                    PROP_SOCKET, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_object ("socket", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |                                                         G_TYPE_SOCKET, | 
					
						
							|  |  |  |                                                         G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_READWRITE | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_socket_connection_init (GSocketConnection *connection) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-24 15:43:04 +01:00
										 |  |  |   connection->priv = g_socket_connection_get_instance_private (connection); | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | g_socket_connection_close (GIOStream     *stream, | 
					
						
							|  |  |  | 			   GCancellable  *cancellable, | 
					
						
							|  |  |  | 			   GError       **error) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   GSocketConnection *connection = G_SOCKET_CONNECTION (stream); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (connection->priv->output_stream) | 
					
						
							|  |  |  |     g_output_stream_close (connection->priv->output_stream, | 
					
						
							|  |  |  | 			   cancellable, NULL); | 
					
						
							|  |  |  |   if (connection->priv->input_stream) | 
					
						
							|  |  |  |     g_input_stream_close (connection->priv->input_stream, | 
					
						
							|  |  |  | 			  cancellable, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-23 08:47:18 -04:00
										 |  |  |   /* Don't close the underlying socket if this is being called
 | 
					
						
							|  |  |  |    * as part of dispose(); when destroying the GSocketConnection, | 
					
						
							|  |  |  |    * we only want to close the socket if we're holding the last | 
					
						
							|  |  |  |    * reference on it, and in that case it will close itself when | 
					
						
							|  |  |  |    * we unref it in finalize(). | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   if (connection->priv->in_dispose) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |   return g_socket_close (connection->priv->socket, error); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | g_socket_connection_close_async (GIOStream           *stream, | 
					
						
							|  |  |  | 				 int                  io_priority, | 
					
						
							|  |  |  | 				 GCancellable        *cancellable, | 
					
						
							|  |  |  | 				 GAsyncReadyCallback  callback, | 
					
						
							|  |  |  | 				 gpointer             user_data) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   GTask *task; | 
					
						
							| 
									
										
										
										
											2009-05-20 11:18:34 +02:00
										 |  |  |   GIOStreamClass *class; | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |   GError *error; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-20 11:18:34 +02:00
										 |  |  |   class = G_IO_STREAM_GET_CLASS (stream); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   task = g_task_new (stream, cancellable, callback, user_data); | 
					
						
							| 
									
										
										
										
											2016-06-16 19:39:38 -04:00
										 |  |  |   g_task_set_source_tag (task, g_socket_connection_close_async); | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |   /* socket close is not blocked, just do it! */ | 
					
						
							|  |  |  |   error = NULL; | 
					
						
							| 
									
										
										
										
											2009-05-20 11:18:34 +02:00
										 |  |  |   if (class->close_fn && | 
					
						
							|  |  |  |       !class->close_fn (stream, cancellable, &error)) | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |     g_task_return_error (task, error); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     g_task_return_boolean (task, TRUE); | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   g_object_unref (task); | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | g_socket_connection_close_finish (GIOStream     *stream, | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | 				  GAsyncResult  *result, | 
					
						
							|  |  |  | 				  GError       **error) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-08-02 15:48:22 -04:00
										 |  |  |   return g_task_propagate_boolean (G_TASK (result), error); | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |   GSocketFamily socket_family; | 
					
						
							|  |  |  |   GSocketType socket_type; | 
					
						
							|  |  |  |   int protocol; | 
					
						
							|  |  |  |   GType implementation; | 
					
						
							|  |  |  | } ConnectionFactory; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static guint | 
					
						
							|  |  |  | connection_factory_hash (gconstpointer key) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const ConnectionFactory *factory = key; | 
					
						
							|  |  |  |   guint h; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   h = factory->socket_family ^ (factory->socket_type << 4) ^ (factory->protocol << 8); | 
					
						
							|  |  |  |   /* This is likely to be small, so spread over whole
 | 
					
						
							|  |  |  |      hash space to get some distribution */ | 
					
						
							|  |  |  |   h = h ^ (h << 8) ^ (h << 16) ^ (h << 24); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return h; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | connection_factory_equal (gconstpointer _a, | 
					
						
							|  |  |  | 			  gconstpointer _b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   const ConnectionFactory *a = _a; | 
					
						
							|  |  |  |   const ConnectionFactory *b = _b; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (a->socket_family != b->socket_family) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (a->socket_type != b->socket_type) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (a->protocol != b->protocol) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GHashTable *connection_factories = NULL; | 
					
						
							|  |  |  | G_LOCK_DEFINE_STATIC(connection_factories); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_factory_register_type: | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * @g_type: a #GType, inheriting from %G_TYPE_SOCKET_CONNECTION | 
					
						
							|  |  |  |  * @family: a #GSocketFamily | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * @type: a #GSocketType | 
					
						
							|  |  |  |  * @protocol: a protocol id | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Looks up the #GType to be used when creating socket connections on | 
					
						
							| 
									
										
										
										
											2011-04-20 19:08:06 +02:00
										 |  |  |  * sockets with the specified @family, @type and @protocol. | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * If no type is registered, the #GSocketConnection base type is returned. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | g_socket_connection_factory_register_type (GType         g_type, | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | 					   GSocketFamily family, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | 					   GSocketType   type, | 
					
						
							|  |  |  | 					   gint          protocol) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   ConnectionFactory *factory; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_LOCK (connection_factories); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (connection_factories == NULL) | 
					
						
							|  |  |  |     connection_factories = g_hash_table_new_full (connection_factory_hash, | 
					
						
							|  |  |  | 						  connection_factory_equal, | 
					
						
							|  |  |  | 						  (GDestroyNotify)g_free, | 
					
						
							|  |  |  | 						  NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   factory = g_new0 (ConnectionFactory, 1); | 
					
						
							|  |  |  |   factory->socket_family = family; | 
					
						
							|  |  |  |   factory->socket_type = type; | 
					
						
							|  |  |  |   factory->protocol = protocol; | 
					
						
							|  |  |  |   factory->implementation = g_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_hash_table_insert (connection_factories, | 
					
						
							|  |  |  | 		       factory, factory); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_UNLOCK (connection_factories); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | init_builtin_types (void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-03 14:47:56 -05:00
										 |  |  |   g_type_ensure (G_TYPE_UNIX_CONNECTION); | 
					
						
							|  |  |  |   g_type_ensure (G_TYPE_TCP_CONNECTION); | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_factory_lookup_type: | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * @family: a #GSocketFamily | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * @type: a #GSocketType | 
					
						
							|  |  |  |  * @protocol_id: a protocol id | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Looks up the #GType to be used when creating socket connections on | 
					
						
							| 
									
										
										
										
											2011-04-20 19:08:06 +02:00
										 |  |  |  * sockets with the specified @family, @type and @protocol_id. | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * If no type is registered, the #GSocketConnection base type is returned. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Returns: a #GType | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | GType | 
					
						
							|  |  |  | g_socket_connection_factory_lookup_type (GSocketFamily family, | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  | 					 GSocketType   type, | 
					
						
							|  |  |  | 					 gint          protocol_id) | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | { | 
					
						
							|  |  |  |   ConnectionFactory *factory, key; | 
					
						
							|  |  |  |   GType g_type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   init_builtin_types (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_LOCK (connection_factories); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_type = G_TYPE_SOCKET_CONNECTION; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (connection_factories) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       key.socket_family = family; | 
					
						
							|  |  |  |       key.socket_type = type; | 
					
						
							|  |  |  |       key.protocol = protocol_id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       factory = g_hash_table_lookup (connection_factories, &key); | 
					
						
							|  |  |  |       if (factory) | 
					
						
							|  |  |  | 	g_type = factory->implementation; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   G_UNLOCK (connection_factories); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return g_type; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * g_socket_connection_factory_create_connection: | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  * @socket: a #GSocket | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Creates a #GSocketConnection subclass of the right type for | 
					
						
							|  |  |  |  * @socket. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-09-24 18:24:41 -03:00
										 |  |  |  * Returns: (transfer full): a #GSocketConnection | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Since: 2.22 | 
					
						
							| 
									
										
										
										
											2009-05-27 18:20:08 -04:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  | GSocketConnection * | 
					
						
							|  |  |  | g_socket_connection_factory_create_connection (GSocket *socket) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GType type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   type = g_socket_connection_factory_lookup_type (g_socket_get_family (socket), | 
					
						
							|  |  |  | 						  g_socket_get_socket_type (socket), | 
					
						
							| 
									
										
										
										
											2009-05-20 12:01:29 +02:00
										 |  |  | 						  g_socket_get_protocol (socket)); | 
					
						
							| 
									
										
										
										
											2009-05-15 21:26:24 +02:00
										 |  |  |   return g_object_new (type, "socket", socket, NULL); | 
					
						
							|  |  |  | } |