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, see <http://www.gnu.org/licenses/>.
20 * Authors: Christian Kellner <gicmo@gnome.org>
21 * Samuel Cormier-Iijima <sciyoshi@gmail.com>
22 * Ryan Lortie <desrt@desrt.ca>
23 * Alexander Larsson <alexl@redhat.com>
27 #include "gsocketlistener.h"
29 #include <gio/gtask.h>
30 #include <gio/gcancellable.h>
31 #include <gio/gsocketaddress.h>
32 #include <gio/ginetaddress.h>
33 #include <gio/gioerror.h>
34 #include <gio/gsocket.h>
35 #include <gio/gsocketconnection.h>
36 #include <gio/ginetsocketaddress.h>
41 * SECTION:gsocketlistener
42 * @title: GSocketListener
43 * @short_description: Helper for accepting network client connections
45 * @see_also: #GThreadedSocketService, #GSocketService.
47 * A #GSocketListener is an object that keeps track of a set
48 * of server sockets and helps you accept sockets from any of the
49 * socket, either sync or async.
51 * If you want to implement a network server, also look at #GSocketService
52 * and #GThreadedSocketService which are subclass of #GSocketListener
53 * that makes this even easier.
65 static GQuark source_quark = 0;
67 struct _GSocketListenerPrivate
70 GMainContext *main_context;
75 G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener, g_socket_listener, G_TYPE_OBJECT)
78 g_socket_listener_finalize (GObject *object)
80 GSocketListener *listener = G_SOCKET_LISTENER (object);
82 if (listener->priv->main_context)
83 g_main_context_unref (listener->priv->main_context);
85 if (!listener->priv->closed)
86 g_socket_listener_close (listener);
88 g_ptr_array_free (listener->priv->sockets, TRUE);
90 G_OBJECT_CLASS (g_socket_listener_parent_class)
95 g_socket_listener_get_property (GObject *object,
100 GSocketListener *listener = G_SOCKET_LISTENER (object);
104 case PROP_LISTEN_BACKLOG:
105 g_value_set_int (value, listener->priv->listen_backlog);
109 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
114 g_socket_listener_set_property (GObject *object,
119 GSocketListener *listener = G_SOCKET_LISTENER (object);
123 case PROP_LISTEN_BACKLOG:
124 g_socket_listener_set_backlog (listener, g_value_get_int (value));
128 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
134 g_socket_listener_class_init (GSocketListenerClass *klass)
136 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
138 gobject_class->finalize = g_socket_listener_finalize;
139 gobject_class->set_property = g_socket_listener_set_property;
140 gobject_class->get_property = g_socket_listener_get_property;
141 g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG,
142 g_param_spec_int ("listen-backlog",
143 P_("Listen backlog"),
144 P_("outstanding connections in the listen queue"),
148 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 source_quark = g_quark_from_static_string ("g-socket-listener-source");
154 g_socket_listener_init (GSocketListener *listener)
156 listener->priv = g_socket_listener_get_instance_private (listener);
157 listener->priv->sockets =
158 g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
159 listener->priv->listen_backlog = 10;
163 * g_socket_listener_new:
165 * Creates a new #GSocketListener with no sockets to listen for.
166 * New listeners can be added with e.g. g_socket_listener_add_address()
167 * or g_socket_listener_add_inet_port().
169 * Returns: a new #GSocketListener.
174 g_socket_listener_new (void)
176 return g_object_new (G_TYPE_SOCKET_LISTENER, NULL);
180 check_listener (GSocketListener *listener,
183 if (listener->priv->closed)
185 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
186 _("Listener is already closed"));
194 * g_socket_listener_add_socket:
195 * @listener: a #GSocketListener
196 * @socket: a listening #GSocket
197 * @source_object: (allow-none): Optional #GObject identifying this source
198 * @error: #GError for error reporting, or %NULL to ignore.
200 * Adds @socket to the set of sockets that we try to accept
201 * new clients from. The socket must be bound to a local
202 * address and listened to.
204 * @source_object will be passed out in the various calls
205 * to accept to identify this particular source, which is
206 * useful if you're listening on multiple addresses and do
207 * different things depending on what address is connected to.
209 * Returns: %TRUE on success, %FALSE on error.
214 g_socket_listener_add_socket (GSocketListener *listener,
216 GObject *source_object,
219 if (!check_listener (listener, error))
222 /* TODO: Check that socket it is bound & not closed? */
224 if (g_socket_is_closed (socket))
226 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
227 _("Added socket is closed"));
231 g_object_ref (socket);
232 g_ptr_array_add (listener->priv->sockets, socket);
235 g_object_set_qdata_full (G_OBJECT (socket), source_quark,
236 g_object_ref (source_object), g_object_unref);
239 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
240 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
246 * g_socket_listener_add_address:
247 * @listener: a #GSocketListener
248 * @address: a #GSocketAddress
249 * @type: a #GSocketType
250 * @protocol: a #GSocketProtocol
251 * @source_object: (allow-none): Optional #GObject identifying this source
252 * @effective_address: (out) (allow-none): location to store the address that was bound to, or %NULL.
253 * @error: #GError for error reporting, or %NULL to ignore.
255 * Creates a socket of type @type and protocol @protocol, binds
256 * it to @address and adds it to the set of sockets we're accepting
259 * Note that adding an IPv6 address, depending on the platform,
260 * may or may not result in a listener that also accepts IPv4
261 * connections. For more deterministic behavior, see
262 * g_socket_listener_add_inet_port().
264 * @source_object will be passed out in the various calls
265 * to accept to identify this particular source, which is
266 * useful if you're listening on multiple addresses and do
267 * different things depending on what address is connected to.
269 * If successful and @effective_address is non-%NULL then it will
270 * be set to the address that the binding actually occurred at. This
271 * is helpful for determining the port number that was used for when
272 * requesting a binding to port 0 (ie: "any port"). This address, if
273 * requested, belongs to the caller and must be freed.
275 * Returns: %TRUE on success, %FALSE on error.
280 g_socket_listener_add_address (GSocketListener *listener,
281 GSocketAddress *address,
283 GSocketProtocol protocol,
284 GObject *source_object,
285 GSocketAddress **effective_address,
288 GSocketAddress *local_address;
289 GSocketFamily family;
292 if (!check_listener (listener, error))
295 family = g_socket_address_get_family (address);
296 socket = g_socket_new (family, type, protocol, error);
300 g_socket_set_listen_backlog (socket, listener->priv->listen_backlog);
302 if (!g_socket_bind (socket, address, TRUE, error) ||
303 !g_socket_listen (socket, error))
305 g_object_unref (socket);
309 local_address = NULL;
310 if (effective_address)
312 local_address = g_socket_get_local_address (socket, error);
313 if (local_address == NULL)
315 g_object_unref (socket);
320 if (!g_socket_listener_add_socket (listener, socket,
325 g_object_unref (local_address);
326 g_object_unref (socket);
330 if (effective_address)
331 *effective_address = local_address;
333 g_object_unref (socket); /* add_socket refs this */
339 * g_socket_listener_add_inet_port:
340 * @listener: a #GSocketListener
341 * @port: an IP port number (non-zero)
342 * @source_object: (allow-none): Optional #GObject identifying this source
343 * @error: #GError for error reporting, or %NULL to ignore.
345 * Helper function for g_socket_listener_add_address() that
346 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
347 * supported) on the specified port on all interfaces.
349 * @source_object will be passed out in the various calls
350 * to accept to identify this particular source, which is
351 * useful if you're listening on multiple addresses and do
352 * different things depending on what address is connected to.
354 * Returns: %TRUE on success, %FALSE on error.
359 g_socket_listener_add_inet_port (GSocketListener *listener,
361 GObject *source_object,
364 gboolean need_ipv4_socket = TRUE;
365 GSocket *socket4 = NULL;
368 g_return_val_if_fail (listener != NULL, FALSE);
369 g_return_val_if_fail (port != 0, FALSE);
371 if (!check_listener (listener, error))
374 /* first try to create an IPv6 socket */
375 socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
376 G_SOCKET_TYPE_STREAM,
377 G_SOCKET_PROTOCOL_DEFAULT,
381 /* IPv6 is supported on this platform, so if we fail now it is
382 * a result of being unable to bind to our port. Don't fail
383 * silently as a result of this!
386 GInetAddress *inet_address;
387 GSocketAddress *address;
390 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
391 address = g_inet_socket_address_new (inet_address, port);
392 g_object_unref (inet_address);
394 g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
396 result = g_socket_bind (socket6, address, TRUE, error) &&
397 g_socket_listen (socket6, error);
399 g_object_unref (address);
403 g_object_unref (socket6);
409 g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
410 g_object_ref (source_object),
413 /* If this socket already speaks IPv4 then we are done. */
414 if (g_socket_speaks_ipv4 (socket6))
415 need_ipv4_socket = FALSE;
418 if (need_ipv4_socket)
419 /* We are here for exactly one of the following reasons:
421 * - our platform doesn't support IPv6
422 * - we successfully created an IPv6 socket but it's V6ONLY
424 * In either case, we need to go ahead and create an IPv4 socket
425 * and fail the call if we can't bind to it.
428 socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
429 G_SOCKET_TYPE_STREAM,
430 G_SOCKET_PROTOCOL_DEFAULT,
434 /* IPv4 is supported on this platform, so if we fail now it is
435 * a result of being unable to bind to our port. Don't fail
436 * silently as a result of this!
439 GInetAddress *inet_address;
440 GSocketAddress *address;
443 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
444 address = g_inet_socket_address_new (inet_address, port);
445 g_object_unref (inet_address);
447 g_socket_set_listen_backlog (socket4,
448 listener->priv->listen_backlog);
450 result = g_socket_bind (socket4, address, TRUE, error) &&
451 g_socket_listen (socket4, error);
453 g_object_unref (address);
457 g_object_unref (socket4);
460 g_object_unref (socket6);
466 g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
467 g_object_ref (source_object),
471 /* Ok. So IPv4 is not supported on this platform. If we
472 * succeeded at creating an IPv6 socket then that's OK, but
473 * otherwise we need to tell the user we failed.
477 g_clear_error (error);
483 g_assert (socket6 != NULL || socket4 != NULL);
486 g_ptr_array_add (listener->priv->sockets, socket6);
489 g_ptr_array_add (listener->priv->sockets, socket4);
491 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
492 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
498 add_sources (GSocketListener *listener,
499 GSocketSourceFunc callback,
500 gpointer callback_data,
501 GCancellable *cancellable,
502 GMainContext *context)
510 for (i = 0; i < listener->priv->sockets->len; i++)
512 socket = listener->priv->sockets->pdata[i];
514 source = g_socket_create_source (socket, G_IO_IN, cancellable);
515 g_source_set_callback (source,
516 (GSourceFunc) callback,
517 callback_data, NULL);
518 g_source_attach (source, context);
520 sources = g_list_prepend (sources, source);
527 free_sources (GList *sources)
530 while (sources != NULL)
532 source = sources->data;
533 sources = g_list_delete_link (sources, sources);
534 g_source_destroy (source);
535 g_source_unref (source);
545 accept_callback (GSocket *socket,
546 GIOCondition condition,
549 struct AcceptData *data = user_data;
551 data->socket = socket;
552 g_main_loop_quit (data->loop);
558 * g_socket_listener_accept_socket:
559 * @listener: a #GSocketListener
560 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL.
561 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
562 * @error: #GError for error reporting, or %NULL to ignore.
564 * Blocks waiting for a client to connect to any of the sockets added
565 * to the listener. Returns the #GSocket that was accepted.
567 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
568 * which is often the case, then you should use g_socket_listener_accept()
571 * If @source_object is not %NULL it will be filled out with the source
572 * object specified when the corresponding socket or address was added
575 * If @cancellable is not %NULL, then the operation can be cancelled by
576 * triggering the cancellable object from another thread. If the operation
577 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
579 * Returns: (transfer full): a #GSocket on success, %NULL on error.
584 g_socket_listener_accept_socket (GSocketListener *listener,
585 GObject **source_object,
586 GCancellable *cancellable,
589 GSocket *accept_socket, *socket;
591 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
593 if (!check_listener (listener, error))
596 if (listener->priv->sockets->len == 1)
598 accept_socket = listener->priv->sockets->pdata[0];
599 if (!g_socket_condition_wait (accept_socket, G_IO_IN,
606 struct AcceptData data;
609 if (listener->priv->main_context == NULL)
610 listener->priv->main_context = g_main_context_new ();
612 loop = g_main_loop_new (listener->priv->main_context, FALSE);
614 sources = add_sources (listener,
618 listener->priv->main_context);
619 g_main_loop_run (loop);
620 accept_socket = data.socket;
621 free_sources (sources);
622 g_main_loop_unref (loop);
625 if (!(socket = g_socket_accept (accept_socket, cancellable, error)))
629 *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
635 * g_socket_listener_accept:
636 * @listener: a #GSocketListener
637 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL
638 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
639 * @error: #GError for error reporting, or %NULL to ignore.
641 * Blocks waiting for a client to connect to any of the sockets added
642 * to the listener. Returns a #GSocketConnection for the socket that was
645 * If @source_object is not %NULL it will be filled out with the source
646 * object specified when the corresponding socket or address was added
649 * If @cancellable is not %NULL, then the operation can be cancelled by
650 * triggering the cancellable object from another thread. If the operation
651 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
653 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
658 g_socket_listener_accept (GSocketListener *listener,
659 GObject **source_object,
660 GCancellable *cancellable,
663 GSocketConnection *connection;
666 socket = g_socket_listener_accept_socket (listener,
673 connection = g_socket_connection_factory_create_connection (socket);
674 g_object_unref (socket);
680 accept_ready (GSocket *accept_socket,
681 GIOCondition condition,
684 GTask *task = user_data;
685 GError *error = NULL;
687 GObject *source_object;
689 socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
692 source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
694 g_object_set_qdata_full (G_OBJECT (task),
696 g_object_ref (source_object), g_object_unref);
697 g_task_return_pointer (task, socket, g_object_unref);
701 g_task_return_error (task, error);
704 g_object_unref (task);
709 * g_socket_listener_accept_socket_async:
710 * @listener: a #GSocketListener
711 * @cancellable: (allow-none): a #GCancellable, or %NULL
712 * @callback: (scope async): a #GAsyncReadyCallback
713 * @user_data: (closure): user data for the callback
715 * This is the asynchronous version of g_socket_listener_accept_socket().
717 * When the operation is finished @callback will be
718 * called. You can then call g_socket_listener_accept_socket_finish()
719 * to get the result of the operation.
724 g_socket_listener_accept_socket_async (GSocketListener *listener,
725 GCancellable *cancellable,
726 GAsyncReadyCallback callback,
731 GError *error = NULL;
733 task = g_task_new (listener, cancellable, callback, user_data);
735 if (!check_listener (listener, &error))
737 g_task_return_error (task, error);
738 g_object_unref (task);
742 sources = add_sources (listener,
746 g_main_context_get_thread_default ());
747 g_task_set_task_data (task, sources, (GDestroyNotify) free_sources);
751 * g_socket_listener_accept_socket_finish:
752 * @listener: a #GSocketListener
753 * @result: a #GAsyncResult.
754 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
755 * @error: a #GError location to store the error occurring, or %NULL to
758 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
760 * Returns: (transfer full): a #GSocket on success, %NULL on error.
765 g_socket_listener_accept_socket_finish (GSocketListener *listener,
766 GAsyncResult *result,
767 GObject **source_object,
770 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
771 g_return_val_if_fail (g_task_is_valid (result, listener), NULL);
774 *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
776 return g_task_propagate_pointer (G_TASK (result), error);
780 * g_socket_listener_accept_async:
781 * @listener: a #GSocketListener
782 * @cancellable: (allow-none): a #GCancellable, or %NULL
783 * @callback: (scope async): a #GAsyncReadyCallback
784 * @user_data: (closure): user data for the callback
786 * This is the asynchronous version of g_socket_listener_accept().
788 * When the operation is finished @callback will be
789 * called. You can then call g_socket_listener_accept_socket()
790 * to get the result of the operation.
795 g_socket_listener_accept_async (GSocketListener *listener,
796 GCancellable *cancellable,
797 GAsyncReadyCallback callback,
800 g_socket_listener_accept_socket_async (listener,
807 * g_socket_listener_accept_finish:
808 * @listener: a #GSocketListener
809 * @result: a #GAsyncResult.
810 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
811 * @error: a #GError location to store the error occurring, or %NULL to
814 * Finishes an async accept operation. See g_socket_listener_accept_async()
816 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
821 g_socket_listener_accept_finish (GSocketListener *listener,
822 GAsyncResult *result,
823 GObject **source_object,
827 GSocketConnection *connection;
829 socket = g_socket_listener_accept_socket_finish (listener,
836 connection = g_socket_connection_factory_create_connection (socket);
837 g_object_unref (socket);
842 * g_socket_listener_set_backlog:
843 * @listener: a #GSocketListener
844 * @listen_backlog: an integer
846 * Sets the listen backlog on the sockets in the listener.
848 * See g_socket_set_listen_backlog() for details
853 g_socket_listener_set_backlog (GSocketListener *listener,
859 if (listener->priv->closed)
862 listener->priv->listen_backlog = listen_backlog;
864 for (i = 0; i < listener->priv->sockets->len; i++)
866 socket = listener->priv->sockets->pdata[i];
867 g_socket_set_listen_backlog (socket, listen_backlog);
872 * g_socket_listener_close:
873 * @listener: a #GSocketListener
875 * Closes all the sockets in the listener.
880 g_socket_listener_close (GSocketListener *listener)
885 g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
887 if (listener->priv->closed)
890 for (i = 0; i < listener->priv->sockets->len; i++)
892 socket = listener->priv->sockets->pdata[i];
893 g_socket_close (socket, NULL);
895 listener->priv->closed = TRUE;
899 * g_socket_listener_add_any_inet_port:
900 * @listener: a #GSocketListener
901 * @source_object: (allow-none): Optional #GObject identifying this source
902 * @error: a #GError location to store the error occurring, or %NULL to
905 * Listens for TCP connections on any available port number for both
906 * IPv6 and IPv4 (if each is available).
908 * This is useful if you need to have a socket for incoming connections
909 * but don't care about the specific port number.
911 * @source_object will be passed out in the various calls
912 * to accept to identify this particular source, which is
913 * useful if you're listening on multiple addresses and do
914 * different things depending on what address is connected to.
916 * Returns: the port number, or 0 in case of failure.
921 g_socket_listener_add_any_inet_port (GSocketListener *listener,
922 GObject *source_object,
925 GSList *sockets_to_close = NULL;
926 guint16 candidate_port = 0;
927 GSocket *socket6 = NULL;
928 GSocket *socket4 = NULL;
932 * multi-step process:
933 * - first, create an IPv6 socket.
934 * - if that fails, create an IPv4 socket and bind it to port 0 and
935 * that's it. no retries if that fails (why would it?).
936 * - if our IPv6 socket also speaks IPv4 then we are done.
937 * - if not, then we need to create a IPv4 socket with the same port
938 * number. this might fail, of course. so we try this a bunch of
939 * times -- leaving the old IPv6 sockets open so that we get a
940 * different port number to try each time.
941 * - if all that fails then just give up.
946 GInetAddress *inet_address;
947 GSocketAddress *address;
950 g_assert (socket6 == NULL);
951 socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
952 G_SOCKET_TYPE_STREAM,
953 G_SOCKET_PROTOCOL_DEFAULT,
958 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
959 address = g_inet_socket_address_new (inet_address, 0);
960 g_object_unref (inet_address);
961 result = g_socket_bind (socket6, address, TRUE, error);
962 g_object_unref (address);
965 !(address = g_socket_get_local_address (socket6, error)))
967 g_object_unref (socket6);
972 g_assert (G_IS_INET_SOCKET_ADDRESS (address));
974 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
975 g_assert (candidate_port != 0);
976 g_object_unref (address);
978 if (g_socket_speaks_ipv4 (socket6))
982 g_assert (socket4 == NULL);
983 socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
984 G_SOCKET_TYPE_STREAM,
985 G_SOCKET_PROTOCOL_DEFAULT,
986 socket6 ? NULL : error);
989 /* IPv4 not supported.
990 * if IPv6 is supported then candidate_port will be non-zero
991 * (and the error parameter above will have been NULL)
992 * if IPv6 is unsupported then candidate_port will be zero
993 * (and error will have been set by the above call)
997 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
998 address = g_inet_socket_address_new (inet_address, candidate_port);
999 g_object_unref (inet_address);
1000 /* a note on the 'error' clause below:
1002 * if candidate_port is 0 then we report the error right away
1003 * since it is strange that this binding would fail at all.
1004 * otherwise, we ignore the error message (ie: NULL).
1006 * the exception to this rule is the last time through the loop
1007 * (ie: attempts == 0) in which case we want to set the error
1008 * because failure here means that the entire call will fail and
1009 * we need something to show to the user.
1011 * an english summary of the situation: "if we gave a candidate
1012 * port number AND we have more attempts to try, then ignore the
1015 result = g_socket_bind (socket4, address, TRUE,
1016 (candidate_port && attempts) ? NULL : error);
1017 g_object_unref (address);
1021 g_assert (socket6 != NULL);
1024 /* got our candidate port successfully */
1028 /* we failed to bind to the specified port. try again. */
1030 g_object_unref (socket4);
1033 /* keep this open so we get a different port number */
1034 sockets_to_close = g_slist_prepend (sockets_to_close,
1041 /* we didn't tell it a port. this means two things.
1042 * - if we failed, then something really bad happened.
1043 * - if we succeeded, then we need to find out the port number.
1046 g_assert (socket6 == NULL);
1049 !(address = g_socket_get_local_address (socket4, error)))
1051 g_object_unref (socket4);
1056 g_assert (G_IS_INET_SOCKET_ADDRESS (address));
1058 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
1059 g_assert (candidate_port != 0);
1060 g_object_unref (address);
1065 /* should only be non-zero if we have a socket */
1066 g_assert ((candidate_port != 0) == (socket4 || socket6));
1068 while (sockets_to_close)
1070 g_object_unref (sockets_to_close->data);
1071 sockets_to_close = g_slist_delete_link (sockets_to_close,
1075 /* now we actually listen() the sockets and add them to the listener */
1076 if (socket6 != NULL)
1078 g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
1079 if (!g_socket_listen (socket6, error))
1081 g_object_unref (socket6);
1083 g_object_unref (socket4);
1089 g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
1090 g_object_ref (source_object),
1093 g_ptr_array_add (listener->priv->sockets, socket6);
1096 if (socket4 != NULL)
1098 g_socket_set_listen_backlog (socket4, listener->priv->listen_backlog);
1099 if (!g_socket_listen (socket4, error))
1101 g_object_unref (socket4);
1103 g_object_unref (socket6);
1109 g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
1110 g_object_ref (source_object),
1113 g_ptr_array_add (listener->priv->sockets, socket4);
1116 if ((socket4 != NULL || socket6 != NULL) &&
1117 G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
1118 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
1120 return candidate_port;