GSettings: small internal refactor
[glib.git] / gio / gsocketlistener.c
blob8d6b19e8369e8d42f0971fbd9ff897a989f49539
1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2008 Christian Kellner, Samuel Cormier-Iijima
4 * Copyright © 2009 codethink
5 * Copyright © 2009 Red Hat, Inc
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.
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.
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.
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>
28 #include "config.h"
29 #include "gsocketlistener.h"
31 #include <gio/gtask.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"
42 /**
43 * SECTION:gsocketlistener
44 * @title: GSocketListener
45 * @short_description: Helper for accepting network client connections
46 * @see_also: #GThreadedSocketService, #GSocketService.
48 * A #GSocketListener is an object that keeps track of a set
49 * of server sockets and helps you accept sockets from any of the
50 * socket, either sync or async.
52 * If you want to implement a network server, also look at #GSocketService
53 * and #GThreadedSocketService which are subclass of #GSocketListener
54 * that makes this even easier.
56 * Since: 2.22
59 enum
61 PROP_0,
62 PROP_LISTEN_BACKLOG
66 static GQuark source_quark = 0;
68 struct _GSocketListenerPrivate
70 GPtrArray *sockets;
71 GMainContext *main_context;
72 int listen_backlog;
73 guint closed : 1;
76 G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener, g_socket_listener, G_TYPE_OBJECT)
78 static void
79 g_socket_listener_finalize (GObject *object)
81 GSocketListener *listener = G_SOCKET_LISTENER (object);
83 if (listener->priv->main_context)
84 g_main_context_unref (listener->priv->main_context);
86 if (!listener->priv->closed)
87 g_socket_listener_close (listener);
89 g_ptr_array_free (listener->priv->sockets, TRUE);
91 G_OBJECT_CLASS (g_socket_listener_parent_class)
92 ->finalize (object);
95 static void
96 g_socket_listener_get_property (GObject *object,
97 guint prop_id,
98 GValue *value,
99 GParamSpec *pspec)
101 GSocketListener *listener = G_SOCKET_LISTENER (object);
103 switch (prop_id)
105 case PROP_LISTEN_BACKLOG:
106 g_value_set_int (value, listener->priv->listen_backlog);
107 break;
109 default:
110 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
114 static void
115 g_socket_listener_set_property (GObject *object,
116 guint prop_id,
117 const GValue *value,
118 GParamSpec *pspec)
120 GSocketListener *listener = G_SOCKET_LISTENER (object);
122 switch (prop_id)
124 case PROP_LISTEN_BACKLOG:
125 g_socket_listener_set_backlog (listener, g_value_get_int (value));
126 break;
128 default:
129 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
134 static void
135 g_socket_listener_class_init (GSocketListenerClass *klass)
137 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
139 gobject_class->finalize = g_socket_listener_finalize;
140 gobject_class->set_property = g_socket_listener_set_property;
141 gobject_class->get_property = g_socket_listener_get_property;
142 g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG,
143 g_param_spec_int ("listen-backlog",
144 P_("Listen backlog"),
145 P_("outstanding connections in the listen queue"),
147 2000,
149 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
151 source_quark = g_quark_from_static_string ("g-socket-listener-source");
154 static void
155 g_socket_listener_init (GSocketListener *listener)
157 listener->priv = g_socket_listener_get_instance_private (listener);
158 listener->priv->sockets =
159 g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
160 listener->priv->listen_backlog = 10;
164 * g_socket_listener_new:
166 * Creates a new #GSocketListener with no sockets to listen for.
167 * New listeners can be added with e.g. g_socket_listener_add_address()
168 * or g_socket_listener_add_inet_port().
170 * Returns: a new #GSocketListener.
172 * Since: 2.22
174 GSocketListener *
175 g_socket_listener_new (void)
177 return g_object_new (G_TYPE_SOCKET_LISTENER, NULL);
180 static gboolean
181 check_listener (GSocketListener *listener,
182 GError **error)
184 if (listener->priv->closed)
186 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
187 _("Listener is already closed"));
188 return FALSE;
191 return TRUE;
195 * g_socket_listener_add_socket:
196 * @listener: a #GSocketListener
197 * @socket: a listening #GSocket
198 * @source_object: (allow-none): Optional #GObject identifying this source
199 * @error: #GError for error reporting, or %NULL to ignore.
201 * Adds @socket to the set of sockets that we try to accept
202 * new clients from. The socket must be bound to a local
203 * address and listened to.
205 * @source_object will be passed out in the various calls
206 * to accept to identify this particular source, which is
207 * useful if you're listening on multiple addresses and do
208 * different things depending on what address is connected to.
210 * Returns: %TRUE on success, %FALSE on error.
212 * Since: 2.22
214 gboolean
215 g_socket_listener_add_socket (GSocketListener *listener,
216 GSocket *socket,
217 GObject *source_object,
218 GError **error)
220 if (!check_listener (listener, error))
221 return FALSE;
223 /* TODO: Check that socket it is bound & not closed? */
225 if (g_socket_is_closed (socket))
227 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
228 _("Added socket is closed"));
229 return FALSE;
232 g_object_ref (socket);
233 g_ptr_array_add (listener->priv->sockets, socket);
235 if (source_object)
236 g_object_set_qdata_full (G_OBJECT (socket), source_quark,
237 g_object_ref (source_object), g_object_unref);
240 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
241 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
243 return TRUE;
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: (allow-none): Optional #GObject identifying this source
253 * @effective_address: (out) (allow-none): location to store the address that was bound to, or %NULL.
254 * @error: #GError for error reporting, or %NULL to ignore.
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.
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 deterministic behavior, see
263 * g_socket_listener_add_inet_port().
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.
270 * If successful and @effective_address is non-%NULL then it will
271 * be set to the address that the binding actually occurred 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.
276 * Returns: %TRUE on success, %FALSE on error.
278 * Since: 2.22
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)
289 GSocketAddress *local_address;
290 GSocketFamily family;
291 GSocket *socket;
293 if (!check_listener (listener, error))
294 return FALSE;
296 family = g_socket_address_get_family (address);
297 socket = g_socket_new (family, type, protocol, error);
298 if (socket == NULL)
299 return FALSE;
301 g_socket_set_listen_backlog (socket, listener->priv->listen_backlog);
303 if (!g_socket_bind (socket, address, TRUE, error) ||
304 !g_socket_listen (socket, error))
306 g_object_unref (socket);
307 return FALSE;
310 local_address = NULL;
311 if (effective_address)
313 local_address = g_socket_get_local_address (socket, error);
314 if (local_address == NULL)
316 g_object_unref (socket);
317 return FALSE;
321 if (!g_socket_listener_add_socket (listener, socket,
322 source_object,
323 error))
325 if (local_address)
326 g_object_unref (local_address);
327 g_object_unref (socket);
328 return FALSE;
331 if (effective_address)
332 *effective_address = local_address;
334 g_object_unref (socket); /* add_socket refs this */
336 return TRUE;
340 * g_socket_listener_add_inet_port:
341 * @listener: a #GSocketListener
342 * @port: an IP port number (non-zero)
343 * @source_object: (allow-none): Optional #GObject identifying this source
344 * @error: #GError for error reporting, or %NULL to ignore.
346 * Helper function for g_socket_listener_add_address() that
347 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
348 * supported) on the specified port on all interfaces.
350 * @source_object will be passed out in the various calls
351 * to accept to identify this particular source, which is
352 * useful if you're listening on multiple addresses and do
353 * different things depending on what address is connected to.
355 * Returns: %TRUE on success, %FALSE on error.
357 * Since: 2.22
359 gboolean
360 g_socket_listener_add_inet_port (GSocketListener *listener,
361 guint16 port,
362 GObject *source_object,
363 GError **error)
365 gboolean need_ipv4_socket = TRUE;
366 GSocket *socket4 = NULL;
367 GSocket *socket6;
369 g_return_val_if_fail (listener != NULL, FALSE);
370 g_return_val_if_fail (port != 0, FALSE);
372 if (!check_listener (listener, error))
373 return FALSE;
375 /* first try to create an IPv6 socket */
376 socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
377 G_SOCKET_TYPE_STREAM,
378 G_SOCKET_PROTOCOL_DEFAULT,
379 NULL);
381 if (socket6 != NULL)
382 /* IPv6 is supported on this platform, so if we fail now it is
383 * a result of being unable to bind to our port. Don't fail
384 * silently as a result of this!
387 GInetAddress *inet_address;
388 GSocketAddress *address;
389 gboolean result;
391 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
392 address = g_inet_socket_address_new (inet_address, port);
393 g_object_unref (inet_address);
395 g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
397 result = g_socket_bind (socket6, address, TRUE, error) &&
398 g_socket_listen (socket6, error);
400 g_object_unref (address);
402 if (!result)
404 g_object_unref (socket6);
406 return FALSE;
409 if (source_object)
410 g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
411 g_object_ref (source_object),
412 g_object_unref);
414 /* If this socket already speaks IPv4 then we are done. */
415 if (g_socket_speaks_ipv4 (socket6))
416 need_ipv4_socket = FALSE;
419 if (need_ipv4_socket)
420 /* We are here for exactly one of the following reasons:
422 * - our platform doesn't support IPv6
423 * - we successfully created an IPv6 socket but it's V6ONLY
425 * In either case, we need to go ahead and create an IPv4 socket
426 * and fail the call if we can't bind to it.
429 socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
430 G_SOCKET_TYPE_STREAM,
431 G_SOCKET_PROTOCOL_DEFAULT,
432 error);
434 if (socket4 != NULL)
435 /* IPv4 is supported on this platform, so if we fail now it is
436 * a result of being unable to bind to our port. Don't fail
437 * silently as a result of this!
440 GInetAddress *inet_address;
441 GSocketAddress *address;
442 gboolean result;
444 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
445 address = g_inet_socket_address_new (inet_address, port);
446 g_object_unref (inet_address);
448 g_socket_set_listen_backlog (socket4,
449 listener->priv->listen_backlog);
451 result = g_socket_bind (socket4, address, TRUE, error) &&
452 g_socket_listen (socket4, error);
454 g_object_unref (address);
456 if (!result)
458 g_object_unref (socket4);
460 if (socket6 != NULL)
461 g_object_unref (socket6);
463 return FALSE;
466 if (source_object)
467 g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
468 g_object_ref (source_object),
469 g_object_unref);
471 else
472 /* Ok. So IPv4 is not supported on this platform. If we
473 * succeeded at creating an IPv6 socket then that's OK, but
474 * otherwise we need to tell the user we failed.
477 if (socket6 != NULL)
478 g_clear_error (error);
479 else
480 return FALSE;
484 g_assert (socket6 != NULL || socket4 != NULL);
486 if (socket6 != NULL)
487 g_ptr_array_add (listener->priv->sockets, socket6);
489 if (socket4 != NULL)
490 g_ptr_array_add (listener->priv->sockets, socket4);
492 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
493 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
495 return TRUE;
498 static GList *
499 add_sources (GSocketListener *listener,
500 GSocketSourceFunc callback,
501 gpointer callback_data,
502 GCancellable *cancellable,
503 GMainContext *context)
505 GSocket *socket;
506 GSource *source;
507 GList *sources;
508 int i;
510 sources = NULL;
511 for (i = 0; i < listener->priv->sockets->len; i++)
513 socket = listener->priv->sockets->pdata[i];
515 source = g_socket_create_source (socket, G_IO_IN, cancellable);
516 g_source_set_callback (source,
517 (GSourceFunc) callback,
518 callback_data, NULL);
519 g_source_attach (source, context);
521 sources = g_list_prepend (sources, source);
524 return sources;
527 static void
528 free_sources (GList *sources)
530 GSource *source;
531 while (sources != NULL)
533 source = sources->data;
534 sources = g_list_delete_link (sources, sources);
535 g_source_destroy (source);
536 g_source_unref (source);
540 struct AcceptData {
541 GMainLoop *loop;
542 GSocket *socket;
545 static gboolean
546 accept_callback (GSocket *socket,
547 GIOCondition condition,
548 gpointer user_data)
550 struct AcceptData *data = user_data;
552 data->socket = socket;
553 g_main_loop_quit (data->loop);
555 return TRUE;
559 * g_socket_listener_accept_socket:
560 * @listener: a #GSocketListener
561 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL.
562 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
563 * @error: #GError for error reporting, or %NULL to ignore.
565 * Blocks waiting for a client to connect to any of the sockets added
566 * to the listener. Returns the #GSocket that was accepted.
568 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
569 * which is often the case, then you should use g_socket_listener_accept()
570 * instead.
572 * If @source_object is not %NULL it will be filled out with the source
573 * object specified when the corresponding socket or address was added
574 * to the listener.
576 * If @cancellable is not %NULL, then the operation can be cancelled by
577 * triggering the cancellable object from another thread. If the operation
578 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
580 * Returns: (transfer full): a #GSocket on success, %NULL on error.
582 * Since: 2.22
584 GSocket *
585 g_socket_listener_accept_socket (GSocketListener *listener,
586 GObject **source_object,
587 GCancellable *cancellable,
588 GError **error)
590 GSocket *accept_socket, *socket;
592 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
594 if (!check_listener (listener, error))
595 return NULL;
597 if (listener->priv->sockets->len == 1)
599 accept_socket = listener->priv->sockets->pdata[0];
600 if (!g_socket_condition_wait (accept_socket, G_IO_IN,
601 cancellable, error))
602 return NULL;
604 else
606 GList *sources;
607 struct AcceptData data;
608 GMainLoop *loop;
610 if (listener->priv->main_context == NULL)
611 listener->priv->main_context = g_main_context_new ();
613 loop = g_main_loop_new (listener->priv->main_context, FALSE);
614 data.loop = loop;
615 sources = add_sources (listener,
616 accept_callback,
617 &data,
618 cancellable,
619 listener->priv->main_context);
620 g_main_loop_run (loop);
621 accept_socket = data.socket;
622 free_sources (sources);
623 g_main_loop_unref (loop);
626 if (!(socket = g_socket_accept (accept_socket, cancellable, error)))
627 return NULL;
629 if (source_object)
630 *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
632 return socket;
636 * g_socket_listener_accept:
637 * @listener: a #GSocketListener
638 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL
639 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
640 * @error: #GError for error reporting, or %NULL to ignore.
642 * Blocks waiting for a client to connect to any of the sockets added
643 * to the listener. Returns a #GSocketConnection for the socket that was
644 * accepted.
646 * If @source_object is not %NULL it will be filled out with the source
647 * object specified when the corresponding socket or address was added
648 * to the listener.
650 * If @cancellable is not %NULL, then the operation can be cancelled by
651 * triggering the cancellable object from another thread. If the operation
652 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
654 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
656 * Since: 2.22
658 GSocketConnection *
659 g_socket_listener_accept (GSocketListener *listener,
660 GObject **source_object,
661 GCancellable *cancellable,
662 GError **error)
664 GSocketConnection *connection;
665 GSocket *socket;
667 socket = g_socket_listener_accept_socket (listener,
668 source_object,
669 cancellable,
670 error);
671 if (socket == NULL)
672 return NULL;
674 connection = g_socket_connection_factory_create_connection (socket);
675 g_object_unref (socket);
677 return connection;
680 static gboolean
681 accept_ready (GSocket *accept_socket,
682 GIOCondition condition,
683 gpointer user_data)
685 GTask *task = user_data;
686 GError *error = NULL;
687 GSocket *socket;
688 GObject *source_object;
690 socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
691 if (socket)
693 source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
694 if (source_object)
695 g_object_set_qdata_full (G_OBJECT (task),
696 source_quark,
697 g_object_ref (source_object), g_object_unref);
698 g_task_return_pointer (task, socket, g_object_unref);
700 else
702 g_task_return_error (task, error);
705 g_object_unref (task);
706 return FALSE;
710 * g_socket_listener_accept_socket_async:
711 * @listener: a #GSocketListener
712 * @cancellable: (allow-none): a #GCancellable, or %NULL
713 * @callback: (scope async): a #GAsyncReadyCallback
714 * @user_data: (closure): user data for the callback
716 * This is the asynchronous version of g_socket_listener_accept_socket().
718 * When the operation is finished @callback will be
719 * called. You can then call g_socket_listener_accept_socket_finish()
720 * to get the result of the operation.
722 * Since: 2.22
724 void
725 g_socket_listener_accept_socket_async (GSocketListener *listener,
726 GCancellable *cancellable,
727 GAsyncReadyCallback callback,
728 gpointer user_data)
730 GTask *task;
731 GList *sources;
732 GError *error = NULL;
734 task = g_task_new (listener, cancellable, callback, user_data);
736 if (!check_listener (listener, &error))
738 g_task_return_error (task, error);
739 g_object_unref (task);
740 return;
743 sources = add_sources (listener,
744 accept_ready,
745 task,
746 cancellable,
747 g_main_context_get_thread_default ());
748 g_task_set_task_data (task, sources, (GDestroyNotify) free_sources);
752 * g_socket_listener_accept_socket_finish:
753 * @listener: a #GSocketListener
754 * @result: a #GAsyncResult.
755 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
756 * @error: a #GError location to store the error occurring, or %NULL to
757 * ignore.
759 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
761 * Returns: (transfer full): a #GSocket on success, %NULL on error.
763 * Since: 2.22
765 GSocket *
766 g_socket_listener_accept_socket_finish (GSocketListener *listener,
767 GAsyncResult *result,
768 GObject **source_object,
769 GError **error)
771 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
772 g_return_val_if_fail (g_task_is_valid (result, listener), NULL);
774 if (source_object)
775 *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
777 return g_task_propagate_pointer (G_TASK (result), error);
781 * g_socket_listener_accept_async:
782 * @listener: a #GSocketListener
783 * @cancellable: (allow-none): a #GCancellable, or %NULL
784 * @callback: (scope async): a #GAsyncReadyCallback
785 * @user_data: (closure): user data for the callback
787 * This is the asynchronous version of g_socket_listener_accept().
789 * When the operation is finished @callback will be
790 * called. You can then call g_socket_listener_accept_socket()
791 * to get the result of the operation.
793 * Since: 2.22
795 void
796 g_socket_listener_accept_async (GSocketListener *listener,
797 GCancellable *cancellable,
798 GAsyncReadyCallback callback,
799 gpointer user_data)
801 g_socket_listener_accept_socket_async (listener,
802 cancellable,
803 callback,
804 user_data);
808 * g_socket_listener_accept_finish:
809 * @listener: a #GSocketListener
810 * @result: a #GAsyncResult.
811 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
812 * @error: a #GError location to store the error occurring, or %NULL to
813 * ignore.
815 * Finishes an async accept operation. See g_socket_listener_accept_async()
817 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
819 * Since: 2.22
821 GSocketConnection *
822 g_socket_listener_accept_finish (GSocketListener *listener,
823 GAsyncResult *result,
824 GObject **source_object,
825 GError **error)
827 GSocket *socket;
828 GSocketConnection *connection;
830 socket = g_socket_listener_accept_socket_finish (listener,
831 result,
832 source_object,
833 error);
834 if (socket == NULL)
835 return NULL;
837 connection = g_socket_connection_factory_create_connection (socket);
838 g_object_unref (socket);
839 return connection;
843 * g_socket_listener_set_backlog:
844 * @listener: a #GSocketListener
845 * @listen_backlog: an integer
847 * Sets the listen backlog on the sockets in the listener.
849 * See g_socket_set_listen_backlog() for details
851 * Since: 2.22
853 void
854 g_socket_listener_set_backlog (GSocketListener *listener,
855 int listen_backlog)
857 GSocket *socket;
858 int i;
860 if (listener->priv->closed)
861 return;
863 listener->priv->listen_backlog = listen_backlog;
865 for (i = 0; i < listener->priv->sockets->len; i++)
867 socket = listener->priv->sockets->pdata[i];
868 g_socket_set_listen_backlog (socket, listen_backlog);
873 * g_socket_listener_close:
874 * @listener: a #GSocketListener
876 * Closes all the sockets in the listener.
878 * Since: 2.22
880 void
881 g_socket_listener_close (GSocketListener *listener)
883 GSocket *socket;
884 int i;
886 g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
888 if (listener->priv->closed)
889 return;
891 for (i = 0; i < listener->priv->sockets->len; i++)
893 socket = listener->priv->sockets->pdata[i];
894 g_socket_close (socket, NULL);
896 listener->priv->closed = TRUE;
900 * g_socket_listener_add_any_inet_port:
901 * @listener: a #GSocketListener
902 * @source_object: (allow-none): Optional #GObject identifying this source
903 * @error: a #GError location to store the error occurring, or %NULL to
904 * ignore.
906 * Listens for TCP connections on any available port number for both
907 * IPv6 and IPv4 (if each is available).
909 * This is useful if you need to have a socket for incoming connections
910 * but don't care about the specific port number.
912 * @source_object will be passed out in the various calls
913 * to accept to identify this particular source, which is
914 * useful if you're listening on multiple addresses and do
915 * different things depending on what address is connected to.
917 * Returns: the port number, or 0 in case of failure.
919 * Since: 2.24
921 guint16
922 g_socket_listener_add_any_inet_port (GSocketListener *listener,
923 GObject *source_object,
924 GError **error)
926 GSList *sockets_to_close = NULL;
927 guint16 candidate_port = 0;
928 GSocket *socket6 = NULL;
929 GSocket *socket4 = NULL;
930 gint attempts = 37;
933 * multi-step process:
934 * - first, create an IPv6 socket.
935 * - if that fails, create an IPv4 socket and bind it to port 0 and
936 * that's it. no retries if that fails (why would it?).
937 * - if our IPv6 socket also speaks IPv4 then we are done.
938 * - if not, then we need to create a IPv4 socket with the same port
939 * number. this might fail, of course. so we try this a bunch of
940 * times -- leaving the old IPv6 sockets open so that we get a
941 * different port number to try each time.
942 * - if all that fails then just give up.
945 while (attempts--)
947 GInetAddress *inet_address;
948 GSocketAddress *address;
949 gboolean result;
951 g_assert (socket6 == NULL);
952 socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
953 G_SOCKET_TYPE_STREAM,
954 G_SOCKET_PROTOCOL_DEFAULT,
955 NULL);
957 if (socket6 != NULL)
959 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
960 address = g_inet_socket_address_new (inet_address, 0);
961 g_object_unref (inet_address);
962 result = g_socket_bind (socket6, address, TRUE, error);
963 g_object_unref (address);
965 if (!result ||
966 !(address = g_socket_get_local_address (socket6, error)))
968 g_object_unref (socket6);
969 socket6 = NULL;
970 break;
973 g_assert (G_IS_INET_SOCKET_ADDRESS (address));
974 candidate_port =
975 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
976 g_assert (candidate_port != 0);
977 g_object_unref (address);
979 if (g_socket_speaks_ipv4 (socket6))
980 break;
983 g_assert (socket4 == NULL);
984 socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
985 G_SOCKET_TYPE_STREAM,
986 G_SOCKET_PROTOCOL_DEFAULT,
987 socket6 ? NULL : error);
989 if (socket4 == NULL)
990 /* IPv4 not supported.
991 * if IPv6 is supported then candidate_port will be non-zero
992 * (and the error parameter above will have been NULL)
993 * if IPv6 is unsupported then candidate_port will be zero
994 * (and error will have been set by the above call)
996 break;
998 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
999 address = g_inet_socket_address_new (inet_address, candidate_port);
1000 g_object_unref (inet_address);
1001 /* a note on the 'error' clause below:
1003 * if candidate_port is 0 then we report the error right away
1004 * since it is strange that this binding would fail at all.
1005 * otherwise, we ignore the error message (ie: NULL).
1007 * the exception to this rule is the last time through the loop
1008 * (ie: attempts == 0) in which case we want to set the error
1009 * because failure here means that the entire call will fail and
1010 * we need something to show to the user.
1012 * an english summary of the situation: "if we gave a candidate
1013 * port number AND we have more attempts to try, then ignore the
1014 * error for now".
1016 result = g_socket_bind (socket4, address, TRUE,
1017 (candidate_port && attempts) ? NULL : error);
1018 g_object_unref (address);
1020 if (candidate_port)
1022 g_assert (socket6 != NULL);
1024 if (result)
1025 /* got our candidate port successfully */
1026 break;
1028 else
1029 /* we failed to bind to the specified port. try again. */
1031 g_object_unref (socket4);
1032 socket4 = NULL;
1034 /* keep this open so we get a different port number */
1035 sockets_to_close = g_slist_prepend (sockets_to_close,
1036 socket6);
1037 candidate_port = 0;
1038 socket6 = NULL;
1041 else
1042 /* we didn't tell it a port. this means two things.
1043 * - if we failed, then something really bad happened.
1044 * - if we succeeded, then we need to find out the port number.
1047 g_assert (socket6 == NULL);
1049 if (!result ||
1050 !(address = g_socket_get_local_address (socket4, error)))
1052 g_object_unref (socket4);
1053 socket4 = NULL;
1054 break;
1057 g_assert (G_IS_INET_SOCKET_ADDRESS (address));
1058 candidate_port =
1059 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
1060 g_assert (candidate_port != 0);
1061 g_object_unref (address);
1062 break;
1066 /* should only be non-zero if we have a socket */
1067 g_assert ((candidate_port != 0) == (socket4 || socket6));
1069 while (sockets_to_close)
1071 g_object_unref (sockets_to_close->data);
1072 sockets_to_close = g_slist_delete_link (sockets_to_close,
1073 sockets_to_close);
1076 /* now we actually listen() the sockets and add them to the listener */
1077 if (socket6 != NULL)
1079 g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
1080 if (!g_socket_listen (socket6, error))
1082 g_object_unref (socket6);
1083 if (socket4)
1084 g_object_unref (socket4);
1086 return 0;
1089 if (source_object)
1090 g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
1091 g_object_ref (source_object),
1092 g_object_unref);
1094 g_ptr_array_add (listener->priv->sockets, socket6);
1097 if (socket4 != NULL)
1099 g_socket_set_listen_backlog (socket4, listener->priv->listen_backlog);
1100 if (!g_socket_listen (socket4, error))
1102 g_object_unref (socket4);
1103 if (socket6)
1104 g_object_unref (socket6);
1106 return 0;
1109 if (source_object)
1110 g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
1111 g_object_ref (source_object),
1112 g_object_unref);
1114 g_ptr_array_add (listener->priv->sockets, socket4);
1117 if ((socket4 != NULL || socket6 != NULL) &&
1118 G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
1119 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
1121 return candidate_port;