static char * socket_address_to_string (GSocketAddress *address) { char *res = NULL; if (G_IS_INET_SOCKET_ADDRESS (address)) { GInetAddress *inet_address; char *str; int port; inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address)); str = g_inet_address_to_string (inet_address); port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)); res = g_strdup_printf ("%s:%d", str, port); g_free (str); } #ifdef G_OS_UNIX else if (G_IS_UNIX_SOCKET_ADDRESS (address)) { GUnixSocketAddress *uaddr = G_UNIX_SOCKET_ADDRESS (address); res = g_strdup_printf ("%s:%s", unix_socket_address_types[g_unix_socket_address_get_address_type (uaddr)], g_unix_socket_address_get_path (uaddr)); } #endif return res; }
/* note that address_entry has already been validated => exactly one of path, tmpdir or abstract keys are set */ static gboolean try_unix (GDBusServer *server, const gchar *address_entry, GHashTable *key_value_pairs, GError **error) { gboolean ret; const gchar *path; const gchar *tmpdir; const gchar *abstract; GSocketAddress *address; ret = FALSE; address = NULL; path = g_hash_table_lookup (key_value_pairs, "path"); tmpdir = g_hash_table_lookup (key_value_pairs, "tmpdir"); abstract = g_hash_table_lookup (key_value_pairs, "abstract"); if (path != NULL) { address = g_unix_socket_address_new (path); } else if (tmpdir != NULL) { gint n; GString *s; GError *local_error; retry: s = g_string_new (tmpdir); g_string_append (s, "/dbus-"); for (n = 0; n < 8; n++) g_string_append_c (s, random_ascii ()); /* prefer abstract namespace if available */ if (g_unix_socket_address_abstract_names_supported ()) address = g_unix_socket_address_new_with_type (s->str, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); else address = g_unix_socket_address_new (s->str); g_string_free (s, TRUE); local_error = NULL; if (!g_socket_listener_add_address (server->listener, address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, NULL, /* source_object */ NULL, /* effective_address */ &local_error)) { if (local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_ADDRESS_IN_USE) { g_error_free (local_error); goto retry; } g_propagate_error (error, local_error); goto out; } ret = TRUE; goto out; } else if (abstract != NULL) { if (!g_unix_socket_address_abstract_names_supported ()) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Abstract name space not supported")); goto out; } address = g_unix_socket_address_new_with_type (abstract, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); } else { g_assert_not_reached (); } if (!g_socket_listener_add_address (server->listener, address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, NULL, /* source_object */ NULL, /* effective_address */ error)) goto out; ret = TRUE; out: if (address != NULL) { /* Fill out client_address if the connection attempt worked */ if (ret) { server->is_using_listener = TRUE; switch (g_unix_socket_address_get_address_type (G_UNIX_SOCKET_ADDRESS (address))) { case G_UNIX_SOCKET_ADDRESS_ABSTRACT: server->client_address = g_strdup_printf ("unix:abstract=%s", g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (address))); break; case G_UNIX_SOCKET_ADDRESS_PATH: server->client_address = g_strdup_printf ("unix:path=%s", g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (address))); break; default: g_assert_not_reached (); break; } } g_object_unref (address); } return ret; }