gdbusserver: retry binding to unix addresses only when possible

This adds the condition that a new unix address is tried only when there
is enough space to append random character(s) before the address reach
the length of UNIX_PATH_MAX.

Before this change, creating a GDBusServer with unix addresses longer
than UNIX_PATH_MAX that existed in the filesystem would never return. A
test that expects G_IO_ERROR_ADDRESS_IN_USE in such scenario was added.
This commit is contained in:
André Barnabá Silva
2025-10-29 02:38:00 -03:00
parent a4962ca460
commit dcf716945f
2 changed files with 58 additions and 2 deletions

View File

@@ -537,6 +537,50 @@ test_server_auth_sha1_tcp (void)
do_test_server_auth (INTEROP_FLAGS_SHA1 | INTEROP_FLAGS_TCP);
}
static void
test_server_path_in_use (void)
{
#ifdef G_OS_UNIX
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path)
#endif
GError *error = NULL;
GString *path = NULL;
gchar *listenable_address = NULL;
GDBusServer *server = NULL;
gchar *guid = NULL;
gchar *escaped = NULL;
path = g_string_new (g_get_tmp_dir ());
guid = g_dbus_generate_guid ();
while (path->len < UNIX_PATH_MAX - 1)
g_string_append_c (path, 'x');
escaped = g_dbus_address_escape_value (path->str);
listenable_address = g_strdup_printf ("unix:%s=%s", "dir", escaped);
g_assert_cmpint (g_mkdir_with_parents (path->str, 0700), ==, 0);
g_string_free (path, TRUE);
server = g_dbus_server_new_sync (listenable_address,
G_DBUS_SERVER_FLAGS_RUN_IN_THREAD,
guid,
NULL,
NULL,
&error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE);
g_error_free (error);
if (server != NULL)
g_dbus_server_stop (server);
g_clear_object (&server);
g_free (guid);
g_free (escaped);
g_free (listenable_address);
#else
g_test_skip ("unix: addresses only work on Unix");
#endif
}
int
main (int argc,
char *argv[])
@@ -552,6 +596,7 @@ main (int argc,
g_test_add_func ("/gdbus/server-auth/external/require-same-user", test_server_auth_external_require_same_user);
g_test_add_func ("/gdbus/server-auth/sha1", test_server_auth_sha1);
g_test_add_func ("/gdbus/server-auth/sha1/tcp", test_server_auth_sha1_tcp);
g_test_add_func ("/gdbus/server-auth/path-in-use", test_server_path_in_use);
return g_test_run();
}