summaryrefslogtreecommitdiff
path: root/gio
diff options
context:
space:
mode:
authorHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 11:06:12 +0900
committerHyunjee Kim <hj0426.kim@samsung.com>2019-12-03 11:06:12 +0900
commitac2d6c432f28bcb3835093099e344bceaba4363e (patch)
treed70878e0b00ff277442a1532919c70893d3f8447 /gio
parentd5e8c67d8c0767480fe257260d4aeff277a0f30a (diff)
downloadglib-ac2d6c432f28bcb3835093099e344bceaba4363e.tar.gz
glib-ac2d6c432f28bcb3835093099e344bceaba4363e.tar.bz2
glib-ac2d6c432f28bcb3835093099e344bceaba4363e.zip
Imported Upstream version 2.62.3upstream/2.62.3
Diffstat (limited to 'gio')
-rw-r--r--gio/gcredentials.c42
-rw-r--r--gio/gcredentialsprivate.h77
-rw-r--r--gio/gdbusauth.c27
-rw-r--r--gio/gdbusauthmechanismsha1.c26
-rw-r--r--gio/gdbusserver.c45
-rw-r--r--gio/gdesktopappinfo.c165
-rw-r--r--gio/glocalfilemonitor.c63
-rw-r--r--gio/glocalfilemonitor.h1
-rw-r--r--gio/kqueue/gkqueuefilemonitor.c2
-rw-r--r--gio/tests/gdbus-peer.c78
-rw-r--r--gio/tests/meson.build6
11 files changed, 370 insertions, 162 deletions
diff --git a/gio/gcredentials.c b/gio/gcredentials.c
index 57a39f2a2..ff9b7e0b8 100644
--- a/gio/gcredentials.c
+++ b/gio/gcredentials.c
@@ -265,6 +265,35 @@ g_credentials_to_string (GCredentials *credentials)
/* ---------------------------------------------------------------------------------------------------- */
+#if G_CREDENTIALS_USE_LINUX_UCRED
+/*
+ * Check whether @native contains invalid data. If getsockopt SO_PEERCRED
+ * is used on a TCP socket, it succeeds but yields a credentials structure
+ * with pid 0, uid -1 and gid -1. Similarly, if SO_PASSCRED is used on a
+ * receiving Unix socket when the sending socket did not also enable
+ * SO_PASSCRED, it can succeed but yield a credentials structure with
+ * pid 0, uid /proc/sys/kernel/overflowuid and gid
+ * /proc/sys/kernel/overflowgid.
+ */
+static gboolean
+linux_ucred_check_valid (struct ucred *native,
+ GError **error)
+{
+ if (native->pid == 0
+ || native->uid == -1
+ || native->gid == -1)
+ {
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_DATA,
+ "GCredentials contains invalid data");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif
+
/**
* g_credentials_is_same_user:
* @credentials: A #GCredentials.
@@ -294,7 +323,8 @@ g_credentials_is_same_user (GCredentials *credentials,
ret = FALSE;
#if G_CREDENTIALS_USE_LINUX_UCRED
- if (credentials->native.uid == other_credentials->native.uid)
+ if (linux_ucred_check_valid (&credentials->native, NULL)
+ && credentials->native.uid == other_credentials->native.uid)
ret = TRUE;
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
@@ -453,7 +483,10 @@ g_credentials_get_unix_user (GCredentials *credentials,
g_return_val_if_fail (error == NULL || *error == NULL, -1);
#if G_CREDENTIALS_USE_LINUX_UCRED
- ret = credentials->native.uid;
+ if (linux_ucred_check_valid (&credentials->native, error))
+ ret = credentials->native.uid;
+ else
+ ret = -1;
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
ret = credentials->native.cmcred_euid;
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
@@ -499,7 +532,10 @@ g_credentials_get_unix_pid (GCredentials *credentials,
g_return_val_if_fail (error == NULL || *error == NULL, -1);
#if G_CREDENTIALS_USE_LINUX_UCRED
- ret = credentials->native.pid;
+ if (linux_ucred_check_valid (&credentials->native, error))
+ ret = credentials->native.pid;
+ else
+ ret = -1;
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
ret = credentials->native.cmcred_pid;
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
index 4d1c420a8..e9ec09b9f 100644
--- a/gio/gcredentialsprivate.h
+++ b/gio/gcredentialsprivate.h
@@ -22,6 +22,77 @@
#include "gio/gcredentials.h"
#include "gio/gnetworking.h"
+/*
+ * G_CREDENTIALS_SUPPORTED:
+ *
+ * Defined to 1 if GCredentials works.
+ */
+#undef G_CREDENTIALS_SUPPORTED
+
+/*
+ * G_CREDENTIALS_USE_LINUX_UCRED, etc.:
+ *
+ * Defined to 1 if GCredentials uses Linux `struct ucred`, etc.
+ */
+#undef G_CREDENTIALS_USE_LINUX_UCRED
+#undef G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+#undef G_CREDENTIALS_USE_NETBSD_UNPCBID
+#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
+#undef G_CREDENTIALS_USE_SOLARIS_UCRED
+
+/*
+ * G_CREDENTIALS_NATIVE_TYPE:
+ *
+ * Defined to one of G_CREDENTIALS_TYPE_LINUX_UCRED, etc.
+ */
+#undef G_CREDENTIALS_NATIVE_TYPE
+
+/*
+ * G_CREDENTIALS_NATIVE_SIZE:
+ *
+ * Defined to the size of the %G_CREDENTIALS_NATIVE_TYPE
+ */
+#undef G_CREDENTIALS_NATIVE_SIZE
+
+/*
+ * G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED:
+ *
+ * Defined to 1 if we have a message-passing API in which credentials
+ * are attached to a particular message, such as `SCM_CREDENTIALS` on Linux
+ * or `SCM_CREDS` on FreeBSD.
+ */
+#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
+
+/*
+ * G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED:
+ *
+ * Defined to 1 if we have a `getsockopt()`-style API in which one end of
+ * a socket connection can directly query the credentials of the process
+ * that initiated the other end, such as `getsockopt SO_PEERCRED` on Linux
+ * or `getpeereid()` on multiple operating systems.
+ */
+#undef G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
+
+/*
+ * G_CREDENTIALS_SPOOFING_SUPPORTED:
+ *
+ * Defined to 1 if privileged processes can spoof their credentials when
+ * using the message-passing API.
+ */
+#undef G_CREDENTIALS_SPOOFING_SUPPORTED
+
+/*
+ * G_CREDENTIALS_PREFER_MESSAGE_PASSING:
+ *
+ * Defined to 1 if the data structure transferred by the message-passing
+ * API is strictly more informative than the one transferred by the
+ * `getsockopt()`-style API, and hence should be preferred, even for
+ * protocols like D-Bus that are defined in terms of the credentials of
+ * the (process that opened the) socket, as opposed to the credentials
+ * of an individual message.
+ */
+#undef G_CREDENTIALS_PREFER_MESSAGE_PASSING
+
#ifdef __linux__
#define G_CREDENTIALS_SUPPORTED 1
#define G_CREDENTIALS_USE_LINUX_UCRED 1
@@ -41,6 +112,12 @@
#define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct cmsgcred))
#define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
#define G_CREDENTIALS_SPOOFING_SUPPORTED 1
+/* GLib doesn't implement it yet, but FreeBSD's getsockopt()-style API
+ * is getpeereid(), which is not as informative as struct cmsgcred -
+ * it does not tell us the PID. As a result, libdbus prefers to use
+ * SCM_CREDS, and if we implement getpeereid() in future, we should
+ * do the same. */
+#define G_CREDENTIALS_PREFER_MESSAGE_PASSING 1
#elif defined(__NetBSD__)
#define G_CREDENTIALS_SUPPORTED 1
diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
index 752ec23fc..14cc5d70e 100644
--- a/gio/gdbusauth.c
+++ b/gio/gdbusauth.c
@@ -31,6 +31,7 @@
#include "gdbusutils.h"
#include "gioenumtypes.h"
#include "gcredentials.h"
+#include "gcredentialsprivate.h"
#include "gdbusprivate.h"
#include "giostream.h"
#include "gdatainputstream.h"
@@ -969,9 +970,31 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
- /* first read the NUL-byte */
+ /* read the NUL-byte, possibly with credentials attached */
#ifdef G_OS_UNIX
- if (G_IS_UNIX_CONNECTION (auth->priv->stream))
+#ifndef G_CREDENTIALS_PREFER_MESSAGE_PASSING
+ if (G_IS_SOCKET_CONNECTION (auth->priv->stream))
+ {
+ GSocket *sock = g_socket_connection_get_socket (G_SOCKET_CONNECTION (auth->priv->stream));
+
+ local_error = NULL;
+ credentials = g_socket_get_credentials (sock, &local_error);
+
+ if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
+ {
+ g_propagate_error (error, local_error);
+ goto out;
+ }
+ else
+ {
+ /* Clear the error indicator, so we can retry with
+ * g_unix_connection_receive_credentials() if necessary */
+ g_clear_error (&local_error);
+ }
+ }
+#endif
+
+ if (credentials == NULL && G_IS_UNIX_CONNECTION (auth->priv->stream))
{
local_error = NULL;
credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream),
diff --git a/gio/gdbusauthmechanismsha1.c b/gio/gdbusauthmechanismsha1.c
index 553bcdc32..2754d3c2b 100644
--- a/gio/gdbusauthmechanismsha1.c
+++ b/gio/gdbusauthmechanismsha1.c
@@ -48,6 +48,7 @@ struct _GDBusAuthMechanismSha1Private
gboolean is_client;
gboolean is_server;
GDBusAuthMechanismState state;
+ gchar *reject_reason; /* non-NULL iff (state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED) */
/* used on the client side */
gchar *to_send;
@@ -101,6 +102,7 @@ _g_dbus_auth_mechanism_sha1_finalize (GObject *object)
{
GDBusAuthMechanismSha1 *mechanism = G_DBUS_AUTH_MECHANISM_SHA1 (object);
+ g_free (mechanism->priv->reject_reason);
g_free (mechanism->priv->to_send);
g_free (mechanism->priv->cookie);
@@ -290,7 +292,7 @@ ensure_keyring_directory (GError **error)
goto out;
}
- if (g_mkdir (path, 0700) != 0)
+ if (g_mkdir_with_parents (path, 0700) != 0)
{
int errsv = errno;
g_set_error (error,
@@ -963,7 +965,8 @@ mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
tokens = g_strsplit (data, " ", 0);
if (g_strv_length (tokens) != 2)
{
- g_warning ("Malformed data '%s'", data);
+ g_free (m->priv->reject_reason);
+ m->priv->reject_reason = g_strdup_printf ("Malformed data '%s'", data);
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
goto out;
}
@@ -979,6 +982,8 @@ mechanism_server_data_receive (GDBusAuthMechanism *mechanism,
}
else
{
+ g_free (m->priv->reject_reason);
+ m->priv->reject_reason = g_strdup_printf ("SHA-1 mismatch");
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
}
@@ -1014,7 +1019,8 @@ mechanism_server_data_send (GDBusAuthMechanism *mechanism,
&m->priv->cookie,
&error))
{
- g_warning ("Error adding entry to keyring: %s", error->message);
+ g_free (m->priv->reject_reason);
+ m->priv->reject_reason = g_strdup_printf ("Error adding entry to keyring: %s", error->message);
g_error_free (error);
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
goto out;
@@ -1042,10 +1048,7 @@ mechanism_server_get_reject_reason (GDBusAuthMechanism *mechanism)
g_return_val_if_fail (m->priv->is_server && !m->priv->is_client, NULL);
g_return_val_if_fail (m->priv->state == G_DBUS_AUTH_MECHANISM_STATE_REJECTED, NULL);
- /* can never end up here because we are never in the REJECTED state */
- g_assert_not_reached ();
-
- return NULL;
+ return g_strdup (m->priv->reject_reason);
}
static void
@@ -1128,7 +1131,8 @@ mechanism_client_data_receive (GDBusAuthMechanism *mechanism,
tokens = g_strsplit (data, " ", 0);
if (g_strv_length (tokens) != 3)
{
- g_warning ("Malformed data '%s'", data);
+ g_free (m->priv->reject_reason);
+ m->priv->reject_reason = g_strdup_printf ("Malformed data '%s'", data);
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
goto out;
}
@@ -1137,7 +1141,8 @@ mechanism_client_data_receive (GDBusAuthMechanism *mechanism,
cookie_id = g_ascii_strtoll (tokens[1], &endp, 10);
if (*endp != '\0')
{
- g_warning ("Malformed cookie_id '%s'", tokens[1]);
+ g_free (m->priv->reject_reason);
+ m->priv->reject_reason = g_strdup_printf ("Malformed cookie_id '%s'", tokens[1]);
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
goto out;
}
@@ -1147,7 +1152,8 @@ mechanism_client_data_receive (GDBusAuthMechanism *mechanism,
cookie = keyring_lookup_entry (cookie_context, cookie_id, &error);
if (cookie == NULL)
{
- g_warning ("Problems looking up entry in keyring: %s", error->message);
+ g_free (m->priv->reject_reason);
+ m->priv->reject_reason = g_strdup_printf ("Problems looking up entry in keyring: %s", error->message);
g_error_free (error);
m->priv->state = G_DBUS_AUTH_MECHANISM_STATE_REJECTED;
goto out;
diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c
index 26f8dadd0..4a8dab0ea 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -179,6 +179,8 @@ g_dbus_server_finalize (GObject *object)
{
GDBusServer *server = G_DBUS_SERVER (object);
+ g_assert (!server->active);
+
if (server->authentication_observer != NULL)
g_object_unref (server->authentication_observer);
@@ -197,19 +199,8 @@ g_dbus_server_finalize (GObject *object)
g_free (server->nonce);
}
- if (server->unix_socket_path)
- {
- if (g_unlink (server->unix_socket_path) != 0)
- g_warning ("Failed to delete %s: %s", server->unix_socket_path, g_strerror (errno));
- g_free (server->unix_socket_path);
- }
-
- if (server->nonce_file)
- {
- if (g_unlink (server->nonce_file) != 0)
- g_warning ("Failed to delete %s: %s", server->nonce_file, g_strerror (errno));
- g_free (server->nonce_file);
- }
+ g_free (server->unix_socket_path);
+ g_free (server->nonce_file);
g_main_context_unref (server->main_context_at_construction);
@@ -622,6 +613,12 @@ g_dbus_server_start (GDBusServer *server)
return;
/* Right now we don't have any transport not using the listener... */
g_assert (server->is_using_listener);
+ server->run_signal_handler_id = g_signal_connect_data (G_SOCKET_SERVICE (server->listener),
+ "run",
+ G_CALLBACK (on_run),
+ g_object_ref (server),
+ (GClosureNotify) g_object_unref,
+ 0 /* flags */);
g_socket_service_start (G_SOCKET_SERVICE (server->listener));
server->active = TRUE;
g_object_notify (G_OBJECT (server), "active");
@@ -648,6 +645,18 @@ g_dbus_server_stop (GDBusServer *server)
g_socket_service_stop (G_SOCKET_SERVICE (server->listener));
server->active = FALSE;
g_object_notify (G_OBJECT (server), "active");
+
+ if (server->unix_socket_path)
+ {
+ if (g_unlink (server->unix_socket_path) != 0)
+ g_warning ("Failed to delete %s: %s", server->unix_socket_path, g_strerror (errno));
+ }
+
+ if (server->nonce_file)
+ {
+ if (g_unlink (server->nonce_file) != 0)
+ g_warning ("Failed to delete %s: %s", server->nonce_file, g_strerror (errno));
+ }
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1159,15 +1168,7 @@ initable_init (GInitable *initable,
if (ret)
{
- if (last_error != NULL)
- g_error_free (last_error);
-
- /* Right now we don't have any transport not using the listener... */
- g_assert (server->is_using_listener);
- server->run_signal_handler_id = g_signal_connect (G_SOCKET_SERVICE (server->listener),
- "run",
- G_CALLBACK (on_run),
- server);
+ g_clear_error (&last_error);
}
else
{
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index a484c63d4..f1e2fdd65 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -143,6 +143,7 @@ G_DEFINE_TYPE_WITH_CODE (GDesktopAppInfo, g_desktop_app_info, G_TYPE_OBJECT,
typedef struct
{
+ gatomicrefcount ref_count;
gchar *path;
gchar *alternatively_watching;
gboolean is_config;
@@ -154,17 +155,35 @@ typedef struct
GHashTable *memory_implementations;
} DesktopFileDir;
-static DesktopFileDir *desktop_file_dirs;
-static guint n_desktop_file_dirs;
+static GPtrArray *desktop_file_dirs = NULL;
static const gchar *desktop_file_dirs_config_dir = NULL;
-static const guint desktop_file_dir_user_config_index = 0;
-static guint desktop_file_dir_user_data_index;
+static DesktopFileDir *desktop_file_dir_user_config = NULL; /* (owned) */
+static DesktopFileDir *desktop_file_dir_user_data = NULL; /* (owned) */
static GMutex desktop_file_dir_lock;
static const gchar *gio_launch_desktop_path = NULL;
/* Monitor 'changed' signal handler {{{2 */
static void desktop_file_dir_reset (DesktopFileDir *dir);
+static DesktopFileDir *
+desktop_file_dir_ref (DesktopFileDir *dir)
+{
+ g_atomic_ref_count_inc (&dir->ref_count);
+
+ return dir;
+}
+
+static void
+desktop_file_dir_unref (DesktopFileDir *dir)
+{
+ if (g_atomic_ref_count_dec (&dir->ref_count))
+ {
+ desktop_file_dir_reset (dir);
+ g_free (dir->path);
+ g_free (dir);
+ }
+}
+
/*< internal >
* desktop_file_dir_get_alternative_dir:
* @dir: a #DesktopFileDir
@@ -270,11 +289,15 @@ static gboolean
desktop_file_dir_app_name_is_masked (DesktopFileDir *dir,
const gchar *app_name)
{
- while (dir > desktop_file_dirs)
+ guint i;
+
+ for (i = 0; i < desktop_file_dirs->len; i++)
{
- dir--;
+ DesktopFileDir *i_dir = g_ptr_array_index (desktop_file_dirs, i);
- if (dir->app_names && g_hash_table_contains (dir->app_names, app_name))
+ if (dir == i_dir)
+ return FALSE;
+ if (i_dir->app_names && g_hash_table_contains (i_dir->app_names, app_name))
return TRUE;
}
@@ -1251,44 +1274,41 @@ desktop_file_dir_unindexed_get_implementations (DesktopFileDir *dir,
/* DesktopFileDir "API" {{{2 */
/*< internal >
- * desktop_file_dir_create:
- * @array: the #GArray to add a new item to
+ * desktop_file_dir_new:
* @data_dir: an XDG_DATA_DIR
*
- * Creates a #DesktopFileDir for the corresponding @data_dir, adding it
- * to @array.
+ * Creates a #DesktopFileDir for the corresponding @data_dir.
*/
-static void
-desktop_file_dir_create (GArray *array,
- const gchar *data_dir)
+static DesktopFileDir *
+desktop_file_dir_new (const gchar *data_dir)
{
- DesktopFileDir dir = { 0, };
+ DesktopFileDir *dir = g_new0 (DesktopFileDir, 1);
- dir.path = g_build_filename (data_dir, "applications", NULL);
+ g_atomic_ref_count_init (&dir->ref_count);
+ dir->path = g_build_filename (data_dir, "applications", NULL);
- g_array_append_val (array, dir);
+ return g_steal_pointer (&dir);
}
/*< internal >
- * desktop_file_dir_create:
- * @array: the #GArray to add a new item to
+ * desktop_file_dir_new_for_config:
* @config_dir: an XDG_CONFIG_DIR
*
- * Just the same as desktop_file_dir_create() except that it does not
+ * Just the same as desktop_file_dir_new() except that it does not
* add the "applications" directory. It also marks the directory as
* config-only, which prevents us from attempting to find desktop files
* here.
*/
-static void
-desktop_file_dir_create_for_config (GArray *array,
- const gchar *config_dir)
+static DesktopFileDir *
+desktop_file_dir_new_for_config (const gchar *config_dir)
{
- DesktopFileDir dir = { 0, };
+ DesktopFileDir *dir = g_new0 (DesktopFileDir, 1);
- dir.path = g_strdup (config_dir);
- dir.is_config = TRUE;
+ g_atomic_ref_count_init (&dir->ref_count);
+ dir->path = g_strdup (config_dir);
+ dir->is_config = TRUE;
- g_array_append_val (array, dir);
+ return g_steal_pointer (&dir);
}
/*< internal >
@@ -1309,6 +1329,7 @@ desktop_file_dir_reset (DesktopFileDir *dir)
if (dir->monitor)
{
g_signal_handlers_disconnect_by_func (dir->monitor, desktop_file_dir_changed, dir);
+ g_file_monitor_cancel (dir->monitor);
g_object_unref (dir->monitor);
dir->monitor = NULL;
}
@@ -1340,6 +1361,14 @@ desktop_file_dir_reset (DesktopFileDir *dir)
dir->is_setup = FALSE;
}
+static void
+closure_notify_cb (gpointer data,
+ GClosure *closure)
+{
+ DesktopFileDir *dir = data;
+ desktop_file_dir_unref (dir);
+}
+
/*< internal >
* desktop_file_dir_init:
* @dir: a #DesktopFileDir
@@ -1368,7 +1397,9 @@ desktop_file_dir_init (DesktopFileDir *dir)
* we will fall back to polling.
*/
dir->monitor = g_local_file_monitor_new_in_worker (watch_dir, TRUE, G_FILE_MONITOR_NONE,
- desktop_file_dir_changed, dir, NULL);
+ desktop_file_dir_changed,
+ desktop_file_dir_ref (dir),
+ closure_notify_cb, NULL);
desktop_file_dir_unindexed_init (dir);
@@ -1487,55 +1518,51 @@ desktop_file_dirs_lock (void)
/* If the XDG dirs configuration has changed (expected only during tests),
* clear and reload the state. */
- if (g_strcmp0 (desktop_file_dirs_config_dir, user_config_dir) != 0)
+ if (desktop_file_dirs_config_dir != NULL &&
+ g_strcmp0 (desktop_file_dirs_config_dir, user_config_dir) != 0)
{
g_debug ("%s: Resetting desktop app info dirs from %s to %s",
G_STRFUNC, desktop_file_dirs_config_dir, user_config_dir);
- for (i = 0; i < n_desktop_file_dirs; i++)
- desktop_file_dir_reset (&desktop_file_dirs[i]);
- g_clear_pointer (&desktop_file_dirs, g_free);
- n_desktop_file_dirs = 0;
- desktop_file_dir_user_data_index = 0;
+ g_ptr_array_set_size (desktop_file_dirs, 0);
+ g_clear_pointer (&desktop_file_dir_user_config, desktop_file_dir_unref);
+ g_clear_pointer (&desktop_file_dir_user_data, desktop_file_dir_unref);
}
- if (desktop_file_dirs == NULL)
+ if (desktop_file_dirs == NULL || desktop_file_dirs->len == 0)
{
const char * const *dirs;
- GArray *tmp;
gint i;
- tmp = g_array_new (FALSE, FALSE, sizeof (DesktopFileDir));
+ if (desktop_file_dirs == NULL)
+ desktop_file_dirs = g_ptr_array_new_with_free_func ((GDestroyNotify) desktop_file_dir_unref);
/* First, the configs. Highest priority: the user's ~/.config */
- desktop_file_dir_create_for_config (tmp, user_config_dir);
+ desktop_file_dir_user_config = desktop_file_dir_new_for_config (user_config_dir);
+ g_ptr_array_add (desktop_file_dirs, desktop_file_dir_ref (desktop_file_dir_user_config));
/* Next, the system configs (/etc/xdg, and so on). */
dirs = g_get_system_config_dirs ();
for (i = 0; dirs[i]; i++)
- desktop_file_dir_create_for_config (tmp, dirs[i]);
+ g_ptr_array_add (desktop_file_dirs, desktop_file_dir_new_for_config (dirs[i]));
/* Now the data. Highest priority: the user's ~/.local/share/applications */
- desktop_file_dir_user_data_index = tmp->len;
- desktop_file_dir_create (tmp, g_get_user_data_dir ());
+ desktop_file_dir_user_data = desktop_file_dir_new (g_get_user_data_dir ());
+ g_ptr_array_add (desktop_file_dirs, desktop_file_dir_ref (desktop_file_dir_user_data));
/* Following that, XDG_DATA_DIRS/applications, in order */
dirs = g_get_system_data_dirs ();
for (i = 0; dirs[i]; i++)
- desktop_file_dir_create (tmp, dirs[i]);
+ g_ptr_array_add (desktop_file_dirs, desktop_file_dir_new (dirs[i]));
/* The list of directories will never change after this, unless
* g_get_user_config_dir() changes due to %G_TEST_OPTION_ISOLATE_DIRS. */
- desktop_file_dirs = (DesktopFileDir *) tmp->data;
- n_desktop_file_dirs = tmp->len;
desktop_file_dirs_config_dir = user_config_dir;
-
- g_array_free (tmp, FALSE);
}
- for (i = 0; i < n_desktop_file_dirs; i++)
- if (!desktop_file_dirs[i].is_setup)
- desktop_file_dir_init (&desktop_file_dirs[i]);
+ for (i = 0; i < desktop_file_dirs->len; i++)
+ if (!((DesktopFileDir *) g_ptr_array_index (desktop_file_dirs, i))->is_setup)
+ desktop_file_dir_init (g_ptr_array_index (desktop_file_dirs, i));
}
static void
@@ -1549,8 +1576,8 @@ desktop_file_dirs_invalidate_user_config (void)
{
g_mutex_lock (&desktop_file_dir_lock);
- if (n_desktop_file_dirs)
- desktop_file_dir_reset (&desktop_file_dirs[desktop_file_dir_user_config_index]);
+ if (desktop_file_dir_user_config != NULL)
+ desktop_file_dir_reset (desktop_file_dir_user_config);
g_mutex_unlock (&desktop_file_dir_lock);
}
@@ -1560,8 +1587,8 @@ desktop_file_dirs_invalidate_user_data (void)
{
g_mutex_lock (&desktop_file_dir_lock);
- if (n_desktop_file_dirs)
- desktop_file_dir_reset (&desktop_file_dirs[desktop_file_dir_user_data_index]);
+ if (desktop_file_dir_user_data != NULL)
+ desktop_file_dir_reset (desktop_file_dir_user_data);
g_mutex_unlock (&desktop_file_dir_lock);
}
@@ -1950,9 +1977,9 @@ g_desktop_app_info_new (const char *desktop_id)
desktop_file_dirs_lock ();
- for (i = 0; i < n_desktop_file_dirs; i++)
+ for (i = 0; i < desktop_file_dirs->len; i++)
{
- appinfo = desktop_file_dir_get_app (&desktop_file_dirs[i], desktop_id);
+ appinfo = desktop_file_dir_get_app (g_ptr_array_index (desktop_file_dirs, i), desktop_id);
if (appinfo)
break;
@@ -4109,8 +4136,8 @@ g_desktop_app_info_get_desktop_ids_for_content_type (const gchar *content_type,
desktop_file_dirs_lock ();
for (i = 0; types[i]; i++)
- for (j = 0; j < n_desktop_file_dirs; j++)
- desktop_file_dir_mime_lookup (&desktop_file_dirs[j], types[i], hits, blacklist);
+ for (j = 0; j < desktop_file_dirs->len; j++)
+ desktop_file_dir_mime_lookup (g_ptr_array_index (desktop_file_dirs, j), types[i], hits, blacklist);
/* We will keep the hits past unlocking, so we must dup them */
for (i = 0; i < hits->len; i++)
@@ -4312,21 +4339,21 @@ g_app_info_get_default_for_type (const char *content_type,
for (i = 0; types[i]; i++)
{
/* Collect all the default apps for this type */
- for (j = 0; j < n_desktop_file_dirs; j++)
- desktop_file_dir_default_lookup (&desktop_file_dirs[j], types[i], results);
+ for (j = 0; j < desktop_file_dirs->len; j++)
+ desktop_file_dir_default_lookup (g_ptr_array_index (desktop_file_dirs, j), types[i], results);
/* Consider the associations as well... */
- for (j = 0; j < n_desktop_file_dirs; j++)
- desktop_file_dir_mime_lookup (&desktop_file_dirs[j], types[i], results, blacklist);
+ for (j = 0; j < desktop_file_dirs->len; j++)
+ desktop_file_dir_mime_lookup (g_ptr_array_index (desktop_file_dirs, j), types[i], results, blacklist);
/* (If any), see if one of those apps is installed... */
for (j = 0; j < results->len; j++)
{
const gchar *desktop_id = g_ptr_array_index (results, j);
- for (k = 0; k < n_desktop_file_dirs; k++)
+ for (k = 0; k < desktop_file_dirs->len; k++)
{
- info = (GAppInfo *) desktop_file_dir_get_app (&desktop_file_dirs[k], desktop_id);
+ info = (GAppInfo *) desktop_file_dir_get_app (g_ptr_array_index (desktop_file_dirs, k), desktop_id);
if (info)
{
@@ -4405,8 +4432,8 @@ g_desktop_app_info_get_implementations (const gchar *interface)
desktop_file_dirs_lock ();
- for (i = 0; i < n_desktop_file_dirs; i++)
- desktop_file_dir_get_implementations (&desktop_file_dirs[i], &result, interface);
+ for (i = 0; i < desktop_file_dirs->len; i++)
+ desktop_file_dir_get_implementations (g_ptr_array_index (desktop_file_dirs, i), &result, interface);
desktop_file_dirs_unlock ();
@@ -4464,11 +4491,11 @@ g_desktop_app_info_search (const gchar *search_string)
reset_total_search_results ();
- for (i = 0; i < n_desktop_file_dirs; i++)
+ for (i = 0; i < desktop_file_dirs->len; i++)
{
for (j = 0; search_tokens[j]; j++)
{
- desktop_file_dir_search (&desktop_file_dirs[i], search_tokens[j]);
+ desktop_file_dir_search (g_ptr_array_index (desktop_file_dirs, i), search_tokens[j]);
merge_token_results (j == 0);
}
merge_directory_results ();
@@ -4543,8 +4570,8 @@ g_app_info_get_all (void)
desktop_file_dirs_lock ();
- for (i = 0; i < n_desktop_file_dirs; i++)
- desktop_file_dir_get_all (&desktop_file_dirs[i], apps);
+ for (i = 0; i < desktop_file_dirs->len; i++)
+ desktop_file_dir_get_all (g_ptr_array_index (desktop_file_dirs, i), apps);
desktop_file_dirs_unlock ();
diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c
index 897d5f244..3212beff7 100644
--- a/gio/glocalfilemonitor.c
+++ b/gio/glocalfilemonitor.c
@@ -46,7 +46,7 @@ struct _GFileMonitorSource {
GSource source;
GMutex lock;
- gpointer instance;
+ GWeakRef instance_ref;
GFileMonitorFlags flags;
gchar *dirname;
gchar *basename;
@@ -348,6 +348,7 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms,
gint64 event_time)
{
gboolean interesting = TRUE;
+ GFileMonitor *instance = NULL;
g_assert (!child || is_basename (child));
g_assert (!rename_to || is_basename (rename_to));
@@ -359,7 +360,8 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms,
g_mutex_lock (&fms->lock);
/* monitor is already gone -- don't bother */
- if (!fms->instance)
+ instance = g_weak_ref_get (&fms->instance_ref);
+ if (instance == NULL)
{
g_mutex_unlock (&fms->lock);
return TRUE;
@@ -450,6 +452,7 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms,
g_file_monitor_source_update_ready_time (fms);
g_mutex_unlock (&fms->lock);
+ g_clear_object (&instance);
return interesting;
}
@@ -500,9 +503,11 @@ g_file_monitor_source_dispatch (GSource *source,
QueuedEvent *event;
GQueue event_queue;
gint64 now;
+ GFileMonitor *instance = NULL;
/* make sure the monitor still exists */
- if (!fms->instance)
+ instance = g_weak_ref_get (&fms->instance_ref);
+ if (instance == NULL)
return FALSE;
now = g_source_get_time (source);
@@ -550,15 +555,18 @@ g_file_monitor_source_dispatch (GSource *source,
g_file_monitor_source_update_ready_time (fms);
+ g_clear_object (&instance);
g_mutex_unlock (&fms->lock);
/* We now have our list of events to deliver */
while ((event = g_queue_pop_head (&event_queue)))
{
/* an event handler could destroy 'instance', so check each time */
- if (fms->instance)
- g_file_monitor_emit_event (fms->instance, event->child, event->other, event->event_type);
+ instance = g_weak_ref_get (&fms->instance_ref);
+ if (instance != NULL)
+ g_file_monitor_emit_event (instance, event->child, event->other, event->event_type);
+ g_clear_object (&instance);
queued_event_free (event);
}
@@ -568,31 +576,28 @@ g_file_monitor_source_dispatch (GSource *source,
static void
g_file_monitor_source_dispose (GFileMonitorSource *fms)
{
+ GHashTableIter iter;
+ gpointer seqiter;
+ QueuedEvent *event;
+
g_mutex_lock (&fms->lock);
- if (fms->instance)
+ g_hash_table_iter_init (&iter, fms->pending_changes_table);
+ while (g_hash_table_iter_next (&iter, NULL, &seqiter))
{
- GHashTableIter iter;
- gpointer seqiter;
- QueuedEvent *event;
-
- g_hash_table_iter_init (&iter, fms->pending_changes_table);
- while (g_hash_table_iter_next (&iter, NULL, &seqiter))
- {
- g_hash_table_iter_remove (&iter);
- g_sequence_remove (seqiter);
- }
+ g_hash_table_iter_remove (&iter);
+ g_sequence_remove (seqiter);
+ }
- while ((event = g_queue_pop_head (&fms->event_queue)))
- queued_event_free (event);
+ while ((event = g_queue_pop_head (&fms->event_queue)))
+ queued_event_free (event);
- g_assert (g_sequence_is_empty (fms->pending_changes));
- g_assert (g_hash_table_size (fms->pending_changes_table) == 0);
- g_assert (fms->event_queue.length == 0);
- fms->instance = NULL;
+ g_assert (g_sequence_is_empty (fms->pending_changes));
+ g_assert (g_hash_table_size (fms->pending_changes_table) == 0);
+ g_assert (fms->event_queue.length == 0);
+ g_weak_ref_set (&fms->instance_ref, NULL);
- g_file_monitor_source_update_ready_time (fms);
- }
+ g_file_monitor_source_update_ready_time (fms);
g_mutex_unlock (&fms->lock);
@@ -605,7 +610,9 @@ g_file_monitor_source_finalize (GSource *source)
GFileMonitorSource *fms = (GFileMonitorSource *) source;
/* should already have been cleared in dispose of the monitor */
- g_assert (fms->instance == NULL);
+ g_assert (g_weak_ref_get (&fms->instance_ref) == NULL);
+ g_weak_ref_clear (&fms->instance_ref);
+
g_assert (g_sequence_is_empty (fms->pending_changes));
g_assert (g_hash_table_size (fms->pending_changes_table) == 0);
g_assert (fms->event_queue.length == 0);
@@ -653,7 +660,7 @@ g_file_monitor_source_new (gpointer instance,
g_source_set_name (source, "GFileMonitorSource");
g_mutex_init (&fms->lock);
- fms->instance = instance;
+ g_weak_ref_init (&fms->instance_ref, instance);
fms->pending_changes = g_sequence_new (pending_change_free);
fms->pending_changes_table = g_hash_table_new (str_hash0, str_equal0);
fms->rate_limit = DEFAULT_RATE_LIMIT;
@@ -887,6 +894,7 @@ g_local_file_monitor_new_in_worker (const gchar *pathname,
GFileMonitorFlags flags,
GFileMonitorCallback callback,
gpointer user_data,
+ GClosureNotify destroy_user_data,
GError **error)
{
GLocalFileMonitor *monitor;
@@ -899,7 +907,8 @@ g_local_file_monitor_new_in_worker (const gchar *pathname,
if (monitor)
{
if (callback)
- g_signal_connect (monitor, "changed", G_CALLBACK (callback), user_data);
+ g_signal_connect_data (monitor, "changed", G_CALLBACK (callback),
+ user_data, destroy_user_data, 0 /* flags */);
g_local_file_monitor_start (monitor, pathname, is_directory, flags, GLIB_PRIVATE_CALL(g_get_worker_context) ());
}
diff --git a/gio/glocalfilemonitor.h b/gio/glocalfilemonitor.h
index 7f3baadbd..3d3cf7528 100644
--- a/gio/glocalfilemonitor.h
+++ b/gio/glocalfilemonitor.h
@@ -87,6 +87,7 @@ g_local_file_monitor_new_in_worker (const gchar *pathname,
GFileMonitorFlags flags,
GFileMonitorCallback callback,
gpointer user_data,
+ GClosureNotify destroy_user_data,
GError **error);
/* for implementations of GLocalFileMonitor */
diff --git a/gio/kqueue/gkqueuefilemonitor.c b/gio/kqueue/gkqueuefilemonitor.c
index 3055506a9..fd0db4e29 100644
--- a/gio/kqueue/gkqueuefilemonitor.c
+++ b/gio/kqueue/gkqueuefilemonitor.c
@@ -107,7 +107,7 @@ G_DEFINE_TYPE_WITH_CODE (GKqueueFileMonitor, g_kqueue_file_monitor, G_TYPE_LOCAL
static inline unsigned int
note_all (void)
{
- unsigned int notes = NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME;
+ unsigned int notes = NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE;
#ifdef NOTE_TRUNCATE
notes |= NOTE_TRUNCATE;
#endif
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index a3260a6e0..d01bc9a7a 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -273,26 +273,21 @@ setup_test_address (void)
{
if (is_unix)
{
- g_test_message ("Testing with unix:tmpdir address");
- if (g_unix_socket_address_abstract_names_supported ())
- tmp_address = g_strdup ("unix:tmpdir=/tmp/gdbus-test-");
- else
- {
- tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL);
- tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
- }
+ g_test_message ("Testing with unix:dir address");
+ tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL);
+ tmp_address = g_strdup_printf ("unix:dir=%s", tmpdir);
}
else
- tmp_address = g_strdup ("nonce-tcp:");
+ tmp_address = g_strdup ("nonce-tcp:host=127.0.0.1");
}
#ifdef G_OS_UNIX
static void
-setup_dir_test_address (void)
+setup_tmpdir_test_address (void)
{
- g_test_message ("Testing with unix:dir address");
+ g_test_message ("Testing with unix:tmpdir address");
tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL);
- tmp_address = g_strdup_printf ("unix:dir=%s", tmpdir);
+ tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir);
}
static void
@@ -313,7 +308,8 @@ teardown_test_address (void)
/* Ensuring the rmdir succeeds also ensures any sockets created on the
* filesystem are also deleted.
*/
- g_assert_cmpint (g_rmdir (tmpdir), ==, 0);
+ g_assert_cmpstr (g_rmdir (tmpdir) == 0 ? "OK" : g_strerror (errno),
+ ==, "OK");
g_clear_pointer (&tmpdir, g_free);
}
}
@@ -730,7 +726,7 @@ do_test_peer (void)
c = g_dbus_connection_new_for_address_sync (is_unix ? "unix:path=/tmp/gdbus-test-does-not-exist-pid" :
/* NOTE: Even if something is listening on port 12345 the connection
* will fail because the nonce file doesn't exist */
- "nonce-tcp:host=localhost,port=12345,noncefile=this-does-not-exist-gdbus",
+ "nonce-tcp:host=127.0.0.1,port=12345,noncefile=this-does-not-exist-gdbus",
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
NULL, /* GDBusAuthObserver */
NULL, /* cancellable */
@@ -1033,6 +1029,9 @@ do_test_peer (void)
static void
test_peer (void)
{
+ test_guid = g_dbus_generate_guid ();
+ loop = g_main_loop_new (NULL, FALSE);
+
/* Run this test multiple times using different address formats to ensure
* they all work.
*/
@@ -1041,7 +1040,7 @@ test_peer (void)
teardown_test_address ();
#ifdef G_OS_UNIX
- setup_dir_test_address ();
+ setup_tmpdir_test_address ();
do_test_peer ();
teardown_test_address ();
@@ -1049,6 +1048,9 @@ test_peer (void)
do_test_peer ();
teardown_test_address ();
#endif
+
+ g_main_loop_unref (loop);
+ g_free (test_guid);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1064,6 +1066,9 @@ test_peer_signals (void)
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1620");
+ test_guid = g_dbus_generate_guid ();
+ loop = g_main_loop_new (NULL, FALSE);
+
setup_test_address ();
memset (&data, '\0', sizeof (PeerData));
data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
@@ -1119,6 +1124,9 @@ test_peer_signals (void)
g_thread_join (service_thread);
teardown_test_address ();
+
+ g_main_loop_unref (loop);
+ g_free (test_guid);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1246,6 +1254,7 @@ dmp_thread_func (gpointer user_data)
data->loop = g_main_loop_new (data->context, FALSE);
g_main_loop_run (data->loop);
+ g_dbus_server_stop (data->server);
g_main_context_pop_thread_default (data->context);
g_free (guid);
@@ -1260,6 +1269,9 @@ delayed_message_processing (void)
GThread *service_thread;
guint n;
+ test_guid = g_dbus_generate_guid ();
+ loop = g_main_loop_new (NULL, FALSE);
+
setup_test_address ();
data = g_new0 (DmpData, 1);
@@ -1307,6 +1319,9 @@ delayed_message_processing (void)
g_thread_join (service_thread);
dmp_data_free (data);
teardown_test_address ();
+
+ g_main_loop_unref (loop);
+ g_free (test_guid);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1360,7 +1375,7 @@ nonce_tcp_service_thread_func (gpointer user_data)
error = NULL;
observer = g_dbus_auth_observer_new ();
- server = g_dbus_server_new_sync ("nonce-tcp:",
+ server = g_dbus_server_new_sync ("nonce-tcp:host=127.0.0.1",
G_DBUS_SERVER_FLAGS_NONE,
test_guid,
observer,
@@ -1405,6 +1420,9 @@ test_nonce_tcp (void)
gboolean res;
const gchar *address;
+ test_guid = g_dbus_generate_guid ();
+ loop = g_main_loop_new (NULL, FALSE);
+
memset (&data, '\0', sizeof (PeerData));
data.current_connections = g_ptr_array_new_with_free_func (g_object_unref);
@@ -1512,6 +1530,9 @@ test_nonce_tcp (void)
g_thread_join (service_thread);
g_ptr_array_unref (data.current_connections);
+
+ g_main_loop_unref (loop);
+ g_free (test_guid);
}
static void
@@ -1563,7 +1584,7 @@ tcp_anonymous_service_thread_func (gpointer user_data)
g_main_context_push_thread_default (service_context);
error = NULL;
- server = g_dbus_server_new_sync ("tcp:",
+ server = g_dbus_server_new_sync ("tcp:host=127.0.0.1",
G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
test_guid,
NULL, /* GDBusObserver* */
@@ -1596,6 +1617,9 @@ test_tcp_anonymous (void)
GDBusConnection *connection;
GError *error;
+ test_guid = g_dbus_generate_guid ();
+ loop = g_main_loop_new (NULL, FALSE);
+
seen_connection = FALSE;
service_thread = g_thread_new ("tcp-anon-service",
tcp_anonymous_service_thread_func,
@@ -1623,6 +1647,9 @@ test_tcp_anonymous (void)
server = NULL;
g_thread_join (service_thread);
+
+ g_main_loop_unref (loop);
+ g_free (test_guid);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1767,6 +1794,9 @@ codegen_test_peer (void)
GVariant *value;
const gchar *s;
+ test_guid = g_dbus_generate_guid ();
+ loop = g_main_loop_new (NULL, FALSE);
+
setup_test_address ();
/* bring up a server - we run the server in a different thread to avoid deadlocks */
@@ -1874,6 +1904,9 @@ codegen_test_peer (void)
g_thread_join (service_thread);
teardown_test_address ();
+
+ g_main_loop_unref (loop);
+ g_free (test_guid);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1886,17 +1919,12 @@ main (int argc,
gint ret;
GDBusNodeInfo *introspection_data = NULL;
- g_test_init (&argc, &argv, NULL);
+ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL);
g_assert (introspection_data != NULL);
test_interface_introspection_data = introspection_data->interfaces[0];
- test_guid = g_dbus_generate_guid ();
-
- /* all the tests rely on a shared main loop */
- loop = g_main_loop_new (NULL, FALSE);
-
g_test_add_func ("/gdbus/peer-to-peer", test_peer);
g_test_add_func ("/gdbus/peer-to-peer/signals", test_peer_signals);
g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
@@ -1906,10 +1934,8 @@ main (int argc,
g_test_add_func ("/gdbus/credentials", test_credentials);
g_test_add_func ("/gdbus/codegen-peer-to-peer", codegen_test_peer);
- ret = g_test_run();
+ ret = g_test_run ();
- g_main_loop_unref (loop);
- g_free (test_guid);
g_dbus_node_info_unref (introspection_data);
return ret;
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
index b5593a4ec..382dfccad 100644
--- a/gio/tests/meson.build
+++ b/gio/tests/meson.build
@@ -577,7 +577,9 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
# Support for --add-symbol was added to LLVM objcopy in 2019
# (https://reviews.llvm.org/D58234). FIXME: This test could be enabled for
# LLVM once that support is in a stable release.
- if build_machine.system() == 'linux' and cc.get_id() == 'gcc'
+ objcopy = find_program('objcopy', required : false)
+
+ if build_machine.system() == 'linux' and cc.get_id() == 'gcc' and objcopy.found()
test_gresource_binary = custom_target('test5.gresource',
input : 'test5.gresource.xml',
output : 'test5.gresource',
@@ -616,7 +618,7 @@ if not meson.is_cross_build() or meson.has_exe_wrapper()
test_resources_binary2 = custom_target('test_resources2.o',
input : test_resources_binary,
output : 'test_resources2.o',
- command : ['objcopy',
+ command : [objcopy,
'--add-symbol','_g_binary_test1_resource_data=.data:0',
'@INPUT@',
'@OUTPUT@'])