gio: Use the new private instance data declaration
[platform/upstream/glib.git] / gio / gsocketconnection.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
4  *           © 2008 codethink
5  * Copyright © 2009 Red Hat, Inc
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General
18  * Public License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  * Authors: Christian Kellner <gicmo@gnome.org>
23  *          Samuel Cormier-Iijima <sciyoshi@gmail.com>
24  *          Ryan Lortie <desrt@desrt.ca>
25  *          Alexander Larsson <alexl@redhat.com>
26  */
27
28 #include "config.h"
29
30 #include "gsocketconnection.h"
31
32 #include "gsocketoutputstream.h"
33 #include "gsocketinputstream.h"
34 #include <gio/giostream.h>
35 #include <gio/gtask.h>
36 #include "gunixconnection.h"
37 #include "gtcpconnection.h"
38 #include "glibintl.h"
39
40
41 /**
42  * SECTION:gsocketconnection
43  * @short_description: A socket connection
44  * @include: gio/gio.h
45  * @see_also: #GIOStream, #GSocketClient, #GSocketListener
46  *
47  * #GSocketConnection is a #GIOStream for a connected socket. They
48  * can be created either by #GSocketClient when connecting to a host,
49  * or by #GSocketListener when accepting a new client.
50  *
51  * The type of the #GSocketConnection object returned from these calls
52  * depends on the type of the underlying socket that is in use. For
53  * instance, for a TCP/IP connection it will be a #GTcpConnection.
54  *
55  * Choosing what type of object to construct is done with the socket
56  * connection factory, and it is possible for 3rd parties to register
57  * custom socket connection types for specific combination of socket
58  * family/type/protocol using g_socket_connection_factory_register_type().
59  *
60  * Since: 2.22
61  */
62
63 enum
64 {
65   PROP_NONE,
66   PROP_SOCKET,
67 };
68
69 struct _GSocketConnectionPrivate
70 {
71   GSocket       *socket;
72   GInputStream  *input_stream;
73   GOutputStream *output_stream;
74
75   gboolean       in_dispose;
76 };
77
78 static gboolean g_socket_connection_close         (GIOStream            *stream,
79                                                    GCancellable         *cancellable,
80                                                    GError              **error);
81 static void     g_socket_connection_close_async   (GIOStream            *stream,
82                                                    int                   io_priority,
83                                                    GCancellable         *cancellable,
84                                                    GAsyncReadyCallback   callback,
85                                                    gpointer              user_data);
86 static gboolean g_socket_connection_close_finish  (GIOStream            *stream,
87                                                    GAsyncResult         *result,
88                                                    GError              **error);
89
90 G_DEFINE_TYPE_WITH_PRIVATE (GSocketConnection, g_socket_connection, G_TYPE_IO_STREAM)
91
92 static GInputStream *
93 g_socket_connection_get_input_stream (GIOStream *io_stream)
94 {
95   GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
96
97   if (connection->priv->input_stream == NULL)
98     connection->priv->input_stream = (GInputStream *)
99       _g_socket_input_stream_new (connection->priv->socket);
100
101   return connection->priv->input_stream;
102 }
103
104 static GOutputStream *
105 g_socket_connection_get_output_stream (GIOStream *io_stream)
106 {
107   GSocketConnection *connection = G_SOCKET_CONNECTION (io_stream);
108
109   if (connection->priv->output_stream == NULL)
110     connection->priv->output_stream = (GOutputStream *)
111       _g_socket_output_stream_new (connection->priv->socket);
112
113   return connection->priv->output_stream;
114 }
115
116 /**
117  * g_socket_connection_is_connected:
118  * @connection: a #GSocketConnection
119  *
120  * Checks if @connection is connected. This is equivalent to calling
121  * g_socket_is_connected() on @connection's underlying #GSocket.
122  *
123  * Returns: whether @connection is connected
124  *
125  * Since: 2.32
126  */
127 gboolean
128 g_socket_connection_is_connected (GSocketConnection  *connection)
129 {
130   return g_socket_is_connected (connection->priv->socket);
131 }
132
133 /**
134  * g_socket_connection_connect:
135  * @connection: a #GSocketConnection
136  * @address: a #GSocketAddress specifying the remote address.
137  * @cancellable: (allow-none): a %GCancellable or %NULL
138  * @error: #GError for error reporting, or %NULL to ignore.
139  *
140  * Connect @connection to the specified remote address.
141  *
142  * Returns: %TRUE if the connection succeeded, %FALSE on error
143  *
144  * Since: 2.32
145  */
146 gboolean
147 g_socket_connection_connect (GSocketConnection  *connection,
148                              GSocketAddress     *address,
149                              GCancellable       *cancellable,
150                              GError            **error)
151 {
152   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
153   g_return_val_if_fail (G_IS_SOCKET_ADDRESS (address), FALSE);
154
155   return g_socket_connect (connection->priv->socket, address,
156                            cancellable, error);
157 }
158
159 static gboolean g_socket_connection_connect_callback (GSocket      *socket,
160                                                       GIOCondition  condition,
161                                                       gpointer      user_data);
162
163 /**
164  * g_socket_connection_connect_async:
165  * @connection: a #GSocketConnection
166  * @address: a #GSocketAddress specifying the remote address.
167  * @cancellable: (allow-none): a %GCancellable or %NULL
168  * @callback: (scope async): a #GAsyncReadyCallback
169  * @user_data: (closure): user data for the callback
170  *
171  * Asynchronously connect @connection to the specified remote address.
172  *
173  * This clears the #GSocket:blocking flag on @connection's underlying
174  * socket if it is currently set.
175  *
176  * Use g_socket_connection_connect_finish() to retrieve the result.
177  *
178  * Since: 2.32
179  */
180 void
181 g_socket_connection_connect_async (GSocketConnection   *connection,
182                                    GSocketAddress      *address,
183                                    GCancellable        *cancellable,
184                                    GAsyncReadyCallback  callback,
185                                    gpointer             user_data)
186 {
187   GTask *task;
188   GError *tmp_error = NULL;
189
190   g_return_if_fail (G_IS_SOCKET_CONNECTION (connection));
191   g_return_if_fail (G_IS_SOCKET_ADDRESS (address));
192
193   task = g_task_new (connection, cancellable, callback, user_data);
194
195   g_socket_set_blocking (connection->priv->socket, FALSE);
196
197   if (g_socket_connect (connection->priv->socket, address,
198                         cancellable, &tmp_error))
199     {
200       g_task_return_boolean (task, TRUE);
201       g_object_unref (task);
202     }
203   else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
204     {
205       GSource *source;
206
207       g_error_free (tmp_error);
208       source = g_socket_create_source (connection->priv->socket,
209                                        G_IO_OUT, cancellable);
210       g_task_attach_source (task, source,
211                             (GSourceFunc) g_socket_connection_connect_callback);
212       g_source_unref (source);
213     }
214   else
215     {
216       g_task_return_error (task, tmp_error);
217       g_object_unref (task);
218     }
219 }
220
221 static gboolean
222 g_socket_connection_connect_callback (GSocket      *socket,
223                                       GIOCondition  condition,
224                                       gpointer      user_data)
225 {
226   GTask *task = user_data;
227   GSocketConnection *connection = g_task_get_source_object (task);
228   GError *error = NULL;
229
230   if (g_socket_check_connect_result (connection->priv->socket, &error))
231     g_task_return_boolean (task, TRUE);
232   else
233     g_task_return_error (task, error);
234
235   g_object_unref (task);
236   return FALSE;
237 }
238
239 /**
240  * g_socket_connection_connect_finish:
241  * @connection: a #GSocketConnection
242  * @result: the #GAsyncResult
243  * @error: #GError for error reporting, or %NULL to ignore.
244  *
245  * Gets the result of a g_socket_connection_connect_async() call.
246  *
247  * Returns: %TRUE if the connection succeeded, %FALSE on error
248  *
249  * Since: 2.32
250  */
251 gboolean
252 g_socket_connection_connect_finish (GSocketConnection  *connection,
253                                     GAsyncResult       *result,
254                                     GError            **error)
255 {
256   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), FALSE);
257   g_return_val_if_fail (g_task_is_valid (result, connection), FALSE);
258
259   return g_task_propagate_boolean (G_TASK (result), error);
260 }
261
262 /**
263  * g_socket_connection_get_socket:
264  * @connection: a #GSocketConnection
265  *
266  * Gets the underlying #GSocket object of the connection.
267  * This can be useful if you want to do something unusual on it
268  * not supported by the #GSocketConnection APIs.
269  *
270  * Returns: (transfer none): a #GSocketAddress or %NULL on error.
271  *
272  * Since: 2.22
273  */
274 GSocket *
275 g_socket_connection_get_socket (GSocketConnection *connection)
276 {
277   g_return_val_if_fail (G_IS_SOCKET_CONNECTION (connection), NULL);
278
279   return connection->priv->socket;
280 }
281
282 /**
283  * g_socket_connection_get_local_address:
284  * @connection: a #GSocketConnection
285  * @error: #GError for error reporting, or %NULL to ignore.
286  *
287  * Try to get the local address of a socket connection.
288  *
289  * Returns: (transfer full): a #GSocketAddress or %NULL on error.
290  *     Free the returned object with g_object_unref().
291  *
292  * Since: 2.22
293  */
294 GSocketAddress *
295 g_socket_connection_get_local_address (GSocketConnection  *connection,
296                                        GError            **error)
297 {
298   return g_socket_get_local_address (connection->priv->socket, error);
299 }
300
301 /**
302  * g_socket_connection_get_remote_address:
303  * @connection: a #GSocketConnection
304  * @error: #GError for error reporting, or %NULL to ignore.
305  *
306  * Try to get the remote address of a socket connection.
307  *
308  * Returns: (transfer full): a #GSocketAddress or %NULL on error.
309  *     Free the returned object with g_object_unref().
310  *
311  * Since: 2.22
312  */
313 GSocketAddress *
314 g_socket_connection_get_remote_address (GSocketConnection  *connection,
315                                         GError            **error)
316 {
317   return g_socket_get_remote_address (connection->priv->socket, error);
318 }
319
320 static void
321 g_socket_connection_get_property (GObject    *object,
322                                   guint       prop_id,
323                                   GValue     *value,
324                                   GParamSpec *pspec)
325 {
326   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
327
328   switch (prop_id)
329     {
330      case PROP_SOCKET:
331       g_value_set_object (value, connection->priv->socket);
332       break;
333
334      default:
335       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
336     }
337 }
338
339 static void
340 g_socket_connection_set_property (GObject      *object,
341                                   guint         prop_id,
342                                   const GValue *value,
343                                   GParamSpec   *pspec)
344 {
345   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
346
347   switch (prop_id)
348     {
349      case PROP_SOCKET:
350       connection->priv->socket = G_SOCKET (g_value_dup_object (value));
351       break;
352
353      default:
354       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
355     }
356 }
357
358 static void
359 g_socket_connection_constructed (GObject *object)
360 {
361   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
362
363   g_assert (connection->priv->socket != NULL);
364 }
365
366 static void
367 g_socket_connection_dispose (GObject *object)
368 {
369   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
370
371   connection->priv->in_dispose = TRUE;
372
373   G_OBJECT_CLASS (g_socket_connection_parent_class)
374     ->dispose (object);
375
376   connection->priv->in_dispose = FALSE;
377 }
378
379 static void
380 g_socket_connection_finalize (GObject *object)
381 {
382   GSocketConnection *connection = G_SOCKET_CONNECTION (object);
383
384   if (connection->priv->input_stream)
385     g_object_unref (connection->priv->input_stream);
386
387   if (connection->priv->output_stream)
388     g_object_unref (connection->priv->output_stream);
389
390   g_object_unref (connection->priv->socket);
391
392   G_OBJECT_CLASS (g_socket_connection_parent_class)
393     ->finalize (object);
394 }
395
396 static void
397 g_socket_connection_class_init (GSocketConnectionClass *klass)
398 {
399   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
400   GIOStreamClass *stream_class = G_IO_STREAM_CLASS (klass);
401
402   gobject_class->set_property = g_socket_connection_set_property;
403   gobject_class->get_property = g_socket_connection_get_property;
404   gobject_class->constructed = g_socket_connection_constructed;
405   gobject_class->finalize = g_socket_connection_finalize;
406   gobject_class->dispose = g_socket_connection_dispose;
407
408   stream_class->get_input_stream = g_socket_connection_get_input_stream;
409   stream_class->get_output_stream = g_socket_connection_get_output_stream;
410   stream_class->close_fn = g_socket_connection_close;
411   stream_class->close_async = g_socket_connection_close_async;
412   stream_class->close_finish = g_socket_connection_close_finish;
413
414   g_object_class_install_property (gobject_class,
415                                    PROP_SOCKET,
416                                    g_param_spec_object ("socket",
417                                                         P_("Socket"),
418                                                         P_("The underlying GSocket"),
419                                                         G_TYPE_SOCKET,
420                                                         G_PARAM_CONSTRUCT_ONLY |
421                                                         G_PARAM_READWRITE |
422                                                         G_PARAM_STATIC_STRINGS));
423 }
424
425 static void
426 g_socket_connection_init (GSocketConnection *connection)
427 {
428   connection->priv = g_socket_connection_get_private (connection);
429 }
430
431 static gboolean
432 g_socket_connection_close (GIOStream     *stream,
433                            GCancellable  *cancellable,
434                            GError       **error)
435 {
436   GSocketConnection *connection = G_SOCKET_CONNECTION (stream);
437
438   if (connection->priv->output_stream)
439     g_output_stream_close (connection->priv->output_stream,
440                            cancellable, NULL);
441   if (connection->priv->input_stream)
442     g_input_stream_close (connection->priv->input_stream,
443                           cancellable, NULL);
444
445   /* Don't close the underlying socket if this is being called
446    * as part of dispose(); when destroying the GSocketConnection,
447    * we only want to close the socket if we're holding the last
448    * reference on it, and in that case it will close itself when
449    * we unref it in finalize().
450    */
451   if (connection->priv->in_dispose)
452     return TRUE;
453
454   return g_socket_close (connection->priv->socket, error);
455 }
456
457
458 static void
459 g_socket_connection_close_async (GIOStream           *stream,
460                                  int                  io_priority,
461                                  GCancellable        *cancellable,
462                                  GAsyncReadyCallback  callback,
463                                  gpointer             user_data)
464 {
465   GTask *task;
466   GIOStreamClass *class;
467   GError *error;
468
469   class = G_IO_STREAM_GET_CLASS (stream);
470
471   task = g_task_new (stream, cancellable, callback, user_data);
472
473   /* socket close is not blocked, just do it! */
474   error = NULL;
475   if (class->close_fn &&
476       !class->close_fn (stream, cancellable, &error))
477     g_task_return_error (task, error);
478   else
479     g_task_return_boolean (task, TRUE);
480
481   g_object_unref (task);
482 }
483
484 static gboolean
485 g_socket_connection_close_finish (GIOStream     *stream,
486                                   GAsyncResult  *result,
487                                   GError       **error)
488 {
489   return g_task_propagate_boolean (G_TASK (result), error);
490 }
491
492 typedef struct {
493   GSocketFamily socket_family;
494   GSocketType socket_type;
495   int protocol;
496   GType implementation;
497 } ConnectionFactory;
498
499 static guint
500 connection_factory_hash (gconstpointer key)
501 {
502   const ConnectionFactory *factory = key;
503   guint h;
504
505   h = factory->socket_family ^ (factory->socket_type << 4) ^ (factory->protocol << 8);
506   /* This is likely to be small, so spread over whole
507      hash space to get some distribution */
508   h = h ^ (h << 8) ^ (h << 16) ^ (h << 24);
509
510   return h;
511 }
512
513 static gboolean
514 connection_factory_equal (gconstpointer _a,
515                           gconstpointer _b)
516 {
517   const ConnectionFactory *a = _a;
518   const ConnectionFactory *b = _b;
519
520   if (a->socket_family != b->socket_family)
521     return FALSE;
522
523   if (a->socket_type != b->socket_type)
524     return FALSE;
525
526   if (a->protocol != b->protocol)
527     return FALSE;
528
529   return TRUE;
530 }
531
532 static GHashTable *connection_factories = NULL;
533 G_LOCK_DEFINE_STATIC(connection_factories);
534
535 /**
536  * g_socket_connection_factory_register_type:
537  * @g_type: a #GType, inheriting from %G_TYPE_SOCKET_CONNECTION
538  * @family: a #GSocketFamily
539  * @type: a #GSocketType
540  * @protocol: a protocol id
541  *
542  * Looks up the #GType to be used when creating socket connections on
543  * sockets with the specified @family, @type and @protocol.
544  *
545  * If no type is registered, the #GSocketConnection base type is returned.
546  *
547  * Since: 2.22
548  */
549 void
550 g_socket_connection_factory_register_type (GType         g_type,
551                                            GSocketFamily family,
552                                            GSocketType   type,
553                                            gint          protocol)
554 {
555   ConnectionFactory *factory;
556
557   g_return_if_fail (g_type_is_a (g_type, G_TYPE_SOCKET_CONNECTION));
558
559   G_LOCK (connection_factories);
560
561   if (connection_factories == NULL)
562     connection_factories = g_hash_table_new_full (connection_factory_hash,
563                                                   connection_factory_equal,
564                                                   (GDestroyNotify)g_free,
565                                                   NULL);
566
567   factory = g_new0 (ConnectionFactory, 1);
568   factory->socket_family = family;
569   factory->socket_type = type;
570   factory->protocol = protocol;
571   factory->implementation = g_type;
572
573   g_hash_table_insert (connection_factories,
574                        factory, factory);
575
576   G_UNLOCK (connection_factories);
577 }
578
579 static void
580 init_builtin_types (void)
581 {
582 #ifndef G_OS_WIN32
583   g_type_ensure (G_TYPE_UNIX_CONNECTION);
584 #endif
585   g_type_ensure (G_TYPE_TCP_CONNECTION);
586 }
587
588 /**
589  * g_socket_connection_factory_lookup_type:
590  * @family: a #GSocketFamily
591  * @type: a #GSocketType
592  * @protocol_id: a protocol id
593  *
594  * Looks up the #GType to be used when creating socket connections on
595  * sockets with the specified @family, @type and @protocol_id.
596  *
597  * If no type is registered, the #GSocketConnection base type is returned.
598  *
599  * Returns: a #GType
600  *
601  * Since: 2.22
602  */
603 GType
604 g_socket_connection_factory_lookup_type (GSocketFamily family,
605                                          GSocketType   type,
606                                          gint          protocol_id)
607 {
608   ConnectionFactory *factory, key;
609   GType g_type;
610
611   init_builtin_types ();
612
613   G_LOCK (connection_factories);
614
615   g_type = G_TYPE_SOCKET_CONNECTION;
616
617   if (connection_factories)
618     {
619       key.socket_family = family;
620       key.socket_type = type;
621       key.protocol = protocol_id;
622
623       factory = g_hash_table_lookup (connection_factories, &key);
624       if (factory)
625         g_type = factory->implementation;
626     }
627
628   G_UNLOCK (connection_factories);
629
630   return g_type;
631 }
632
633 /**
634  * g_socket_connection_factory_create_connection:
635  * @socket: a #GSocket
636  *
637  * Creates a #GSocketConnection subclass of the right type for
638  * @socket.
639  *
640  * Returns: (transfer full): a #GSocketConnection
641  *
642  * Since: 2.22
643  */
644 GSocketConnection *
645 g_socket_connection_factory_create_connection (GSocket *socket)
646 {
647   GType type;
648
649   type = g_socket_connection_factory_lookup_type (g_socket_get_family (socket),
650                                                   g_socket_get_socket_type (socket),
651                                                   g_socket_get_protocol (socket));
652   return g_object_new (type, "socket", socket, NULL);
653 }