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>
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>
43 * SECTION:gsocketlistener
44 * @title: GSocketListener
45 * @short_description: Helper for accepting network client connections
47 * @see_also: #GThreadedSocketService, #GSocketService.
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.
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.
67 static GQuark source_quark = 0;
69 struct _GSocketListenerPrivate
72 GMainContext *main_context;
77 G_DEFINE_TYPE_WITH_PRIVATE (GSocketListener, g_socket_listener, G_TYPE_OBJECT)
80 g_socket_listener_finalize (GObject *object)
82 GSocketListener *listener = G_SOCKET_LISTENER (object);
84 if (listener->priv->main_context)
85 g_main_context_unref (listener->priv->main_context);
87 if (!listener->priv->closed)
88 g_socket_listener_close (listener);
90 g_ptr_array_free (listener->priv->sockets, TRUE);
92 G_OBJECT_CLASS (g_socket_listener_parent_class)
97 g_socket_listener_get_property (GObject *object,
102 GSocketListener *listener = G_SOCKET_LISTENER (object);
106 case PROP_LISTEN_BACKLOG:
107 g_value_set_int (value, listener->priv->listen_backlog);
111 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
116 g_socket_listener_set_property (GObject *object,
121 GSocketListener *listener = G_SOCKET_LISTENER (object);
125 case PROP_LISTEN_BACKLOG:
126 g_socket_listener_set_backlog (listener, g_value_get_int (value));
130 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
136 g_socket_listener_class_init (GSocketListenerClass *klass)
138 GObjectClass *gobject_class G_GNUC_UNUSED = G_OBJECT_CLASS (klass);
140 gobject_class->finalize = g_socket_listener_finalize;
141 gobject_class->set_property = g_socket_listener_set_property;
142 gobject_class->get_property = g_socket_listener_get_property;
143 g_object_class_install_property (gobject_class, PROP_LISTEN_BACKLOG,
144 g_param_spec_int ("listen-backlog",
145 P_("Listen backlog"),
146 P_("outstanding connections in the listen queue"),
150 G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
152 source_quark = g_quark_from_static_string ("g-socket-listener-source");
156 g_socket_listener_init (GSocketListener *listener)
158 listener->priv = g_socket_listener_get_instance_private (listener);
159 listener->priv->sockets =
160 g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
161 listener->priv->listen_backlog = 10;
165 * g_socket_listener_new:
167 * Creates a new #GSocketListener with no sockets to listen for.
168 * New listeners can be added with e.g. g_socket_listener_add_address()
169 * or g_socket_listener_add_inet_port().
171 * Returns: a new #GSocketListener.
176 g_socket_listener_new (void)
178 return g_object_new (G_TYPE_SOCKET_LISTENER, NULL);
182 check_listener (GSocketListener *listener,
185 if (listener->priv->closed)
187 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
188 _("Listener is already closed"));
196 * g_socket_listener_add_socket:
197 * @listener: a #GSocketListener
198 * @socket: a listening #GSocket
199 * @source_object: (allow-none): Optional #GObject identifying this source
200 * @error: #GError for error reporting, or %NULL to ignore.
202 * Adds @socket to the set of sockets that we try to accept
203 * new clients from. The socket must be bound to a local
204 * address and listened to.
206 * @source_object will be passed out in the various calls
207 * to accept to identify this particular source, which is
208 * useful if you're listening on multiple addresses and do
209 * different things depending on what address is connected to.
211 * Returns: %TRUE on success, %FALSE on error.
216 g_socket_listener_add_socket (GSocketListener *listener,
218 GObject *source_object,
221 if (!check_listener (listener, error))
224 /* TODO: Check that socket it is bound & not closed? */
226 if (g_socket_is_closed (socket))
228 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
229 _("Added socket is closed"));
233 g_object_ref (socket);
234 g_ptr_array_add (listener->priv->sockets, socket);
237 g_object_set_qdata_full (G_OBJECT (socket), source_quark,
238 g_object_ref (source_object), g_object_unref);
241 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
242 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
248 * g_socket_listener_add_address:
249 * @listener: a #GSocketListener
250 * @address: a #GSocketAddress
251 * @type: a #GSocketType
252 * @protocol: a #GSocketProtocol
253 * @source_object: (allow-none): Optional #GObject identifying this source
254 * @effective_address: (out) (allow-none): location to store the address that was bound to, or %NULL.
255 * @error: #GError for error reporting, or %NULL to ignore.
257 * Creates a socket of type @type and protocol @protocol, binds
258 * it to @address and adds it to the set of sockets we're accepting
261 * Note that adding an IPv6 address, depending on the platform,
262 * may or may not result in a listener that also accepts IPv4
263 * connections. For more deterministic behavior, see
264 * g_socket_listener_add_inet_port().
266 * @source_object will be passed out in the various calls
267 * to accept to identify this particular source, which is
268 * useful if you're listening on multiple addresses and do
269 * different things depending on what address is connected to.
271 * If successful and @effective_address is non-%NULL then it will
272 * be set to the address that the binding actually occurred at. This
273 * is helpful for determining the port number that was used for when
274 * requesting a binding to port 0 (ie: "any port"). This address, if
275 * requested, belongs to the caller and must be freed.
277 * Returns: %TRUE on success, %FALSE on error.
282 g_socket_listener_add_address (GSocketListener *listener,
283 GSocketAddress *address,
285 GSocketProtocol protocol,
286 GObject *source_object,
287 GSocketAddress **effective_address,
290 GSocketAddress *local_address;
291 GSocketFamily family;
294 if (!check_listener (listener, error))
297 family = g_socket_address_get_family (address);
298 socket = g_socket_new (family, type, protocol, error);
302 g_socket_set_listen_backlog (socket, listener->priv->listen_backlog);
304 if (!g_socket_bind (socket, address, TRUE, error) ||
305 !g_socket_listen (socket, error))
307 g_object_unref (socket);
311 local_address = NULL;
312 if (effective_address)
314 local_address = g_socket_get_local_address (socket, error);
315 if (local_address == NULL)
317 g_object_unref (socket);
322 if (!g_socket_listener_add_socket (listener, socket,
327 g_object_unref (local_address);
328 g_object_unref (socket);
332 if (effective_address)
333 *effective_address = local_address;
335 g_object_unref (socket); /* add_socket refs this */
341 * g_socket_listener_add_inet_port:
342 * @listener: a #GSocketListener
343 * @port: an IP port number (non-zero)
344 * @source_object: (allow-none): Optional #GObject identifying this source
345 * @error: #GError for error reporting, or %NULL to ignore.
347 * Helper function for g_socket_listener_add_address() that
348 * creates a TCP/IP socket listening on IPv4 and IPv6 (if
349 * supported) on the specified port on all interfaces.
351 * @source_object will be passed out in the various calls
352 * to accept to identify this particular source, which is
353 * useful if you're listening on multiple addresses and do
354 * different things depending on what address is connected to.
356 * Returns: %TRUE on success, %FALSE on error.
361 g_socket_listener_add_inet_port (GSocketListener *listener,
363 GObject *source_object,
366 gboolean need_ipv4_socket = TRUE;
367 GSocket *socket4 = NULL;
370 g_return_val_if_fail (listener != NULL, FALSE);
371 g_return_val_if_fail (port != 0, FALSE);
373 if (!check_listener (listener, error))
376 /* first try to create an IPv6 socket */
377 socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
378 G_SOCKET_TYPE_STREAM,
379 G_SOCKET_PROTOCOL_DEFAULT,
383 /* IPv6 is supported on this platform, so if we fail now it is
384 * a result of being unable to bind to our port. Don't fail
385 * silently as a result of this!
388 GInetAddress *inet_address;
389 GSocketAddress *address;
392 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
393 address = g_inet_socket_address_new (inet_address, port);
394 g_object_unref (inet_address);
396 g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
398 result = g_socket_bind (socket6, address, TRUE, error) &&
399 g_socket_listen (socket6, error);
401 g_object_unref (address);
405 g_object_unref (socket6);
411 g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
412 g_object_ref (source_object),
415 /* If this socket already speaks IPv4 then we are done. */
416 if (g_socket_speaks_ipv4 (socket6))
417 need_ipv4_socket = FALSE;
420 if (need_ipv4_socket)
421 /* We are here for exactly one of the following reasons:
423 * - our platform doesn't support IPv6
424 * - we successfully created an IPv6 socket but it's V6ONLY
426 * In either case, we need to go ahead and create an IPv4 socket
427 * and fail the call if we can't bind to it.
430 socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
431 G_SOCKET_TYPE_STREAM,
432 G_SOCKET_PROTOCOL_DEFAULT,
436 /* IPv4 is supported on this platform, so if we fail now it is
437 * a result of being unable to bind to our port. Don't fail
438 * silently as a result of this!
441 GInetAddress *inet_address;
442 GSocketAddress *address;
445 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
446 address = g_inet_socket_address_new (inet_address, port);
447 g_object_unref (inet_address);
449 g_socket_set_listen_backlog (socket4,
450 listener->priv->listen_backlog);
452 result = g_socket_bind (socket4, address, TRUE, error) &&
453 g_socket_listen (socket4, error);
455 g_object_unref (address);
459 g_object_unref (socket4);
462 g_object_unref (socket6);
468 g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
469 g_object_ref (source_object),
473 /* Ok. So IPv4 is not supported on this platform. If we
474 * succeeded at creating an IPv6 socket then that's OK, but
475 * otherwise we need to tell the user we failed.
479 g_clear_error (error);
485 g_assert (socket6 != NULL || socket4 != NULL);
488 g_ptr_array_add (listener->priv->sockets, socket6);
491 g_ptr_array_add (listener->priv->sockets, socket4);
493 if (G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
494 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
500 add_sources (GSocketListener *listener,
501 GSocketSourceFunc callback,
502 gpointer callback_data,
503 GCancellable *cancellable,
504 GMainContext *context)
512 for (i = 0; i < listener->priv->sockets->len; i++)
514 socket = listener->priv->sockets->pdata[i];
516 source = g_socket_create_source (socket, G_IO_IN, cancellable);
517 g_source_set_callback (source,
518 (GSourceFunc) callback,
519 callback_data, NULL);
520 g_source_attach (source, context);
522 sources = g_list_prepend (sources, source);
529 free_sources (GList *sources)
532 while (sources != NULL)
534 source = sources->data;
535 sources = g_list_delete_link (sources, sources);
536 g_source_destroy (source);
537 g_source_unref (source);
547 accept_callback (GSocket *socket,
548 GIOCondition condition,
551 struct AcceptData *data = user_data;
553 data->socket = socket;
554 g_main_loop_quit (data->loop);
560 * g_socket_listener_accept_socket:
561 * @listener: a #GSocketListener
562 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL.
563 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
564 * @error: #GError for error reporting, or %NULL to ignore.
566 * Blocks waiting for a client to connect to any of the sockets added
567 * to the listener. Returns the #GSocket that was accepted.
569 * If you want to accept the high-level #GSocketConnection, not a #GSocket,
570 * which is often the case, then you should use g_socket_listener_accept()
573 * If @source_object is not %NULL it will be filled out with the source
574 * object specified when the corresponding socket or address was added
577 * If @cancellable is not %NULL, then the operation can be cancelled by
578 * triggering the cancellable object from another thread. If the operation
579 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
581 * Returns: (transfer full): a #GSocket on success, %NULL on error.
586 g_socket_listener_accept_socket (GSocketListener *listener,
587 GObject **source_object,
588 GCancellable *cancellable,
591 GSocket *accept_socket, *socket;
593 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
595 if (!check_listener (listener, error))
598 if (listener->priv->sockets->len == 1)
600 accept_socket = listener->priv->sockets->pdata[0];
601 if (!g_socket_condition_wait (accept_socket, G_IO_IN,
608 struct AcceptData data;
611 if (listener->priv->main_context == NULL)
612 listener->priv->main_context = g_main_context_new ();
614 loop = g_main_loop_new (listener->priv->main_context, FALSE);
616 sources = add_sources (listener,
620 listener->priv->main_context);
621 g_main_loop_run (loop);
622 accept_socket = data.socket;
623 free_sources (sources);
624 g_main_loop_unref (loop);
627 if (!(socket = g_socket_accept (accept_socket, cancellable, error)))
631 *source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
637 * g_socket_listener_accept:
638 * @listener: a #GSocketListener
639 * @source_object: (out) (transfer none) (allow-none): location where #GObject pointer will be stored, or %NULL
640 * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore.
641 * @error: #GError for error reporting, or %NULL to ignore.
643 * Blocks waiting for a client to connect to any of the sockets added
644 * to the listener. Returns a #GSocketConnection for the socket that was
647 * If @source_object is not %NULL it will be filled out with the source
648 * object specified when the corresponding socket or address was added
651 * If @cancellable is not %NULL, then the operation can be cancelled by
652 * triggering the cancellable object from another thread. If the operation
653 * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
655 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
660 g_socket_listener_accept (GSocketListener *listener,
661 GObject **source_object,
662 GCancellable *cancellable,
665 GSocketConnection *connection;
668 socket = g_socket_listener_accept_socket (listener,
675 connection = g_socket_connection_factory_create_connection (socket);
676 g_object_unref (socket);
682 accept_ready (GSocket *accept_socket,
683 GIOCondition condition,
686 GTask *task = user_data;
687 GError *error = NULL;
689 GObject *source_object;
691 socket = g_socket_accept (accept_socket, g_task_get_cancellable (task), &error);
694 source_object = g_object_get_qdata (G_OBJECT (accept_socket), source_quark);
696 g_object_set_qdata_full (G_OBJECT (task),
698 g_object_ref (source_object), g_object_unref);
699 g_task_return_pointer (task, socket, g_object_unref);
703 g_task_return_error (task, error);
706 g_object_unref (task);
711 * g_socket_listener_accept_socket_async:
712 * @listener: a #GSocketListener
713 * @cancellable: (allow-none): a #GCancellable, or %NULL
714 * @callback: (scope async): a #GAsyncReadyCallback
715 * @user_data: (closure): user data for the callback
717 * This is the asynchronous version of g_socket_listener_accept_socket().
719 * When the operation is finished @callback will be
720 * called. You can then call g_socket_listener_accept_socket_finish()
721 * to get the result of the operation.
726 g_socket_listener_accept_socket_async (GSocketListener *listener,
727 GCancellable *cancellable,
728 GAsyncReadyCallback callback,
733 GError *error = NULL;
735 task = g_task_new (listener, cancellable, callback, user_data);
737 if (!check_listener (listener, &error))
739 g_task_return_error (task, error);
740 g_object_unref (task);
744 sources = add_sources (listener,
748 g_main_context_get_thread_default ());
749 g_task_set_task_data (task, sources, (GDestroyNotify) free_sources);
753 * g_socket_listener_accept_socket_finish:
754 * @listener: a #GSocketListener
755 * @result: a #GAsyncResult.
756 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
757 * @error: a #GError location to store the error occurring, or %NULL to
760 * Finishes an async accept operation. See g_socket_listener_accept_socket_async()
762 * Returns: (transfer full): a #GSocket on success, %NULL on error.
767 g_socket_listener_accept_socket_finish (GSocketListener *listener,
768 GAsyncResult *result,
769 GObject **source_object,
772 g_return_val_if_fail (G_IS_SOCKET_LISTENER (listener), NULL);
773 g_return_val_if_fail (g_task_is_valid (result, listener), NULL);
776 *source_object = g_object_get_qdata (G_OBJECT (result), source_quark);
778 return g_task_propagate_pointer (G_TASK (result), error);
782 * g_socket_listener_accept_async:
783 * @listener: a #GSocketListener
784 * @cancellable: (allow-none): a #GCancellable, or %NULL
785 * @callback: (scope async): a #GAsyncReadyCallback
786 * @user_data: (closure): user data for the callback
788 * This is the asynchronous version of g_socket_listener_accept().
790 * When the operation is finished @callback will be
791 * called. You can then call g_socket_listener_accept_socket()
792 * to get the result of the operation.
797 g_socket_listener_accept_async (GSocketListener *listener,
798 GCancellable *cancellable,
799 GAsyncReadyCallback callback,
802 g_socket_listener_accept_socket_async (listener,
809 * g_socket_listener_accept_finish:
810 * @listener: a #GSocketListener
811 * @result: a #GAsyncResult.
812 * @source_object: (out) (transfer none) (allow-none): Optional #GObject identifying this source
813 * @error: a #GError location to store the error occurring, or %NULL to
816 * Finishes an async accept operation. See g_socket_listener_accept_async()
818 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
823 g_socket_listener_accept_finish (GSocketListener *listener,
824 GAsyncResult *result,
825 GObject **source_object,
829 GSocketConnection *connection;
831 socket = g_socket_listener_accept_socket_finish (listener,
838 connection = g_socket_connection_factory_create_connection (socket);
839 g_object_unref (socket);
844 * g_socket_listener_set_backlog:
845 * @listener: a #GSocketListener
846 * @listen_backlog: an integer
848 * Sets the listen backlog on the sockets in the listener.
850 * See g_socket_set_listen_backlog() for details
855 g_socket_listener_set_backlog (GSocketListener *listener,
861 if (listener->priv->closed)
864 listener->priv->listen_backlog = listen_backlog;
866 for (i = 0; i < listener->priv->sockets->len; i++)
868 socket = listener->priv->sockets->pdata[i];
869 g_socket_set_listen_backlog (socket, listen_backlog);
874 * g_socket_listener_close:
875 * @listener: a #GSocketListener
877 * Closes all the sockets in the listener.
882 g_socket_listener_close (GSocketListener *listener)
887 g_return_if_fail (G_IS_SOCKET_LISTENER (listener));
889 if (listener->priv->closed)
892 for (i = 0; i < listener->priv->sockets->len; i++)
894 socket = listener->priv->sockets->pdata[i];
895 g_socket_close (socket, NULL);
897 listener->priv->closed = TRUE;
901 * g_socket_listener_add_any_inet_port:
902 * @listener: a #GSocketListener
903 * @source_object: (allow-none): Optional #GObject identifying this source
904 * @error: a #GError location to store the error occurring, or %NULL to
907 * Listens for TCP connections on any available port number for both
908 * IPv6 and IPv4 (if each is available).
910 * This is useful if you need to have a socket for incoming connections
911 * but don't care about the specific port number.
913 * @source_object will be passed out in the various calls
914 * to accept to identify this particular source, which is
915 * useful if you're listening on multiple addresses and do
916 * different things depending on what address is connected to.
918 * Returns: the port number, or 0 in case of failure.
923 g_socket_listener_add_any_inet_port (GSocketListener *listener,
924 GObject *source_object,
927 GSList *sockets_to_close = NULL;
928 guint16 candidate_port = 0;
929 GSocket *socket6 = NULL;
930 GSocket *socket4 = NULL;
934 * multi-step process:
935 * - first, create an IPv6 socket.
936 * - if that fails, create an IPv4 socket and bind it to port 0 and
937 * that's it. no retries if that fails (why would it?).
938 * - if our IPv6 socket also speaks IPv4 then we are done.
939 * - if not, then we need to create a IPv4 socket with the same port
940 * number. this might fail, of course. so we try this a bunch of
941 * times -- leaving the old IPv6 sockets open so that we get a
942 * different port number to try each time.
943 * - if all that fails then just give up.
948 GInetAddress *inet_address;
949 GSocketAddress *address;
952 g_assert (socket6 == NULL);
953 socket6 = g_socket_new (G_SOCKET_FAMILY_IPV6,
954 G_SOCKET_TYPE_STREAM,
955 G_SOCKET_PROTOCOL_DEFAULT,
960 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
961 address = g_inet_socket_address_new (inet_address, 0);
962 g_object_unref (inet_address);
963 result = g_socket_bind (socket6, address, TRUE, error);
964 g_object_unref (address);
967 !(address = g_socket_get_local_address (socket6, error)))
969 g_object_unref (socket6);
974 g_assert (G_IS_INET_SOCKET_ADDRESS (address));
976 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
977 g_assert (candidate_port != 0);
978 g_object_unref (address);
980 if (g_socket_speaks_ipv4 (socket6))
984 g_assert (socket4 == NULL);
985 socket4 = g_socket_new (G_SOCKET_FAMILY_IPV4,
986 G_SOCKET_TYPE_STREAM,
987 G_SOCKET_PROTOCOL_DEFAULT,
988 socket6 ? NULL : error);
991 /* IPv4 not supported.
992 * if IPv6 is supported then candidate_port will be non-zero
993 * (and the error parameter above will have been NULL)
994 * if IPv6 is unsupported then candidate_port will be zero
995 * (and error will have been set by the above call)
999 inet_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
1000 address = g_inet_socket_address_new (inet_address, candidate_port);
1001 g_object_unref (inet_address);
1002 /* a note on the 'error' clause below:
1004 * if candidate_port is 0 then we report the error right away
1005 * since it is strange that this binding would fail at all.
1006 * otherwise, we ignore the error message (ie: NULL).
1008 * the exception to this rule is the last time through the loop
1009 * (ie: attempts == 0) in which case we want to set the error
1010 * because failure here means that the entire call will fail and
1011 * we need something to show to the user.
1013 * an english summary of the situation: "if we gave a candidate
1014 * port number AND we have more attempts to try, then ignore the
1017 result = g_socket_bind (socket4, address, TRUE,
1018 (candidate_port && attempts) ? NULL : error);
1019 g_object_unref (address);
1023 g_assert (socket6 != NULL);
1026 /* got our candidate port successfully */
1030 /* we failed to bind to the specified port. try again. */
1032 g_object_unref (socket4);
1035 /* keep this open so we get a different port number */
1036 sockets_to_close = g_slist_prepend (sockets_to_close,
1043 /* we didn't tell it a port. this means two things.
1044 * - if we failed, then something really bad happened.
1045 * - if we succeeded, then we need to find out the port number.
1048 g_assert (socket6 == NULL);
1051 !(address = g_socket_get_local_address (socket4, error)))
1053 g_object_unref (socket4);
1058 g_assert (G_IS_INET_SOCKET_ADDRESS (address));
1060 g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
1061 g_assert (candidate_port != 0);
1062 g_object_unref (address);
1067 /* should only be non-zero if we have a socket */
1068 g_assert ((candidate_port != 0) == (socket4 || socket6));
1070 while (sockets_to_close)
1072 g_object_unref (sockets_to_close->data);
1073 sockets_to_close = g_slist_delete_link (sockets_to_close,
1077 /* now we actually listen() the sockets and add them to the listener */
1078 if (socket6 != NULL)
1080 g_socket_set_listen_backlog (socket6, listener->priv->listen_backlog);
1081 if (!g_socket_listen (socket6, error))
1083 g_object_unref (socket6);
1085 g_object_unref (socket4);
1091 g_object_set_qdata_full (G_OBJECT (socket6), source_quark,
1092 g_object_ref (source_object),
1095 g_ptr_array_add (listener->priv->sockets, socket6);
1098 if (socket4 != NULL)
1100 g_socket_set_listen_backlog (socket4, listener->priv->listen_backlog);
1101 if (!g_socket_listen (socket4, error))
1103 g_object_unref (socket4);
1105 g_object_unref (socket6);
1111 g_object_set_qdata_full (G_OBJECT (socket4), source_quark,
1112 g_object_ref (source_object),
1115 g_ptr_array_add (listener->priv->sockets, socket4);
1118 if ((socket4 != NULL || socket6 != NULL) &&
1119 G_SOCKET_LISTENER_GET_CLASS (listener)->changed)
1120 G_SOCKET_LISTENER_GET_CLASS (listener)->changed (listener);
1122 return candidate_port;