Add bound address out-argument to g_socket_listener_add_address (#585566)
[platform/upstream/glib.git] / gio / gsocketlistener.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
4  * Copyright © 2009 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 #include "gsocketlistener.h"
30
31 #include <gio/gsimpleasyncresult.h>
32 #include <gio/gcancellable.h>
33 #include <gio/gsocketaddress.h>
34 #include <gio/ginetaddress.h>
35 #include <gio/gioerror.h>
36 #include <gio/gsocket.h>
37 #include <gio/gsocketconnection.h>
38 #include <gio/ginetsocketaddress.h>
39 #include "glibintl.h"
40
41 #include "gioalias.h"
42
43 /**
44  * SECTION: gsocketlistener
45  * @title: GSocketListener
46  * @short_description: Helper for accepting network client connections
47  * @see_also: #GThreadedSocketService, #GSocketService.
48  *
49  * A #GSocketListener is an object that keeps track of a set
50  * of server sockets and helps you accept sockets from any of the
51  * socket, either sync or async.
52  *
53  * If you want to implement a network server, also look at #GSocketService
54  * and #GThreadedSocketService which are subclass of #GSocketListener
55  * that makes this even easier.
56  *
57  * Since: 2.22
58  */
59
60 G_DEFINE_TYPE (GSocketListener, g_socket_listener, G_TYPE_OBJECT);
61
62 enum
63 {
64   PROP_0,
65   PROP_LISTEN_BACKLOG
66 };
67
68
69 static GQuark source_quark = 0;
70
71 struct _GSocketListenerPrivate
72 {
73   GPtrArray           *sockets;
74   GMainContext        *main_context;
75   int                 listen_backlog;
76   guint               closed : 1;
77 };
78
79 static void
80 g_socket_listener_finalize (GObject *object)
81 {
82   GSocketListener *listener = G_SOCKET_LISTENER (object);
83
84   if (listener->priv->main_context)
85     g_main_context_unref (listener->priv->main_context);
86
87   if (!listener->priv->closed)
88     g_socket_listener_close (listener);
89
90   g_ptr_array_free (listener->priv->sockets, TRUE);
91
92   G_OBJECT_CLASS (g_socket_listener_parent_class)
93     ->finalize (object);
94 }
95
96 static void
97 g_socket_listener_get_property (GObject    *object,
98                                 guint       prop_id,
99                                 GValue     *value,
100                                 GParamSpec *pspec)
101 {
102   GSocketListener *listener = G_SOCKET_LISTENER (object);
103
104   switch (prop_id)
105     {
106       case PROP_LISTEN_BACKLOG:
107         g_value_set_int (value, listener->priv->listen_backlog);
108         break;
109
110       default:
111         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
112     }
113 }
114
115 static void
116 g_socket_listener_set_property (GObject      *object,
117                                 guint         prop_id,
118                                 const GValue *value,
119                                 GParamSpec   *pspec)
120 {
121   GSocketListener *listener = G_SOCKET_LISTENER (object);
122
123   switch (prop_id)
124     {
125       case PROP_LISTEN_BACKLOG:
126         g_socket_listener_set_backlog (listener, g_value_get_int (value));
127         break;
128
129       default:
130         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
131     }
132 }
133
134
135 static void
136 g_socket_listener_class_init (GSocketListenerClass *klass)
137 {
138   GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
139
140   g_type_class_add_private (klass, sizeof (GSocketListenerPrivate));
141
142   gobject_class->finalize = g_socket_listener_finalize;
143   gobject_class->set_property = g_socket_listener_set_property;
144   gobject_class->get_property = g_socket_listener_get_property;
145   g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG,
146                                    g_param_spec_int ("listen-backlog",
147                                                      P_("Listen backlog"),
148                                                      P_("outstanding connections in the listen queue"),
149                                                      0,
150                                                      2000,
151                                                      10,
152                                                      G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
153
154   source_quark = g_quark_from_static_string ("g-socket-listener-source");
155 }
156
157 static void
158 g_socket_listener_init (GSocketListener *listener)
159 {
160   listener->priv = G_TYPE_INSTANCE_GET_PRIVATE (listener,
161                                                 G_TYPE_SOCKET_LISTENER,
162                                                 GSocketListenerPrivate);
163   listener->priv->sockets =
164     g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
165   listener->priv->listen_backlog = 10;
166 }
167
168 /**
169  * g_socket_listener_new:
170  *
171  * Creates a new #GSocketListener with no sockets to listen for.
172  * New listeners can be added with e.g. g_socket_listener_add_address()
173  * or g_socket_listener_add_inet_port().
174  *
175  * Returns: a new #GSocketListener.
176  *
177  * Since: 2.22
178  */
179 GSocketListener *
180 g_socket_listener_new (void)
181 {
182   return g_object_new (G_TYPE_SOCKET_LISTENER, NULL);
183 }
184
185 static gboolean
186 check_listener (GSocketListener *listener,
187                 GError **error)
188 {
189   if (listener->priv->closed)
190     {
191       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
192                            _("Listener is already closed"));
193       return FALSE;
194     }
195
196   return TRUE;
197 }
198
199 /**
200  * g_socket_listener_add_socket:
201  * @listener: a #GSocketListener
202  * @socket: a listening #GSocket
203  * @source_object: Optional #GObject identifying this source
204  * @error: #GError for error reporting, or %NULL to ignore.
205  *
206  * Adds @socket to the set of sockets that we try to accept
207  * new clients from. The socket must be bound to a local
208  * address and listened to.
209  *
210  * @source_object will be passed out in the various calls
211  * to accept to identify this particular source, which is
212  * useful if you're listening on multiple addresses and do
213  * different things depending on what address is connected to.
214  *
215  * Returns: %TRUE on success, %FALSE on error.
216  *
217  * Since: 2.22
218  */
219 gboolean
220 g_socket_listener_add_socket (GSocketListener  *listener,
221                               GSocket          *socket,
222                               GObject          *source_object,
223                               GError          **error)
224 {
225   if (!check_listener (listener, error))
226     return FALSE;
227
228   /* TODO: Check that socket it is bound & not closed? */
229
230   if (g_socket_is_closed (socket))
231     {
232       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
233                            _("Added socket is closed"));
234       return FALSE;
235     }
236
237   g_ptr_array_add (listener->priv->sockets, socket);
238
239   if (source_object)
240     g_object_set_qdata_full (G_OBJECT (socket), source_quark,
241                              g_object_ref (source_object), g_object_unref);
242
243   return TRUE;
244 }
245
246 /**
247  * g_socket_listener_add_address:
248  * @listener: a #GSocketListener
249  * @address: a #GSocketAddress
250  * @type: a #GSocketType
251  * @protocol: a #GSocketProtocol
252  * @source_object: Optional #GObject identifying this source
253  * @effective_address: location to store the address that was bound to, or %NULL.
254  * @error: #GError for error reporting, or %NULL to ignore.
255  *
256  * Creates a socket of type @type and protocol @protocol, binds
257  * it to @address and adds it to the set of sockets we're accepting
258  * sockets from.
259  *
260  * Note that adding an IPv6 address, depending on the platform,
261  * may or may not result in a listener that also accepts IPv4
262  * connections.  For more determinstic behaviour, see
263  * g_socket_listener_add_inet_port().
264  *
265  * @source_object will be passed out in the various calls
266  * to accept to identify this particular source, which is
267  * useful if you're listening on multiple addresses and do
268  * different things depending on what address is connected to.
269  *
270  * If successful and @effective_address is non-%NULL then it will
271  * be set to the address that the binding actually occured at.  This
272  * is helpful for determining the port number that was used for when
273  * requesting a binding to port 0 (ie: "any port").  This address, if
274  * requested, belongs to the caller and must be freed.
275  *
276  * Returns: %TRUE on success, %FALSE on error.
277  *
278  * Since: 2.22
279  */
280 gboolean
281 g_socket_listener_add_address (GSocketListener  *listener,
282                                GSocketAddress   *address,
283                                GSocketType       type,
284                                GSocketProtocol   protocol,
285                                GObject          *source_object,
286                                GSocketAddress  **effective_address,
287                                GError          **error)
288 {
289   GSocketAddress *local_address;
290   GSocketFamily family;
291   GSocket *socket;
292
293   if (!check_listener (listener, error))
294     return FALSE;
295
296   family = g_socket_address_get_family (address);
297   socket = g_socket_new (family, type, protocol, error);
298   if (socket == NULL)
299     return FALSE;
300
301   g_socket_set_listen_backlog (socket, listener->priv->listen_backlog);
302
303   if (!g_socket_bind (socket, address, TRUE, error) ||
304       !g_socket_listen (socket, error) ||
305       !g_socket_listener_add_socket (listener, socket,
306                                      source_object,
307                                      error))
308     {
309       g_object_unref (socket);
310       return FALSE;
311     }
312
313   if (effective_address)
314     {
315       local_address = g_socket_get_local_address (socket, error);
316       if (local_address == NULL)
317         {
318           g_object_unref (socket);
319           return FALSE;
320         }
321       *effective_address = local_address;
322     }
323
324   if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
325     G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
326
327   return TRUE;
328 }
329
330 /**
331  * g_socket_listener_add_inet_port:
332  * @listener: a #GSocketListener
333  * @port: an IP port number (non-zero)
334  * @source_object: Optional #GObject identifying this source
335  * @error: #GError for error reporting, or %NULL to ignore.
336  *
337  * Helper function for g_socket_listener_add_address() that
338  * creates a TCP/IP socket listening on IPv4 and IPv6 (if
339  * supported) on the specified port on all interfaces.
340  *
341  * @source_object will be passed out in the various calls
342  * to accept to identify this particular source, which is
343  * useful if you're listening on multiple addresses and do
344  * different things depending on what address is connected to.
345  *
346  * Returns: %TRUE on success, %FALSE on error.
347  *
348  * Since: 2.22
349  */
350 gboolean
351 g_socket_listener_add_inet_port (GSocketListener  *listener,
352                                  guint16           port,
353                                  GObject          *source_object,
354                                  GError          **error)
355 {
356   gboolean need_ipv4_socket = TRUE;
357   GSocket *socket4 = NULL;
358   GSocket *socket6;
359
360   g_return_val_if_fail (listener != NULL, FALSE);
361   g_return_val_if_fail (port != 0, FALSE);
362
363   if (!check_listener (listener, error))
364     return FALSE;
365
366   /* first try to create an IPv6 socket */
367   socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
368                           G_SOCKET_TYPE_STREAM,
369                           G_SOCKET_PROTOCOL_DEFAULT,
370                           NULL);
371
372   if (socket6 != NULL)
373     /* IPv6 is supported on this platform, so if we fail now it is
374      * a result of being unable to bind to our port.  Don't fail
375      * silently as a result of this!
376      */
377     {
378       GInetAddress *inet_address;
379       GSocketAddress *address;
380       gboolean result;
381
382       inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
383       address = g_inet_socket_address_new (inet_address, port);
384       g_object_unref (inet_address);
385
386       g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
387
388       result = g_socket_bind (socket6, address, TRUE, error) &&
389                g_socket_listen (socket6, error);
390
391       g_object_unref (address);
392
393       if (!result)
394         {
395           g_object_unref (socket6);
396
397           return FALSE;
398         }
399
400       if (source_object)
401         g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
402                                  g_object_ref (source_object),
403                                  g_object_unref);
404
405       /* If this socket already speaks IPv4 then we are done. */
406       if (g_socket_speaks_ipv4 (socket6))
407         need_ipv4_socket = FALSE;
408     }
409
410   if (need_ipv4_socket)
411     /* We are here for exactly one of the following reasons:
412      *
413      *   - our platform doesn't support IPv6
414      *   - we successfully created an IPv6 socket but it's V6ONLY
415      *
416      * In either case, we need to go ahead and create an IPv4 socket
417      * and fail the call if we can't bind to it.
418      */
419     {
420       socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
421                               G_SOCKET_TYPE_STREAM,
422                               G_SOCKET_PROTOCOL_DEFAULT,
423                               error);
424
425       if (socket4 != NULL)
426         /* IPv4 is supported on this platform, so if we fail now it is
427          * a result of being unable to bind to our port.  Don't fail
428          * silently as a result of this!
429          */
430         {
431           GInetAddress *inet_address;
432           GSocketAddress *address;
433           gboolean result;
434
435           inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
436           address = g_inet_socket_address_new (inet_address, port);
437           g_object_unref (inet_address);
438
439           g_socket_set_listen_backlog (socket4,
440                                        listener->priv->listen_backlog);
441
442           result = g_socket_bind (socket4, address, TRUE, error) &&
443                    g_socket_listen (socket4, error);
444
445           g_object_unref (address);
446
447           if (!result)
448             {
449               g_object_unref (socket4);
450
451               if (socket6 != NULL)
452                 g_object_unref (socket6);
453
454               return FALSE;
455             }
456
457           if (source_object)
458             g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
459                                      g_object_ref (source_object),
460                                      g_object_unref);
461         }
462       else
463         /* Ok.  So IPv4 is not supported on this platform.  If we
464          * succeeded at creating an IPv6 socket then that's OK, but
465          * otherwise we need to tell the user we failed.
466          */
467         {
468           if (socket6 != NULL)
469             g_clear_error (error);
470           else
471             return FALSE;
472         }
473     }
474
475   g_assert (socket6 != NULL || socket4 != NULL);
476
477   if (socket6 != NULL)
478     g_ptr_array_add (listener->priv->sockets, socket6);
479
480   if (socket4 != NULL)
481     g_ptr_array_add (listener->priv->sockets, socket4);
482
483   if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
484     G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
485
486   return TRUE;
487 }
488
489 static GList *
490 add_sources (GSocketListener   *listener,
491              GSocketSourceFunc  callback,
492              gpointer           callback_data,
493              GCancellable      *cancellable,
494              GMainContext      *context)
495 {
496   GSocket *socket;
497   GSource *source;
498   GList *sources;
499   int i;
500
501   sources = NULL;
502   for (i = 0; i < listener->priv->sockets->len; i++)
503     {
504       socket = listener->priv->sockets->pdata[i];
505
506       source = g_socket_create_source (socket, G_IO_IN, cancellable);
507       g_source_set_callback (source,
508                              (GSourceFunc) callback,
509                              callback_data, NULL);
510       g_source_attach (source, context);
511
512       sources = g_list_prepend (sources, source);
513     }
514
515   return sources;
516 }
517
518 static void
519 free_sources (GList *sources)
520 {
521   GSource *source;
522   while (sources != NULL)
523     {
524       source = sources->data;
525       sources = g_list_delete_link (sources, sources);
526       g_source_destroy (source);
527       g_source_unref (source);
528     }
529 }
530
531 struct AcceptData {
532   GMainLoop *loop;
533   GSocket *socket;
534 };
535
536 static gboolean
537 accept_callback (GSocket      *socket,
538                  GIOCondition  condition,
539                  gpointer      user_data)
540 {
541   struct AcceptData *data = user_data;
542
543   data->socket = socket;
544   g_main_loop_quit (data->loop);
545
546   return TRUE;
547 }
548
549 /**
550  * g_socket_listener_accept_socket:
551  * @listener: a #GSocketListener
552  * @source_object: location where #GObject pointer will be stored, or %NULL
553  * @cancellable: optional #GCancellable object, %NULL to ignore.
554  * @error: #GError for error reporting, or %NULL to ignore.
555  *
556  * Blocks waiting for a client to connect to any of the sockets added
557  * to the listener. Returns the #GSocket that was accepted.
558  *
559  * If you want to accept the high-level #GSocketConnection, not a #GSocket,
560  * which is often the case, then you should use g_socket_listener_accept()
561  * instead.
562  *
563  * If @source_object is not %NULL it will be filled out with the source
564  * object specified when the corresponding socket or address was added
565  * to the listener.
566  *
567  * If @cancellable is not %NULL, then the operation can be cancelled by
568  * triggering the cancellable object from another thread. If the operation
569  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
570  *
571  * Returns: a #GSocket on success, %NULL on error.
572  *
573  * Since: 2.22
574  */
575 GSocket *
576 g_socket_listener_accept_socket (GSocketListener  *listener,
577                                  GObject         **source_object,
578                                  GCancellable     *cancellable,
579                                  GError          **error)
580 {
581   GSocket *accept_socket, *socket;
582
583   g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
584
585   if (!check_listener (listener, error))
586     return NULL;
587
588   if (listener->priv->sockets->len == 1)
589     {
590       accept_socket = listener->priv->sockets->pdata[0];
591       if (!g_socket_condition_wait (accept_socket, G_IO_IN,
592                                     cancellable, error))
593         return NULL;
594     }
595   else
596     {
597       GList *sources;
598       struct AcceptData data;
599       GMainLoop *loop;
600
601       if (listener->priv->main_context == NULL)
602         listener->priv->main_context = g_main_context_new ();
603
604       loop = g_main_loop_new (listener->priv->main_context, FALSE);
605       data.loop = loop;
606       sources = add_sources (listener,
607                              accept_callback,
608                              &data,
609                              cancellable,
610                              listener->priv->main_context);
611       g_main_loop_run (loop);
612       accept_socket = data.socket;
613       free_sources (sources);
614       g_main_loop_unref (loop);
615     }
616
617   if (!(socket = g_socket_accept (accept_socket, error)))
618     return NULL;
619
620   if (source_object)
621     *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
622
623   return socket;
624 }
625
626 /**
627  * g_socket_listener_accept:
628  * @listener: a #GSocketListener
629  * @source_object: location where #GObject pointer will be stored, or %NULL
630  * @cancellable: optional #GCancellable object, %NULL to ignore.
631  * @error: #GError for error reporting, or %NULL to ignore.
632  *
633  * Blocks waiting for a client to connect to any of the sockets added
634  * to the listener. Returns a #GSocketConnection for the socket that was
635  * accepted.
636  *
637  * If @source_object is not %NULL it will be filled out with the source
638  * object specified when the corresponding socket or address was added
639  * to the listener.
640  *
641  * If @cancellable is not %NULL, then the operation can be cancelled by
642  * triggering the cancellable object from another thread. If the operation
643  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
644  *
645  * Returns: a #GSocketConnection on success, %NULL on error.
646  *
647  * Since: 2.22
648  */
649 GSocketConnection *
650 g_socket_listener_accept (GSocketListener  *listener,
651                           GObject         **source_object,
652                           GCancellable     *cancellable,
653                           GError          **error)
654 {
655   GSocketConnection *connection;
656   GSocket *socket;
657
658   socket = g_socket_listener_accept_socket (listener,
659                                             source_object,
660                                             cancellable,
661                                             error);
662   if (socket == NULL)
663     return NULL;
664
665   connection = g_socket_connection_factory_create_connection (socket);
666   g_object_unref (socket);
667
668   return connection;
669 }
670
671 struct AcceptAsyncData {
672   GSimpleAsyncResult *simple;
673   GCancellable *cancellable;
674   GList *sources;
675 };
676
677 static gboolean
678 accept_ready (GSocket      *accept_socket,
679               GIOCondition  condition,
680               gpointer      _data)
681 {
682   struct AcceptAsyncData *data = _data;
683   GError *error = NULL;
684
685   if (!g_cancellable_set_error_if_cancelled (data->cancellable,
686                                              &error))
687     {
688       GSocket *socket;
689       GObject *source_object;
690
691       socket = g_socket_accept (accept_socket, &error);
692       if (socket)
693         {
694           g_simple_async_result_set_op_res_gpointer (data->simple, socket,
695                                                      g_object_unref);
696           source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
697           if (source_object)
698             g_object_set_qdata_full (G_OBJECT (data->simple),
699                                      source_quark,
700                                      g_object_ref (source_object), g_object_unref);
701         }
702     }
703
704   if (error)
705     {
706       g_simple_async_result_set_from_error (data->simple, error);
707       g_error_free (error);
708     }
709
710   g_simple_async_result_complete_in_idle (data->simple);
711   g_object_unref (data->simple);
712   free_sources (data->sources);
713   g_free (data);
714
715   return FALSE;
716 }
717
718 /**
719  * g_socket_listener_accept_socket_async:
720  * @listener: a #GSocketListener
721  * @cancellable: a #GCancellable, or %NULL
722  * @callback: a #GAsyncReadyCallback
723  * @user_data: user data for the callback
724  *
725  * This is the asynchronous version of g_socket_listener_accept_socket().
726  *
727  * When the operation is finished @callback will be
728  * called. You can then call g_socket_listener_accept_socket_finish()
729  * to get the result of the operation.
730  *
731  * Since: 2.22
732  */
733 void
734 g_socket_listener_accept_socket_async (GSocketListener     *listener,
735                                        GCancellable        *cancellable,
736                                        GAsyncReadyCallback  callback,
737                                        gpointer             user_data)
738 {
739   struct AcceptAsyncData *data;
740   GError *error = NULL;
741
742   if (!check_listener (listener, &error))
743     {
744       g_simple_async_report_gerror_in_idle (G_OBJECT (listener),
745                                             callback, user_data,
746                                             error);
747       g_error_free (error);
748       return;
749     }
750
751   data = g_new0 (struct AcceptAsyncData, 1);
752   data->simple = g_simple_async_result_new (G_OBJECT (listener),
753                                             callback, user_data,
754                                             g_socket_listener_accept_socket_async);
755   data->cancellable = cancellable;
756   data->sources = add_sources (listener,
757                                accept_ready,
758                                data,
759                                cancellable,
760                                NULL);
761 }
762
763 /**
764  * g_socket_listener_accept_socket_finish:
765  * @listener: a #GSocketListener
766  * @result: a #GAsyncResult.
767  * @source_object: Optional #GObject identifying this source
768  * @error: a #GError location to store the error occuring, or %NULL to
769  * ignore.
770  *
771  * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
772  *
773  * Returns: a #GSocket on success, %NULL on error.
774  *
775  * Since: 2.22
776  */
777 GSocket *
778 g_socket_listener_accept_socket_finish (GSocketListener  *listener,
779                                         GAsyncResult     *result,
780                                         GObject         **source_object,
781                                         GError          **error)
782 {
783   GSocket *socket;
784   GSimpleAsyncResult *simple;
785
786   g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), FALSE);
787
788   simple = G_SIMPLE_ASYNC_RESULT (result);
789
790   if (g_simple_async_result_propagate_error (simple, error))
791     return NULL;
792
793   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_listener_accept_socket_async);
794
795   socket = g_simple_async_result_get_op_res_gpointer (simple);
796
797   if (source_object)
798     *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
799
800   return g_object_ref (socket);
801 }
802
803 /**
804  * g_socket_listener_accept_async:
805  * @listener: a #GSocketListener
806  * @cancellable: a #GCancellable, or %NULL
807  * @callback: a #GAsyncReadyCallback
808  * @user_data: user data for the callback
809  *
810  * This is the asynchronous version of g_socket_listener_accept().
811  *
812  * When the operation is finished @callback will be
813  * called. You can then call g_socket_listener_accept_socket()
814  * to get the result of the operation.
815  *
816  * Since: 2.22
817  */
818 void
819 g_socket_listener_accept_async (GSocketListener     *listener,
820                                 GCancellable        *cancellable,
821                                 GAsyncReadyCallback  callback,
822                                 gpointer             user_data)
823 {
824   g_socket_listener_accept_socket_async (listener,
825                                          cancellable,
826                                          callback,
827                                          user_data);
828 }
829
830 /**
831  * g_socket_listener_accept_finish:
832  * @listener: a #GSocketListener
833  * @result: a #GAsyncResult.
834  * @source_object: Optional #GObject identifying this source
835  * @error: a #GError location to store the error occuring, or %NULL to
836  * ignore.
837  *
838  * Finishes an async accept operation. See g_socket_listener_accept_async()
839  *
840  * Returns: a #GSocketConnection on success, %NULL on error.
841  *
842  * Since: 2.22
843  */
844 GSocketConnection *
845 g_socket_listener_accept_finish (GSocketListener  *listener,
846                                  GAsyncResult     *result,
847                                  GObject         **source_object,
848                                  GError          **error)
849 {
850   GSocket *socket;
851   GSocketConnection *connection;
852
853   socket = g_socket_listener_accept_socket_finish (listener,
854                                                    result,
855                                                    source_object,
856                                                    error);
857   if (socket == NULL)
858     return NULL;
859
860   connection = g_socket_connection_factory_create_connection (socket);
861   g_object_unref (socket);
862   return connection;
863 }
864
865 /**
866  * g_socket_listener_set_backlog:
867  * @listener: a #GSocketListener
868  * @listen_backlog: an integer
869  *
870  * Sets the listen backlog on the sockets in the listener.
871  *
872  * See g_socket_set_listen_backlog() for details
873  *
874  * Since: 2.22
875  */
876 void
877 g_socket_listener_set_backlog (GSocketListener *listener,
878                                int              listen_backlog)
879 {
880   GSocket *socket;
881   int i;
882
883   if (listener->priv->closed)
884     return;
885
886   listener->priv->listen_backlog = listen_backlog;
887
888   for (i = 0; i < listener->priv->sockets->len; i++)
889     {
890       socket = listener->priv->sockets->pdata[i];
891       g_socket_set_listen_backlog (socket, listen_backlog);
892     }
893 }
894
895 /**
896  * g_socket_listener_close:
897  * @listener: a #GSocketListener
898  *
899  * Closes all the sockets in the listener.
900  *
901  * Since: 2.22
902  */
903 void
904 g_socket_listener_close (GSocketListener *listener)
905 {
906   GSocket *socket;
907   int i;
908
909   g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
910
911   if (listener->priv->closed)
912     return;
913
914   for (i = 0; i < listener->priv->sockets->len; i++)
915     {
916       socket = listener->priv->sockets->pdata[i];
917       g_socket_close (socket, NULL);
918     }
919   listener->priv->closed = TRUE;
920 }
921
922 #define __G_SOCKET_LISTENER_C__
923 #include "gioaliasdef.c"