Coverage Report

Created: 2026-06-14 06:15

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