diff options
author | Hyunjee Kim <hj0426.kim@samsung.com> | 2019-12-03 10:55:17 +0900 |
---|---|---|
committer | Hyunjee Kim <hj0426.kim@samsung.com> | 2019-12-03 10:55:17 +0900 |
commit | d5a1e991c0c65ccab2b0cb9b8b9320ee3b2ea8e5 (patch) | |
tree | 8cc185ac77ddbf961f3f7356438007a72e7e1ba4 /gio | |
parent | 25d63acb6a98478b3fd901735198f87c644ffa64 (diff) | |
download | glib-d5a1e991c0c65ccab2b0cb9b8b9320ee3b2ea8e5.tar.gz glib-d5a1e991c0c65ccab2b0cb9b8b9320ee3b2ea8e5.tar.bz2 glib-d5a1e991c0c65ccab2b0cb9b8b9320ee3b2ea8e5.zip |
Imported Upstream version 2.61.0
Diffstat (limited to 'gio')
76 files changed, 1285 insertions, 1312 deletions
diff --git a/gio/gappinfo.c b/gio/gappinfo.c index 84e667575..1fd0a7ad7 100644 --- a/gio/gappinfo.c +++ b/gio/gappinfo.c @@ -778,7 +778,7 @@ g_app_info_should_show (GAppInfo *appinfo) * * The D-Bus–activated applications don't have to be started if your application * terminates too soon after this function. To prevent this, use - * g_app_info_launch_default_for_uri() instead. + * g_app_info_launch_default_for_uri_async() instead. * * Returns: %TRUE on success, %FALSE on error. **/ diff --git a/gio/gapplication.c b/gio/gapplication.c index 321b34f54..2d2ab48e3 100644 --- a/gio/gapplication.c +++ b/gio/gapplication.c @@ -1372,9 +1372,6 @@ g_application_finalize (GObject *object) { GApplication *application = G_APPLICATION (object); - if (application->priv->inactivity_timeout_id) - g_source_remove (application->priv->inactivity_timeout_id); - g_slist_free_full (application->priv->option_groups, (GDestroyNotify) g_option_group_unref); if (application->priv->main_options) g_option_group_unref (application->priv->main_options); diff --git a/gio/gapplicationimpl-dbus.c b/gio/gapplicationimpl-dbus.c index 76d67eec8..fd9d0468d 100644 --- a/gio/gapplicationimpl-dbus.c +++ b/gio/gapplicationimpl-dbus.c @@ -774,7 +774,7 @@ g_application_impl_command_line (GApplicationImpl *impl, const gchar *object_path = "/org/gtk/Application/CommandLine"; GMainContext *context; CommandLineData data; - guint object_id; + guint object_id G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; context = g_main_context_new (); data.loop = g_main_loop_new (context, FALSE); diff --git a/gio/gcancellable.c b/gio/gcancellable.c index de6d43495..31e990f3c 100644 --- a/gio/gcancellable.c +++ b/gio/gcancellable.c @@ -43,7 +43,9 @@ enum { struct _GCancellablePrivate { - guint cancelled : 1; + /* Atomic so that g_cancellable_is_cancelled does not require holding the mutex. */ + gboolean cancelled; + /* Access to fields below is protected by cancellable_mutex. */ guint cancelled_running : 1; guint cancelled_running_waiting : 1; @@ -269,12 +271,12 @@ g_cancellable_reset (GCancellable *cancellable) g_cond_wait (&cancellable_cond, &cancellable_mutex); } - if (priv->cancelled) + if (g_atomic_int_get (&priv->cancelled)) { if (priv->wakeup) GLIB_PRIVATE_CALL (g_wakeup_acknowledge) (priv->wakeup); - priv->cancelled = FALSE; + g_atomic_int_set (&priv->cancelled, FALSE); } g_mutex_unlock (&cancellable_mutex); @@ -292,7 +294,7 @@ g_cancellable_reset (GCancellable *cancellable) gboolean g_cancellable_is_cancelled (GCancellable *cancellable) { - return cancellable != NULL && cancellable->priv->cancelled; + return cancellable != NULL && g_atomic_int_get (&cancellable->priv->cancelled); } /** @@ -404,7 +406,7 @@ g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd) { cancellable->priv->wakeup = GLIB_PRIVATE_CALL (g_wakeup_new) (); - if (cancellable->priv->cancelled) + if (g_atomic_int_get (&cancellable->priv->cancelled)) GLIB_PRIVATE_CALL (g_wakeup_signal) (cancellable->priv->wakeup); } @@ -440,11 +442,11 @@ g_cancellable_release_fd (GCancellable *cancellable) return; g_return_if_fail (G_IS_CANCELLABLE (cancellable)); - g_return_if_fail (cancellable->priv->fd_refcount > 0); priv = cancellable->priv; g_mutex_lock (&cancellable_mutex); + g_assert (priv->fd_refcount > 0); priv->fd_refcount--; if (priv->fd_refcount == 0) @@ -482,21 +484,20 @@ g_cancellable_cancel (GCancellable *cancellable) { GCancellablePrivate *priv; - if (cancellable == NULL || - cancellable->priv->cancelled) + if (cancellable == NULL || g_cancellable_is_cancelled (cancellable)) return; priv = cancellable->priv; g_mutex_lock (&cancellable_mutex); - if (priv->cancelled) + if (g_atomic_int_get (&priv->cancelled)) { g_mutex_unlock (&cancellable_mutex); return; } - priv->cancelled = TRUE; + g_atomic_int_set (&priv->cancelled, TRUE); priv->cancelled_running = TRUE; if (priv->wakeup) @@ -562,7 +563,7 @@ g_cancellable_connect (GCancellable *cancellable, g_mutex_lock (&cancellable_mutex); - if (cancellable->priv->cancelled) + if (g_atomic_int_get (&cancellable->priv->cancelled)) { void (*_callback) (GCancellable *cancellable, gpointer user_data); diff --git a/gio/gcocoanotificationbackend.m b/gio/gcocoanotificationbackend.m index fe9a7a552..9d632b4a5 100644 --- a/gio/gcocoanotificationbackend.m +++ b/gio/gcocoanotificationbackend.m @@ -44,7 +44,7 @@ GType g_cocoa_notification_backend_get_type (void); G_DEFINE_TYPE_WITH_CODE (GCocoaNotificationBackend, g_cocoa_notification_backend, G_TYPE_NOTIFICATION_BACKEND, _g_io_modules_ensure_extension_points_registered (); - g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, g_define_type_id, "cocoa", 0)); + g_io_extension_point_implement (G_NOTIFICATION_BACKEND_EXTENSION_POINT_NAME, g_define_type_id, "cocoa", 200)); static NSString * nsstring_from_cstr (const char *cstr) @@ -258,6 +258,7 @@ g_cocoa_notification_backend_withdraw_notification (GNotificationBackend *backen } } + [notifications release]; [str_id release]; } diff --git a/gio/gdatainputstream.c b/gio/gdatainputstream.c index c2b19fdc9..2e7750cb5 100644 --- a/gio/gdatainputstream.c +++ b/gio/gdatainputstream.c @@ -936,7 +936,7 @@ g_data_input_stream_read_until (GDataInputStream *stream, /* If we're not at end of stream then we have a stop_char to consume. */ if (result != NULL && g_buffered_input_stream_get_available (bstream) > 0) { - gsize res; + gsize res G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; gchar b; res = g_input_stream_read (G_INPUT_STREAM (stream), &b, 1, NULL, NULL); diff --git a/gio/gdbus-tool.c b/gio/gdbus-tool.c index 5fc4027b1..57978f1c2 100644 --- a/gio/gdbus-tool.c +++ b/gio/gdbus-tool.c @@ -31,10 +31,22 @@ #ifdef G_OS_WIN32 #include "glib/glib-private.h" +#include "gdbusprivate.h" #endif /* ---------------------------------------------------------------------------------------------------- */ +/* Escape values for console colors */ +#define UNDERLINE "\033[4m" +#define BLUE "\033[34m" +#define CYAN "\033[36m" +#define GREEN "\033[32m" +#define MAGENTA "\033[35m" +#define RED "\033[31m" +#define YELLOW "\033[33m" + +/* ---------------------------------------------------------------------------------------------------- */ + G_GNUC_UNUSED static void completion_debug (const gchar *format, ...); /* Uncomment to get debug traces in /tmp/gdbus-completion-debug.txt (nice @@ -1225,18 +1237,30 @@ static gboolean opt_introspect_xml = FALSE; static gboolean opt_introspect_recurse = FALSE; static gboolean opt_introspect_only_properties = FALSE; +/* Introspect colors */ +#define RESET_COLOR (use_colors? "\033[0m": "") +#define INTROSPECT_TITLE_COLOR (use_colors? UNDERLINE: "") +#define INTROSPECT_NODE_COLOR (use_colors? RESET_COLOR: "") +#define INTROSPECT_INTERFACE_COLOR (use_colors? YELLOW: "") +#define INTROSPECT_METHOD_COLOR (use_colors? BLUE: "") +#define INTROSPECT_SIGNAL_COLOR (use_colors? BLUE: "") +#define INTROSPECT_PROPERTY_COLOR (use_colors? MAGENTA: "") +#define INTROSPECT_INOUT_COLOR (use_colors? RESET_COLOR: "") +#define INTROSPECT_TYPE_COLOR (use_colors? GREEN: "") +#define INTROSPECT_ANNOTATION_COLOR (use_colors? RESET_COLOR: "") + static void dump_annotation (const GDBusAnnotationInfo *o, guint indent, - gboolean ignore_indent) + gboolean ignore_indent, + gboolean use_colors) { guint n; - g_print ("%*s@%s(\"%s\")\n", + g_print ("%*s%s@%s(\"%s\")%s\n", ignore_indent ? 0 : indent, "", - o->key, - o->value); + INTROSPECT_ANNOTATION_COLOR, o->key, o->value, RESET_COLOR); for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) - dump_annotation (o->annotations[n], indent + 2, FALSE); + dump_annotation (o->annotations[n], indent + 2, FALSE, use_colors); } static void @@ -1244,20 +1268,21 @@ dump_arg (const GDBusArgInfo *o, guint indent, const gchar *direction, gboolean ignore_indent, - gboolean include_newline) + gboolean include_newline, + gboolean use_colors) { guint n; for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) { - dump_annotation (o->annotations[n], indent, ignore_indent); + dump_annotation (o->annotations[n], indent, ignore_indent, use_colors); ignore_indent = FALSE; } - g_print ("%*s%s%s %s%s", + g_print ("%*s%s%s%s%s%s%s %s%s", ignore_indent ? 0 : indent, "", - direction, - o->signature, + INTROSPECT_INOUT_COLOR, direction, RESET_COLOR, + INTROSPECT_TYPE_COLOR, o->signature, RESET_COLOR, o->name, include_newline ? ",\n" : ""); } @@ -1277,7 +1302,8 @@ count_args (GDBusArgInfo **args) static void dump_method (const GDBusMethodInfo *o, - guint indent) + guint indent, + gboolean use_colors) { guint n; guint m; @@ -1285,9 +1311,11 @@ dump_method (const GDBusMethodInfo *o, guint total_num_args; for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) - dump_annotation (o->annotations[n], indent, FALSE); + dump_annotation (o->annotations[n], indent, FALSE, use_colors); - g_print ("%*s%s(", indent, "", o->name); + g_print ("%*s%s%s%s(", + indent, "", + INTROSPECT_METHOD_COLOR, o->name, RESET_COLOR); name_len = strlen (o->name); total_num_args = count_args (o->in_args) + count_args (o->out_args); for (n = 0, m = 0; o->in_args != NULL && o->in_args[n] != NULL; n++, m++) @@ -1299,7 +1327,8 @@ dump_method (const GDBusMethodInfo *o, indent + name_len + 1, "in ", ignore_indent, - include_newline); + include_newline, + use_colors); } for (n = 0; o->out_args != NULL && o->out_args[n] != NULL; n++, m++) { @@ -1309,23 +1338,27 @@ dump_method (const GDBusMethodInfo *o, indent + name_len + 1, "out ", ignore_indent, - include_newline); + include_newline, + use_colors); } g_print (");\n"); } static void dump_signal (const GDBusSignalInfo *o, - guint indent) + guint indent, + gboolean use_colors) { guint n; guint name_len; guint total_num_args; for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) - dump_annotation (o->annotations[n], indent, FALSE); + dump_annotation (o->annotations[n], indent, FALSE, use_colors); - g_print ("%*s%s(", indent, "", o->name); + g_print ("%*s%s%s%s(", + indent, "", + INTROSPECT_SIGNAL_COLOR, o->name, RESET_COLOR); name_len = strlen (o->name); total_num_args = count_args (o->args); for (n = 0; o->args != NULL && o->args[n] != NULL; n++) @@ -1336,7 +1369,8 @@ dump_signal (const GDBusSignalInfo *o, indent + name_len + 1, "", ignore_indent, - include_newline); + include_newline, + use_colors); } g_print (");\n"); } @@ -1344,6 +1378,7 @@ dump_signal (const GDBusSignalInfo *o, static void dump_property (const GDBusPropertyInfo *o, guint indent, + gboolean use_colors, GVariant *value) { const gchar *access; @@ -1359,12 +1394,15 @@ dump_property (const GDBusPropertyInfo *o, g_assert_not_reached (); for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) - dump_annotation (o->annotations[n], indent, FALSE); + dump_annotation (o->annotations[n], indent, FALSE, use_colors); if (value != NULL) { gchar *s = g_variant_print (value, FALSE); - g_print ("%*s%s %s %s = %s;\n", indent, "", access, o->signature, o->name, s); + g_print ("%*s%s %s%s%s %s%s%s = %s;\n", indent, "", access, + INTROSPECT_TYPE_COLOR, o->signature, RESET_COLOR, + INTROSPECT_PROPERTY_COLOR, o->name, RESET_COLOR, + s); g_free (s); } else @@ -1378,6 +1416,7 @@ dump_interface (GDBusConnection *c, const gchar *name, const GDBusInterfaceInfo *o, guint indent, + gboolean use_colors, const gchar *object_path) { guint n; @@ -1458,28 +1497,37 @@ dump_interface (GDBusConnection *c, } for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) - dump_annotation (o->annotations[n], indent, FALSE); + dump_annotation (o->annotations[n], indent, FALSE, use_colors); - g_print ("%*sinterface %s {\n", indent, "", o->name); + g_print ("%*s%sinterface %s%s {\n", + indent, "", + INTROSPECT_INTERFACE_COLOR, o->name, RESET_COLOR); if (o->methods != NULL && !opt_introspect_only_properties) { - g_print ("%*s methods:\n", indent, ""); + g_print ("%*s %smethods%s:\n", + indent, "", + INTROSPECT_TITLE_COLOR, RESET_COLOR); for (n = 0; o->methods[n] != NULL; n++) - dump_method (o->methods[n], indent + 4); + dump_method (o->methods[n], indent + 4, use_colors); } if (o->signals != NULL && !opt_introspect_only_properties) { - g_print ("%*s signals:\n", indent, ""); + g_print ("%*s %ssignals%s:\n", + indent, "", + INTROSPECT_TITLE_COLOR, RESET_COLOR); for (n = 0; o->signals[n] != NULL; n++) - dump_signal (o->signals[n], indent + 4); + dump_signal (o->signals[n], indent + 4, use_colors); } if (o->properties != NULL) { - g_print ("%*s properties:\n", indent, ""); + g_print ("%*s %sproperties%s:\n", + indent, "", + INTROSPECT_TITLE_COLOR, RESET_COLOR); for (n = 0; o->properties[n] != NULL; n++) { dump_property (o->properties[n], indent + 4, + use_colors, g_hash_table_lookup (properties, (o->properties[n])->name)); } } @@ -1492,13 +1540,15 @@ dump_interface (GDBusConnection *c, static gboolean introspect_do (GDBusConnection *c, const gchar *object_path, - guint indent); + guint indent, + gboolean use_colors); static void dump_node (GDBusConnection *c, const gchar *name, const GDBusNodeInfo *o, guint indent, + gboolean use_colors, const gchar *object_path, gboolean recurse) { @@ -1510,9 +1560,13 @@ dump_node (GDBusConnection *c, object_path_to_print = o->path; for (n = 0; o->annotations != NULL && o->annotations[n] != NULL; n++) - dump_annotation (o->annotations[n], indent, FALSE); + dump_annotation (o->annotations[n], indent, FALSE, use_colors); - g_print ("%*snode %s", indent, "", object_path_to_print != NULL ? object_path_to_print : "(not set)"); + g_print ("%*s%snode %s%s", + indent, "", + INTROSPECT_NODE_COLOR, + object_path_to_print != NULL ? object_path_to_print : "(not set)", + RESET_COLOR); if (o->interfaces != NULL || o->nodes != NULL) { g_print (" {\n"); @@ -1521,11 +1575,11 @@ dump_node (GDBusConnection *c, if (opt_introspect_only_properties) { if (o->interfaces[n]->properties != NULL && o->interfaces[n]->properties[0] != NULL) - dump_interface (c, name, o->interfaces[n], indent + 2, object_path); + dump_interface (c, name, o->interfaces[n], indent + 2, use_colors, object_path); } else { - dump_interface (c, name, o->interfaces[n], indent + 2, object_path); + dump_interface (c, name, o->interfaces[n], indent + 2, use_colors, object_path); } } for (n = 0; o->nodes != NULL && o->nodes[n] != NULL; n++) @@ -1539,7 +1593,7 @@ dump_node (GDBusConnection *c, /* avoid infinite loops */ if (g_str_has_prefix (child_path, object_path)) { - introspect_do (c, child_path, indent + 2); + introspect_do (c, child_path, indent + 2, use_colors); } else { @@ -1553,13 +1607,13 @@ dump_node (GDBusConnection *c, child_path = g_strdup_printf ("/%s", o->nodes[n]->path); else child_path = g_strdup_printf ("%s/%s", object_path, o->nodes[n]->path); - introspect_do (c, child_path, indent + 2); + introspect_do (c, child_path, indent + 2, use_colors); } g_free (child_path); } else { - dump_node (NULL, NULL, o->nodes[n], indent + 2, NULL, recurse); + dump_node (NULL, NULL, o->nodes[n], indent + 2, use_colors, NULL, recurse); } } g_print ("%*s};\n", @@ -1584,7 +1638,8 @@ static const GOptionEntry introspect_entries[] = static gboolean introspect_do (GDBusConnection *c, const gchar *object_path, - guint indent) + guint indent, + gboolean use_colors) { GError *error; GVariant *result; @@ -1631,7 +1686,7 @@ introspect_do (GDBusConnection *c, goto out; } - dump_node (c, opt_introspect_dest, node, indent, object_path, opt_introspect_recurse); + dump_node (c, opt_introspect_dest, node, indent, use_colors, object_path, opt_introspect_recurse); } ret = TRUE; @@ -1658,6 +1713,7 @@ handle_introspect (gint *argc, GDBusConnection *c; gboolean complete_names; gboolean complete_paths; + gboolean color_support; ret = FALSE; c = NULL; @@ -1793,7 +1849,10 @@ handle_introspect (gint *argc, if (request_completion) goto out; - if (!introspect_do (c, opt_introspect_object_path, 0)) + /* Before we start printing the actual info, check if we can do colors*/ + color_support = g_log_writer_supports_color (fileno (stdout)); + + if (!introspect_do (c, opt_introspect_object_path, 0, color_support)) goto out; ret = TRUE; @@ -2421,6 +2480,14 @@ main (gint argc, gchar *argv[]) ret = 0; goto out; } +#ifdef G_OS_WIN32 + else if (g_strcmp0 (command, _GDBUS_ARG_WIN32_RUN_SESSION_BUS) == 0) + { + g_win32_run_session_bus (NULL, NULL, NULL, 0); + ret = 0; + goto out; + } +#endif else if (g_strcmp0 (command, "complete") == 0 && argc == 4 && !request_completion) { const gchar *completion_line; diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c index 8b3c858ba..1f7d19396 100644 --- a/gio/gdbusaddress.c +++ b/gio/gdbusaddress.c @@ -37,8 +37,6 @@ #include "gtask.h" #include "glib-private.h" #include "gdbusprivate.h" -#include "giomodule-priv.h" -#include "gdbusdaemon.h" #include "gstdio.h" #ifdef G_OS_UNIX @@ -50,8 +48,6 @@ #ifdef G_OS_WIN32 #include <windows.h> -#include <io.h> -#include <conio.h> #endif #include "glibintl.h" @@ -162,22 +158,18 @@ is_valid_unix (const gchar *address_entry, } } - if (path != NULL) + if ((path != NULL && tmpdir != NULL) || + (tmpdir != NULL && abstract != NULL) || + (abstract != NULL && path != NULL)) { - if (tmpdir != NULL || abstract != NULL) - goto meaningless; - } - else if (tmpdir != NULL) - { - if (path != NULL || abstract != NULL) - goto meaningless; - } - else if (abstract != NULL) - { - if (path != NULL || tmpdir != NULL) - goto meaningless; + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Meaningless key/value pair combination in address entry “%s”"), + address_entry); + goto out; } - else + else if (path == NULL && tmpdir == NULL && abstract == NULL) { g_set_error (error, G_IO_ERROR, @@ -187,16 +179,7 @@ is_valid_unix (const gchar *address_entry, goto out; } - - ret= TRUE; - goto out; - - meaningless: - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_INVALID_ARGUMENT, - _("Meaningless key/value pair combination in address entry “%s”"), - address_entry); + ret = TRUE; out: g_list_free (keys); @@ -468,12 +451,21 @@ _g_dbus_address_parse_entry (const gchar *address_entry, address_entry); goto out; } + else if (s == address_entry) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Transport name in address element “%s” must not be empty"), + address_entry); + goto out; + } transport_name = g_strndup (address_entry, s - address_entry); key_value_pairs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); kv_pairs = g_strsplit (s + 1, ",", 0); - for (n = 0; kv_pairs != NULL && kv_pairs[n] != NULL; n++) + for (n = 0; kv_pairs[n] != NULL; n++) { const gchar *kv_pair = kv_pairs[n]; gchar *key; @@ -491,6 +483,17 @@ _g_dbus_address_parse_entry (const gchar *address_entry, address_entry); goto out; } + else if (s == kv_pair) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Key/Value pair %d, “%s”, in address element “%s” must not have an empty key"), + n, + kv_pair, + address_entry); + goto out; + } key = g_uri_unescape_segment (kv_pair, s, NULL); value = g_uri_unescape_segment (s + 1, kv_pair + strlen (kv_pair), NULL); @@ -513,24 +516,18 @@ _g_dbus_address_parse_entry (const gchar *address_entry, ret = TRUE; out: - g_strfreev (kv_pairs); if (ret) { if (out_transport_name != NULL) - *out_transport_name = transport_name; - else - g_free (transport_name); + *out_transport_name = g_steal_pointer (&transport_name); if (out_key_value_pairs != NULL) - *out_key_value_pairs = key_value_pairs; - else if (key_value_pairs != NULL) - g_hash_table_unref (key_value_pairs); - } - else - { - g_free (transport_name); - if (key_value_pairs != NULL) - g_hash_table_unref (key_value_pairs); + *out_key_value_pairs = g_steal_pointer (&key_value_pairs); } + + g_clear_pointer (&key_value_pairs, g_hash_table_unref); + g_free (transport_name); + g_strfreev (kv_pairs); + return ret; } @@ -966,7 +963,7 @@ g_dbus_address_get_stream_sync (const gchar *address, last_error = NULL; addr_array = g_strsplit (address, ";", 0); - if (addr_array != NULL && addr_array[0] == NULL) + if (addr_array[0] == NULL) { last_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, @@ -1195,367 +1192,12 @@ get_session_address_dbus_launch (GError **error) /* end of G_OS_UNIX case */ #elif defined(G_OS_WIN32) -#define DBUS_DAEMON_ADDRESS_INFO "DBusDaemonAddressInfo" -#define DBUS_DAEMON_MUTEX "DBusDaemonMutex" -#define UNIQUE_DBUS_INIT_MUTEX "UniqueDBusInitMutex" -#define DBUS_AUTOLAUNCH_MUTEX "DBusAutolaunchMutex" - -static void -release_mutex (HANDLE mutex) -{ - ReleaseMutex (mutex); - CloseHandle (mutex); -} - -static HANDLE -acquire_mutex (const char *mutexname) -{ - HANDLE mutex; - DWORD res; - - mutex = CreateMutexA (NULL, FALSE, mutexname); - if (!mutex) - return 0; - - res = WaitForSingleObject (mutex, INFINITE); - switch (res) - { - case WAIT_ABANDONED: - release_mutex (mutex); - return 0; - case WAIT_FAILED: - case WAIT_TIMEOUT: - return 0; - } - - return mutex; -} - -static gboolean -is_mutex_owned (const char *mutexname) -{ - HANDLE mutex; - gboolean res = FALSE; - - mutex = CreateMutexA (NULL, FALSE, mutexname); - if (WaitForSingleObject (mutex, 10) == WAIT_TIMEOUT) - res = TRUE; - else - ReleaseMutex (mutex); - CloseHandle (mutex); - - return res; -} - -static char * -read_shm (const char *shm_name) -{ - HANDLE shared_mem; - char *shared_data; - char *res; - int i; - - res = NULL; - - for (i = 0; i < 20; i++) - { - shared_mem = OpenFileMappingA (FILE_MAP_READ, FALSE, shm_name); - if (shared_mem != 0) - break; - Sleep (100); - } - - if (shared_mem != 0) - { - shared_data = MapViewOfFile (shared_mem, FILE_MAP_READ, 0, 0, 0); - /* It looks that a race is possible here: - * if the dbus process already created mapping but didn't fill it - * the code below may read incorrect address. - * Also this is a bit complicated by the fact that - * any change in the "synchronization contract" between processes - * should be accompanied with renaming all of used win32 named objects: - * otherwise libgio-2.0-0.dll of different versions shipped with - * different apps may break each other due to protocol difference. - */ - if (shared_data != NULL) - { - res = g_strdup (shared_data); - UnmapViewOfFile (shared_data); - } - CloseHandle (shared_mem); - } - - return res; -} - -static HANDLE -set_shm (const char *shm_name, const char *value) -{ - HANDLE shared_mem; - char *shared_data; - - shared_mem = CreateFileMappingA (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, - 0, strlen (value) + 1, shm_name); - if (shared_mem == 0) - return 0; - - shared_data = MapViewOfFile (shared_mem, FILE_MAP_WRITE, 0, 0, 0 ); - if (shared_data == NULL) - return 0; - - strcpy (shared_data, value); - - UnmapViewOfFile (shared_data); - - return shared_mem; -} - -/* These keep state between publish_session_bus and unpublish_session_bus */ -static HANDLE published_daemon_mutex; -static HANDLE published_shared_mem; - -static gboolean -publish_session_bus (const char *address) -{ - HANDLE init_mutex; - - init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); - - published_daemon_mutex = CreateMutexA (NULL, FALSE, DBUS_DAEMON_MUTEX); - if (WaitForSingleObject (published_daemon_mutex, 10 ) != WAIT_OBJECT_0) - { - release_mutex (init_mutex); - CloseHandle (published_daemon_mutex); - published_daemon_mutex = NULL; - return FALSE; - } - - published_shared_mem = set_shm (DBUS_DAEMON_ADDRESS_INFO, address); - if (!published_shared_mem) - { - release_mutex (init_mutex); - CloseHandle (published_daemon_mutex); - published_daemon_mutex = NULL; - return FALSE; - } - - release_mutex (init_mutex); - return TRUE; -} - -static void -unpublish_session_bus (void) -{ - HANDLE init_mutex; - - init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); - - CloseHandle (published_shared_mem); - published_shared_mem = NULL; - - release_mutex (published_daemon_mutex); - published_daemon_mutex = NULL; - - release_mutex (init_mutex); -} - -static void -wait_console_window (void) -{ - FILE *console = fopen ("CONOUT$", "w"); - - SetConsoleTitleW (L"gdbus-daemon output. Type any character to close this window."); - fprintf (console, _("(Type any character to close this window)\n")); - fflush (console); - _getch (); -} - -static void -open_console_window (void) -{ - if (((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE || - (HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) && AllocConsole ()) - { - if ((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE) - freopen ("CONOUT$", "w", stdout); - - if ((HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) - freopen ("CONOUT$", "w", stderr); - - SetConsoleTitleW (L"gdbus-daemon debug output."); - - atexit (wait_console_window); - } -} - -static void -idle_timeout_cb (GDBusDaemon *daemon, gpointer user_data) -{ - GMainLoop *loop = user_data; - g_main_loop_quit (loop); -} - -/* Satisfies STARTF_FORCEONFEEDBACK */ -static void -turn_off_the_starting_cursor (void) -{ - MSG msg; - BOOL bRet; - - PostQuitMessage (0); - - while ((bRet = GetMessage (&msg, 0, 0, 0)) != 0) - { - if (bRet == -1) - continue; - - TranslateMessage (&msg); - DispatchMessage (&msg); - } -} - -__declspec(dllexport) void CALLBACK g_win32_run_session_bus (HWND hwnd, HINSTANCE hinst, char *cmdline, int nCmdShow); - -__declspec(dllexport) void CALLBACK -g_win32_run_session_bus (HWND hwnd, HINSTANCE hinst, char *cmdline, int nCmdShow) -{ - GDBusDaemon *daemon; - GMainLoop *loop; - const char *address; - GError *error = NULL; - - turn_off_the_starting_cursor (); - - if (g_getenv ("GDBUS_DAEMON_DEBUG") != NULL) - open_console_window (); - - loop = g_main_loop_new (NULL, FALSE); - - address = "nonce-tcp:"; - daemon = _g_dbus_daemon_new (address, NULL, &error); - if (daemon == NULL) - { - g_printerr ("Can't init bus: %s\n", error->message); - g_error_free (error); - return; - } - - /* There is a subtle detail with "idle-timeout" signal of dbus daemon: - * It is fired on idle after last client disconnection, - * but (at least with glib 2.59.1) it is NEVER fired - * if no clients connect to daemon at all. - * This may lead to infinite run of this daemon process. - */ - g_signal_connect (daemon, "idle-timeout", G_CALLBACK (idle_timeout_cb), loop); - - if (publish_session_bus (_g_dbus_daemon_get_address (daemon))) - { - g_main_loop_run (loop); - - unpublish_session_bus (); - } - - g_main_loop_unref (loop); - g_object_unref (daemon); -} - static gchar * get_session_address_dbus_launch (GError **error) { - HANDLE autolaunch_mutex, init_mutex; - char *address = NULL; - - autolaunch_mutex = acquire_mutex (DBUS_AUTOLAUNCH_MUTEX); - - init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); - - if (is_mutex_owned (DBUS_DAEMON_MUTEX)) - address = read_shm (DBUS_DAEMON_ADDRESS_INFO); - - release_mutex (init_mutex); - - if (address == NULL) - { - /* rundll32 doesn't support neither spaces, nor quotes in cmdline: - * https://support.microsoft.com/en-us/help/164787/info-windows-rundll-and-rundll32-interface - * Since the dll path may have spaces, it is used as working directory, - * and the plain dll name is passed as argument to rundll32 like - * "C:\Windows\System32\rundll32.exe" .\libgio-2.0-0.dll,g_win32_run_session_bus - * - * Using relative path to dll rises a question if correct dll is loaded. - * According to docs if relative path like .\libgio-2.0-0.dll is passed - * the System32 directory may be searched before current directory: - * https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-search-order#standard-search-order-for-desktop-applications - * Internally rundll32 uses "undefined behavior" parameter combination - * LoadLibraryExW(".\libgio-2.0-0.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH) - * Actual testing shows that if relative name starts from ".\" - * the current directory is searched before System32 (win7, win10 1607). - * So wrong dll would be loaded only if the BOTH of the following holds: - * - rundll32 will change so it would prefer system32 even for .\ paths - * - some app would place libgio-2.0-0.dll in system32 directory - * - * In point of that using .\libgio-2.0-0.dll looks fine. - */ - wchar_t gio_path[MAX_PATH + 2] = { 0 }; - int gio_path_len = GetModuleFileNameW (_g_io_win32_get_module (), gio_path, MAX_PATH + 1); - - /* The <= MAX_PATH check prevents truncated path usage */ - if (gio_path_len > 0 && gio_path_len <= MAX_PATH) - { - PROCESS_INFORMATION pi = { 0 }; - STARTUPINFOW si = { 0 }; - BOOL res = FALSE; - wchar_t rundll_path[MAX_PATH + 100] = { 0 }; - wchar_t args[MAX_PATH*2 + 100] = { 0 }; - /* calculate index of first char of dll file name inside full path */ - int gio_name_index = gio_path_len; - for (; gio_name_index > 0; --gio_name_index) - { - wchar_t prev_char = gio_path[gio_name_index - 1]; - if (prev_char == L'\\' || prev_char == L'/') - break; - } - GetWindowsDirectoryW (rundll_path, MAX_PATH); - wcscat (rundll_path, L"\\rundll32.exe"); - if (GetFileAttributesW (rundll_path) == INVALID_FILE_ATTRIBUTES) - { - GetSystemDirectoryW (rundll_path, MAX_PATH); - wcscat (rundll_path, L"\\rundll32.exe"); - } - - wcscpy (args, L"\""); - wcscat (args, rundll_path); - wcscat (args, L"\" .\\"); - wcscat (args, gio_path + gio_name_index); -#if defined(_WIN64) || defined(_M_X64) || defined(_M_AMD64) - wcscat (args, L",g_win32_run_session_bus"); -#elif defined (_MSC_VER) - wcscat (args, L",_g_win32_run_session_bus@16"); -#else - wcscat (args, L",g_win32_run_session_bus@16"); -#endif - - gio_path[gio_name_index] = L'\0'; - res = CreateProcessW (rundll_path, args, - 0, 0, FALSE, - NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS, - 0, gio_path, - &si, &pi); - if (res) - address = read_shm (DBUS_DAEMON_ADDRESS_INFO); - } - } - - release_mutex (autolaunch_mutex); - - if (address == NULL) - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_FAILED, - _("Session dbus not running, and autolaunch failed")); - - return address; + return _g_dbus_win32_get_session_address_dbus_launch (error); } + #else /* neither G_OS_UNIX nor G_OS_WIN32 */ static gchar * get_session_address_dbus_launch (GError **error) diff --git a/gio/gdbusauthobserver.c b/gio/gdbusauthobserver.c index 4590ffcae..34758aa20 100644 --- a/gio/gdbusauthobserver.c +++ b/gio/gdbusauthobserver.c @@ -39,37 +39,11 @@ * signals you are interested in. Note that new signals may be added * in the future * - * ## Controlling Authentication Mechanisms + * ## Controlling Authentication # {#auth-observer} * - * By default, a #GDBusServer or server-side #GDBusConnection will allow - * any authentication mechanism to be used. If you only - * want to allow D-Bus connections with the `EXTERNAL` mechanism, - * which makes use of credentials passing and is the recommended - * mechanism for modern Unix platforms such as Linux and the BSD family, - * you would use a signal handler like this: - * - * |[<!-- language="C" --> - * static gboolean - * on_allow_mechanism (GDBusAuthObserver *observer, - * const gchar *mechanism, - * gpointer user_data) - * { - * if (g_strcmp0 (mechanism, "EXTERNAL") == 0) - * { - * return TRUE; - * } - * - * return FALSE; - * } - * ]| - * - * ## Controlling Authorization # {#auth-observer} - * - * By default, a #GDBusServer or server-side #GDBusConnection will accept - * connections from any successfully authenticated user (but not from - * anonymous connections using the `ANONYMOUS` mechanism). If you only - * want to allow D-Bus connections from processes owned by the same uid - * as the server, you would use a signal handler like the following: + * For example, if you only want to allow D-Bus connections from + * processes owned by the same uid as the server, you would use a + * signal handler like the following: * * |[<!-- language="C" --> * static gboolean diff --git a/gio/gdbusdaemon.c b/gio/gdbusdaemon.c index d893b930a..a9b626215 100644 --- a/gio/gdbusdaemon.c +++ b/gio/gdbusdaemon.c @@ -1493,16 +1493,21 @@ filter_function (GDBusConnection *connection, } else { + if (g_dbus_message_get_sender (message) == NULL || + g_dbus_message_get_destination (message) == NULL) + { + message = copy_if_locked (message); + if (message == NULL) + { + g_warning ("Failed to copy outgoing message"); + return NULL; + } + } + if (g_dbus_message_get_sender (message) == NULL) - { - message = copy_if_locked (message); - g_dbus_message_set_sender (message, DBUS_SERVICE_NAME); - } + g_dbus_message_set_sender (message, DBUS_SERVICE_NAME); if (g_dbus_message_get_destination (message) == NULL) - { - message = copy_if_locked (message); - g_dbus_message_set_destination (message, client->id); - } + g_dbus_message_set_destination (message, client->id); } return message; @@ -1534,7 +1539,7 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer, GCredentials *credentials, gpointer user_data) { - gboolean authorized = FALSE; + gboolean authorized = TRUE; if (credentials != NULL) { @@ -1544,14 +1549,6 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer, authorized = g_credentials_is_same_user (credentials, own_credentials, NULL); g_object_unref (own_credentials); } -#ifdef G_OS_WIN32 - else - { - /* We allow ANONYMOUS authentication on Windows for now, in - * combination with the nonce-tcp transport. */ - authorized = TRUE; - } -#endif return authorized; } diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c index 3a1a1f9e9..9b89dc5b6 100644 --- a/gio/gdbusmessage.c +++ b/gio/gdbusmessage.c @@ -1714,7 +1714,7 @@ parse_value_from_blob (GMemoryBuffer *buf, if (array_len == 0) { - GVariant *item; + GVariant *item G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; item = parse_value_from_blob (buf, element_type, TRUE, @@ -2345,7 +2345,10 @@ append_value_to_blob (GVariant *value, { gsize len; const gchar *v; +#ifndef G_DISABLE_ASSERT const gchar *end; +#endif + v = g_variant_get_string (value, &len); g_assert (g_utf8_validate (v, -1, &end) && (end == v + len)); g_memory_buffer_put_uint32 (mbuf, len); diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c index 1e8e1d64b..488fe50c4 100644 --- a/gio/gdbusprivate.c +++ b/gio/gdbusprivate.c @@ -33,6 +33,8 @@ #include "gdbusproxy.h" #include "gdbuserror.h" #include "gdbusintrospection.h" +#include "gdbusdaemon.h" +#include "giomodule-priv.h" #include "gtask.h" #include "ginputstream.h" #include "gmemoryinputstream.h" @@ -51,6 +53,8 @@ #ifdef G_OS_WIN32 #include <windows.h> +#include <io.h> +#include <conio.h> #endif #include "glibintl.h" @@ -488,9 +492,9 @@ _g_dbus_worker_emit_message_about_to_be_sent (GDBusWorker *worker, { GDBusMessage *ret; if (!g_atomic_int_get (&worker->stopped)) - ret = worker->message_about_to_be_sent_callback (worker, message, worker->user_data); + ret = worker->message_about_to_be_sent_callback (worker, g_steal_pointer (&message), worker->user_data); else - ret = message; + ret = g_steal_pointer (&message); return ret; } @@ -502,13 +506,13 @@ _g_dbus_worker_queue_or_deliver_received_message (GDBusWorker *worker, if (worker->frozen || g_queue_get_length (worker->received_messages_while_frozen) > 0) { /* queue up */ - g_queue_push_tail (worker->received_messages_while_frozen, message); + g_queue_push_tail (worker->received_messages_while_frozen, g_steal_pointer (&message)); } else { /* not frozen, nor anything in queue */ _g_dbus_worker_emit_message_received (worker, message); - g_object_unref (message); + g_clear_object (&message); } } @@ -525,7 +529,7 @@ unfreeze_in_idle_cb (gpointer user_data) while ((message = g_queue_pop_head (worker->received_messages_while_frozen)) != NULL) { _g_dbus_worker_emit_message_received (worker, message); - g_object_unref (message); + g_clear_object (&message); } worker->frozen = FALSE; } @@ -792,7 +796,7 @@ _g_dbus_worker_do_read_cb (GInputStream *input_stream, } /* yay, got a message, go deliver it */ - _g_dbus_worker_queue_or_deliver_received_message (worker, message); + _g_dbus_worker_queue_or_deliver_received_message (worker, g_steal_pointer (&message)); /* start reading another message! */ worker->read_buffer_bytes_wanted = 0; @@ -1190,13 +1194,6 @@ ostream_flush_cb (GObject *source_object, } } - g_assert (data->flushers != NULL); - flush_data_list_complete (data->flushers, error); - g_list_free (data->flushers); - - if (error != NULL) - g_error_free (error); - /* Make sure we tell folks that we don't have additional flushes pending */ g_mutex_lock (&data->worker->write_lock); @@ -1205,6 +1202,12 @@ ostream_flush_cb (GObject *source_object, data->worker->output_pending = PENDING_NONE; g_mutex_unlock (&data->worker->write_lock); + g_assert (data->flushers != NULL); + flush_data_list_complete (data->flushers, error); + g_list_free (data->flushers); + if (error != NULL) + g_error_free (error); + /* OK, cool, finally kick off the next write */ continue_writing (data->worker); @@ -1373,6 +1376,10 @@ iostream_close_cb (GObject *source_object, g_assert (worker->output_pending == PENDING_CLOSE); worker->output_pending = PENDING_NONE; + /* Ensure threads waiting for pending flushes to finish will be unblocked. */ + worker->write_num_messages_flushed = + worker->write_num_messages_written + g_list_length(pending_flush_attempts); + g_mutex_unlock (&worker->write_lock); while (pending_close_attempts != NULL) @@ -1788,10 +1795,17 @@ _g_dbus_worker_flush_sync (GDBusWorker *worker, if (data != NULL) { - g_cond_wait (&data->cond, &data->mutex); - g_mutex_unlock (&data->mutex); + /* Wait for flush operations to finish. */ + g_mutex_lock (&worker->write_lock); + while (worker->write_num_messages_flushed < data->number_to_wait_for) + { + g_mutex_unlock (&worker->write_lock); + g_cond_wait (&data->cond, &data->mutex); + g_mutex_lock (&worker->write_lock); + } + g_mutex_unlock (&worker->write_lock); - /* note:the element is removed from worker->write_pending_flushes in flush_cb() above */ + g_mutex_unlock (&data->mutex); g_cond_clear (&data->cond); g_mutex_clear (&data->mutex); if (data->error != NULL) @@ -2054,6 +2068,357 @@ out: CloseHandle (h); return ret; } + + +#define DBUS_DAEMON_ADDRESS_INFO "DBusDaemonAddressInfo" +#define DBUS_DAEMON_MUTEX "DBusDaemonMutex" +#define UNIQUE_DBUS_INIT_MUTEX "UniqueDBusInitMutex" +#define DBUS_AUTOLAUNCH_MUTEX "DBusAutolaunchMutex" + +static void +release_mutex (HANDLE mutex) +{ + ReleaseMutex (mutex); + CloseHandle (mutex); +} + +static HANDLE +acquire_mutex (const char *mutexname) +{ + HANDLE mutex; + DWORD res; + + mutex = CreateMutexA (NULL, FALSE, mutexname); + if (!mutex) + return 0; + + res = WaitForSingleObject (mutex, INFINITE); + switch (res) + { + case WAIT_ABANDONED: + release_mutex (mutex); + return 0; + case WAIT_FAILED: + case WAIT_TIMEOUT: + return 0; + } + + return mutex; +} + +static gboolean +is_mutex_owned (const char *mutexname) +{ + HANDLE mutex; + gboolean res = FALSE; + + mutex = CreateMutexA (NULL, FALSE, mutexname); + if (WaitForSingleObject (mutex, 10) == WAIT_TIMEOUT) + res = TRUE; + else + ReleaseMutex (mutex); + CloseHandle (mutex); + + return res; +} + +static char * +read_shm (const char *shm_name) +{ + HANDLE shared_mem; + char *shared_data; + char *res; + int i; + + res = NULL; + + for (i = 0; i < 20; i++) + { + shared_mem = OpenFileMappingA (FILE_MAP_READ, FALSE, shm_name); + if (shared_mem != 0) + break; + Sleep (100); + } + + if (shared_mem != 0) + { + shared_data = MapViewOfFile (shared_mem, FILE_MAP_READ, 0, 0, 0); + /* It looks that a race is possible here: + * if the dbus process already created mapping but didn't fill it + * the code below may read incorrect address. + * Also this is a bit complicated by the fact that + * any change in the "synchronization contract" between processes + * should be accompanied with renaming all of used win32 named objects: + * otherwise libgio-2.0-0.dll of different versions shipped with + * different apps may break each other due to protocol difference. + */ + if (shared_data != NULL) + { + res = g_strdup (shared_data); + UnmapViewOfFile (shared_data); + } + CloseHandle (shared_mem); + } + + return res; +} + +static HANDLE +set_shm (const char *shm_name, const char *value) +{ + HANDLE shared_mem; + char *shared_data; + + shared_mem = CreateFileMappingA (INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, strlen (value) + 1, shm_name); + if (shared_mem == 0) + return 0; + + shared_data = MapViewOfFile (shared_mem, FILE_MAP_WRITE, 0, 0, 0 ); + if (shared_data == NULL) + return 0; + + strcpy (shared_data, value); + + UnmapViewOfFile (shared_data); + + return shared_mem; +} + +/* These keep state between publish_session_bus and unpublish_session_bus */ +static HANDLE published_daemon_mutex; +static HANDLE published_shared_mem; + +static gboolean +publish_session_bus (const char *address) +{ + HANDLE init_mutex; + + init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); + + published_daemon_mutex = CreateMutexA (NULL, FALSE, DBUS_DAEMON_MUTEX); + if (WaitForSingleObject (published_daemon_mutex, 10 ) != WAIT_OBJECT_0) + { + release_mutex (init_mutex); + CloseHandle (published_daemon_mutex); + published_daemon_mutex = NULL; + return FALSE; + } + + published_shared_mem = set_shm (DBUS_DAEMON_ADDRESS_INFO, address); + if (!published_shared_mem) + { + release_mutex (init_mutex); + CloseHandle (published_daemon_mutex); + published_daemon_mutex = NULL; + return FALSE; + } + + release_mutex (init_mutex); + return TRUE; +} + +static void +unpublish_session_bus (void) +{ + HANDLE init_mutex; + + init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); + + CloseHandle (published_shared_mem); + published_shared_mem = NULL; + + release_mutex (published_daemon_mutex); + published_daemon_mutex = NULL; + + release_mutex (init_mutex); +} + +static void +wait_console_window (void) +{ + FILE *console = fopen ("CONOUT$", "w"); + + SetConsoleTitleW (L"gdbus-daemon output. Type any character to close this window."); + fprintf (console, _("(Type any character to close this window)\n")); + fflush (console); + _getch (); +} + +static void +open_console_window (void) +{ + if (((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE || + (HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) && AllocConsole ()) + { + if ((HANDLE) _get_osfhandle (fileno (stdout)) == INVALID_HANDLE_VALUE) + freopen ("CONOUT$", "w", stdout); + + if ((HANDLE) _get_osfhandle (fileno (stderr)) == INVALID_HANDLE_VALUE) + freopen ("CONOUT$", "w", stderr); + + SetConsoleTitleW (L"gdbus-daemon debug output."); + + atexit (wait_console_window); + } +} + +static void +idle_timeout_cb (GDBusDaemon *daemon, gpointer user_data) +{ + GMainLoop *loop = user_data; + g_main_loop_quit (loop); +} + +/* Satisfies STARTF_FORCEONFEEDBACK */ +static void +turn_off_the_starting_cursor (void) +{ + MSG msg; + BOOL bRet; + + PostQuitMessage (0); + + while ((bRet = GetMessage (&msg, 0, 0, 0)) != 0) + { + if (bRet == -1) + continue; + + TranslateMessage (&msg); + DispatchMessage (&msg); + } +} + +__declspec(dllexport) void __stdcall +g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow) +{ + GDBusDaemon *daemon; + GMainLoop *loop; + const char *address; + GError *error = NULL; + + turn_off_the_starting_cursor (); + + if (g_getenv ("GDBUS_DAEMON_DEBUG") != NULL) + open_console_window (); + + address = "nonce-tcp:"; + daemon = _g_dbus_daemon_new (address, NULL, &error); + if (daemon == NULL) + { + g_printerr ("Can't init bus: %s\n", error->message); + g_error_free (error); + return; + } + + loop = g_main_loop_new (NULL, FALSE); + + /* There is a subtle detail with "idle-timeout" signal of dbus daemon: + * It is fired on idle after last client disconnection, + * but (at least with glib 2.59.1) it is NEVER fired + * if no clients connect to daemon at all. + * This may lead to infinite run of this daemon process. + */ + g_signal_connect (daemon, "idle-timeout", G_CALLBACK (idle_timeout_cb), loop); + + if (publish_session_bus (_g_dbus_daemon_get_address (daemon))) + { + g_main_loop_run (loop); + + unpublish_session_bus (); + } + + g_main_loop_unref (loop); + g_object_unref (daemon); +} + +static gboolean autolaunch_binary_absent = FALSE; + +gchar * +_g_dbus_win32_get_session_address_dbus_launch (GError **error) +{ + HANDLE autolaunch_mutex, init_mutex; + char *address = NULL; + + autolaunch_mutex = acquire_mutex (DBUS_AUTOLAUNCH_MUTEX); + + init_mutex = acquire_mutex (UNIQUE_DBUS_INIT_MUTEX); + + if (is_mutex_owned (DBUS_DAEMON_MUTEX)) + address = read_shm (DBUS_DAEMON_ADDRESS_INFO); + + release_mutex (init_mutex); + + if (address == NULL && !autolaunch_binary_absent) + { + wchar_t gio_path[MAX_PATH + 2] = { 0 }; + int gio_path_len = GetModuleFileNameW (_g_io_win32_get_module (), gio_path, MAX_PATH + 1); + + /* The <= MAX_PATH check prevents truncated path usage */ + if (gio_path_len > 0 && gio_path_len <= MAX_PATH) + { + PROCESS_INFORMATION pi = { 0 }; + STARTUPINFOW si = { 0 }; + BOOL res = FALSE; + wchar_t exe_path[MAX_PATH + 100] = { 0 }; + /* calculate index of first char of dll file name inside full path */ + int gio_name_index = gio_path_len; + for (; gio_name_index > 0; --gio_name_index) + { + wchar_t prev_char = gio_path[gio_name_index - 1]; + if (prev_char == L'\\' || prev_char == L'/') + break; + } + gio_path[gio_name_index] = L'\0'; + wcscpy (exe_path, gio_path); + wcscat (exe_path, L"\\gdbus.exe"); + + if (GetFileAttributesW (exe_path) == INVALID_FILE_ATTRIBUTES) + { + /* warning won't be raised another time + * since autolaunch_binary_absent would be already set. + */ + autolaunch_binary_absent = TRUE; + g_warning ("win32 session dbus binary not found: %S", exe_path ); + } + else + { + wchar_t args[MAX_PATH*2 + 100] = { 0 }; + wcscpy (args, L"\""); + wcscat (args, exe_path); + wcscat (args, L"\" "); +#define _L_PREFIX_FOR_EXPANDED(arg) L##arg +#define _L_PREFIX(arg) _L_PREFIX_FOR_EXPANDED (arg) + wcscat (args, _L_PREFIX (_GDBUS_ARG_WIN32_RUN_SESSION_BUS)); +#undef _L_PREFIX +#undef _L_PREFIX_FOR_EXPANDED + + res = CreateProcessW (exe_path, args, + 0, 0, FALSE, + NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW | DETACHED_PROCESS, + 0, gio_path, + &si, &pi); + } + if (res) + { + address = read_shm (DBUS_DAEMON_ADDRESS_INFO); + if (address == NULL) + g_warning ("%S dbus binary failed to launch bus, maybe incompatible version", exe_path ); + } + } + } + + release_mutex (autolaunch_mutex); + + if (address == NULL) + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + _("Session dbus not running, and autolaunch failed")); + + return address; +} + #endif /* ---------------------------------------------------------------------------------------------------- */ diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h index a319166ee..8f8a93ba7 100644 --- a/gio/gdbusprivate.h +++ b/gio/gdbusprivate.h @@ -109,6 +109,17 @@ gchar *_g_dbus_hexdump (const gchar *data, gsize len, guint indent); #ifdef G_OS_WIN32 gchar *_g_dbus_win32_get_user_sid (void); + +#define _GDBUS_ARG_WIN32_RUN_SESSION_BUS "_win32_run_session_bus" +/* The g_win32_run_session_bus is exported from libgio dll on win32, + * but still is NOT part of API/ABI since it is declared in private header + * and used only by tool built from same sources. + * Initially this function was introduces for usage with rundll, + * so the signature is kept rundll-compatible, though parameters aren't used. + */ +__declspec(dllexport) void __stdcall +g_win32_run_session_bus (void* hwnd, void* hinst, const char* cmdline, int cmdshow); +gchar *_g_dbus_win32_get_session_address_dbus_launch (GError **error); #endif gchar *_g_dbus_get_machine_id (GError **error); diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c index eb641a9bc..07757f40f 100644 --- a/gio/gdbusserver.c +++ b/gio/gdbusserver.c @@ -72,11 +72,6 @@ * * An example of peer-to-peer communication with G-DBus can be found * in [gdbus-example-peer.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-peer.c). - * - * Note that a minimal #GDBusServer will accept connections from any - * peer. In many use-cases it will be necessary to add a #GDBusAuthObserver - * that only accepts connections that have successfully authenticated - * as the same user that is running the #GDBusServer. */ /** @@ -462,10 +457,6 @@ on_run (GSocketService *service, * Once constructed, you can use g_dbus_server_get_client_address() to * get a D-Bus address string that clients can use to connect. * - * To have control over the available authentication mechanisms and - * the users that are authorized to connect, it is strongly recommended - * to provide a non-%NULL #GDBusAuthObserver. - * * Connect to the #GDBusServer::new-connection signal to handle * incoming connections. * diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c index 7d7425ea9..238141158 100644 --- a/gio/gdesktopappinfo.c +++ b/gio/gdesktopappinfo.c @@ -4710,7 +4710,7 @@ g_desktop_app_info_get_boolean (GDesktopAppInfo *info, * a %NULL-terminated string array or %NULL if the specified * key cannot be found. The array should be freed with g_strfreev(). * - * Since: 2.60.0 + * Since: 2.60 */ gchar ** g_desktop_app_info_get_string_list (GDesktopAppInfo *info, diff --git a/gio/gfile.c b/gio/gfile.c index 13b435480..24b136d80 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -3284,12 +3284,12 @@ file_copy_fallback (GFile *source, out = (GOutputStream*)_g_local_file_output_stream_replace (_g_local_file_get_filename (G_LOCAL_FILE (destination)), FALSE, NULL, flags & G_FILE_COPY_BACKUP, - G_FILE_CREATE_REPLACE_DESTINATION | - G_FILE_CREATE_PRIVATE, info, + G_FILE_CREATE_REPLACE_DESTINATION, + info, cancellable, error); else out = (GOutputStream*)_g_local_file_output_stream_create (_g_local_file_get_filename (G_LOCAL_FILE (destination)), - FALSE, G_FILE_CREATE_PRIVATE, info, + FALSE, 0, info, cancellable, error); } else if (flags & G_FILE_COPY_OVERWRITE) @@ -3297,13 +3297,12 @@ file_copy_fallback (GFile *source, out = (GOutputStream *)g_file_replace (destination, NULL, flags & G_FILE_COPY_BACKUP, - G_FILE_CREATE_REPLACE_DESTINATION | - G_FILE_CREATE_PRIVATE, + G_FILE_CREATE_REPLACE_DESTINATION, cancellable, error); } else { - out = (GOutputStream *)g_file_create (destination, G_FILE_CREATE_PRIVATE, cancellable, error); + out = (GOutputStream *)g_file_create (destination, 0, cancellable, error); } if (!out) @@ -6935,6 +6934,7 @@ query_default_handler_query_info_cb (GObject *object, /** * g_file_query_default_handler_async: * @file: a #GFile to open + * @io_priority: the [I/O priority][io-priority] of the request * @cancellable: optional #GCancellable object, %NULL to ignore * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done * @user_data: (nullable): data to pass to @callback @@ -7964,7 +7964,7 @@ g_file_real_measure_disk_usage_finish (GFile *file, * * By default, errors are only reported against the toplevel file * itself. Errors found while recursing are silently ignored, unless - * %G_FILE_DISK_USAGE_REPORT_ALL_ERRORS is given in @flags. + * %G_FILE_MEASURE_REPORT_ANY_ERROR is given in @flags. * * The returned size, @disk_usage, is in bytes and should be formatted * with g_format_size() in order to get something reasonable for showing diff --git a/gio/gfile.h b/gio/gfile.h index 6e25b0de0..9c9ea9572 100644 --- a/gio/gfile.h +++ b/gio/gfile.h @@ -80,14 +80,14 @@ typedef struct _GFileIface GFileIface; * @set_display_name: Sets the display name for a #GFile. * @set_display_name_async: Asynchronously sets a #GFile's display name. * @set_display_name_finish: Finishes asynchronously setting a #GFile's display name. - * @query_settable_attributes: Returns a list of #GFileAttributes that can be set. - * @_query_settable_attributes_async: Asynchronously gets a list of #GFileAttributes that can be set. + * @query_settable_attributes: Returns a list of #GFileAttributeInfos that can be set. + * @_query_settable_attributes_async: Asynchronously gets a list of #GFileAttributeInfos that can be set. * @_query_settable_attributes_finish: Finishes asynchronously querying settable attributes. - * @query_writable_namespaces: Returns a list of #GFileAttribute namespaces that are writable. - * @_query_writable_namespaces_async: Asynchronously gets a list of #GFileAttribute namespaces that are writable. + * @query_writable_namespaces: Returns a list of #GFileAttributeInfo namespaces that are writable. + * @_query_writable_namespaces_async: Asynchronously gets a list of #GFileAttributeInfo namespaces that are writable. * @_query_writable_namespaces_finish: Finishes asynchronously querying the writable namespaces. - * @set_attribute: Sets a #GFileAttribute. - * @set_attributes_from_info: Sets a #GFileAttribute with information from a #GFileInfo. + * @set_attribute: Sets a #GFileAttributeInfo. + * @set_attributes_from_info: Sets a #GFileAttributeInfo with information from a #GFileInfo. * @set_attributes_async: Asynchronously sets a file's attributes. * @set_attributes_finish: Finishes setting a file's attributes asynchronously. * @read_fn: Reads a file asynchronously. diff --git a/gio/gfileinfo.c b/gio/gfileinfo.c index 420e46d56..d1c9140df 100644 --- a/gio/gfileinfo.c +++ b/gio/gfileinfo.c @@ -179,7 +179,8 @@ ensure_attribute_hash (void) attribute_hash = g_hash_table_new (g_str_hash, g_str_equal); #define REGISTER_ATTRIBUTE(name) G_STMT_START{\ - guint _u = _lookup_attribute (G_FILE_ATTRIBUTE_ ## name); \ + guint _u G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; \ + _u = _lookup_attribute (G_FILE_ATTRIBUTE_ ## name); \ /* use for generating the ID: g_print ("#define G_FILE_ATTRIBUTE_ID_%s (%u + %u)\n", #name + 17, _u & ~ID_MASK, _u & ID_MASK); */ \ g_assert (_u == G_FILE_ATTRIBUTE_ID_ ## name); \ }G_STMT_END diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h index 2ca623c3a..622c2b611 100644 --- a/gio/gfileinfo.h +++ b/gio/gfileinfo.h @@ -76,6 +76,7 @@ typedef struct _GFileInfoClass GFileInfoClass; * A key in the "standard" namespace for checking if the file is a symlink. * Typically the actual type is something else, if we followed the symlink * to get the type. + * On Windows NTFS mountpoints are considered to be symlinks as well. * Corresponding #GFileAttributeType is %G_FILE_ATTRIBUTE_TYPE_BOOLEAN. **/ #define G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK "standard::is-symlink" /* boolean */ diff --git a/gio/ginputstream.c b/gio/ginputstream.c index e0b34eddc..20cece53d 100644 --- a/gio/ginputstream.c +++ b/gio/ginputstream.c @@ -127,8 +127,8 @@ g_input_stream_init (GInputStream *stream) /** * g_input_stream_read: * @stream: a #GInputStream. - * @buffer: (array length=count) (element-type guint8): a buffer to - * read data into (which should be at least count bytes long). + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long). * @count: the number of bytes that will be read from the stream * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. * @error: location to store the error occurring, or %NULL to ignore @@ -208,8 +208,8 @@ g_input_stream_read (GInputStream *stream, /** * g_input_stream_read_all: * @stream: a #GInputStream. - * @buffer: (array length=count) (element-type guint8): a buffer to - * read data into (which should be at least count bytes long). + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long). * @count: the number of bytes that will be read from the stream * @bytes_read: (out): location to store the number of bytes that was read from the stream * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore. @@ -550,8 +550,8 @@ async_ready_close_callback_wrapper (GObject *source_object, /** * g_input_stream_read_async: * @stream: A #GInputStream. - * @buffer: (array length=count) (element-type guint8): a buffer to - * read data into (which should be at least count bytes long). + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long). * @count: the number of bytes that will be read from the stream * @io_priority: the [I/O priority][io-priority] * of the request. @@ -742,8 +742,8 @@ read_all_async_thread (GTask *task, /** * g_input_stream_read_all_async: * @stream: A #GInputStream - * @buffer: (array length=count) (element-type guint8): a buffer to - * read data into (which should be at least count bytes long) + * @buffer: (array length=count) (element-type guint8) (out caller-allocates): + * a buffer to read data into (which should be at least count bytes long) * @count: the number of bytes that will be read from the stream * @io_priority: the [I/O priority][io-priority] of the request * @cancellable: (nullable): optional #GCancellable object, %NULL to ignore @@ -1045,7 +1045,7 @@ g_input_stream_skip_async (GInputStream *stream, * * Finishes a stream skip operation. * - * Returns: the size of the bytes skipped, or %-1 on error. + * Returns: the size of the bytes skipped, or `-1` on error. **/ gssize g_input_stream_skip_finish (GInputStream *stream, diff --git a/gio/gio-autocleanups.h b/gio/gio-autocleanups.h index dcba4d976..ff407293f 100644 --- a/gio/gio-autocleanups.h +++ b/gio/gio-autocleanups.h @@ -112,6 +112,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GResource, g_resource_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSeekable, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsBackend, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsSchema, g_settings_schema_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsSchemaKey, g_settings_schema_key_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettingsSchemaSource, g_settings_schema_source_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSettings, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSimpleActionGroup, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GSimpleAction, g_object_unref) diff --git a/gio/gioenums.h b/gio/gioenums.h index 9c7d9b6ac..2fc69b6be 100644 --- a/gio/gioenums.h +++ b/gio/gioenums.h @@ -361,6 +361,15 @@ typedef enum { * @G_FILE_TYPE_MOUNTABLE: File is a mountable location. * * Indicates the file's on-disk type. + * + * On Windows systems a file will never have %G_FILE_TYPE_SYMBOLIC_LINK type; + * use #GFileInfo and %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK to determine + * whether a file is a symlink or not. This is due to the fact that NTFS does + * not have a single filesystem object type for symbolic links - it has + * files that symlink to files, and directories that symlink to directories. + * #GFileType enumeration cannot precisely represent this important distinction, + * which is why all Windows symlinks will continue to be reported as + * %G_FILE_TYPE_REGULAR or %G_FILE_TYPE_DIRECTORY. **/ typedef enum { G_FILE_TYPE_UNKNOWN = 0, diff --git a/gio/gioerror.c b/gio/gioerror.c index 900553e98..1ec120d98 100644 --- a/gio/gioerror.c +++ b/gio/gioerror.c @@ -272,6 +272,12 @@ g_io_error_from_errno (gint err_no) break; #endif +#ifdef ENOTSOCK + case ENOTSOCK: + return G_IO_ERROR_INVALID_ARGUMENT; + break; +#endif + default: return G_IO_ERROR_FAILED; break; diff --git a/gio/giomodule.c b/gio/giomodule.c index b97e3a26b..ee1b0b6f4 100644 --- a/gio/giomodule.c +++ b/gio/giomodule.c @@ -1209,7 +1209,6 @@ _g_io_modules_ensure_loaded (void) /* Initialize types from built-in "modules" */ g_type_ensure (g_null_settings_backend_get_type ()); g_type_ensure (g_memory_settings_backend_get_type ()); - g_type_ensure (g_keyfile_settings_backend_get_type ()); #if defined(HAVE_INOTIFY_INIT1) g_type_ensure (g_inotify_file_monitor_get_type ()); #endif @@ -1236,7 +1235,7 @@ _g_io_modules_ensure_loaded (void) g_type_ensure (g_network_monitor_portal_get_type ()); g_type_ensure (g_proxy_resolver_portal_get_type ()); #endif -#if HAVE_MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 g_type_ensure (g_cocoa_notification_backend_get_type ()); #endif #ifdef G_OS_WIN32 diff --git a/gio/giotypes.h b/gio/giotypes.h index 738e517bb..c9ad8dd90 100644 --- a/gio/giotypes.h +++ b/gio/giotypes.h @@ -335,7 +335,7 @@ typedef gboolean (* GFileReadMoreCallback) (const char *file_contents, * final async result would be reported). * * @current_size is in the same units as requested by the operation (see - * %G_FILE_DISK_USAGE_APPARENT_SIZE). + * %G_FILE_MEASURE_APPARENT_SIZE). * * The frequency of the updates is implementation defined, but is * ideally about once every 200ms. diff --git a/gio/gkeyfilesettingsbackend.c b/gio/gkeyfilesettingsbackend.c index 3d793f5a8..3bc392351 100644 --- a/gio/gkeyfilesettingsbackend.c +++ b/gio/gkeyfilesettingsbackend.c @@ -80,7 +80,7 @@ typedef struct #ifdef G_OS_WIN32 #define EXTENSION_PRIORITY 10 #else -#define EXTENSION_PRIORITY (glib_should_use_portal () && !glib_has_dconf_access_in_sandbox () ? 110 : 10) +#define EXTENSION_PRIORITY (glib_should_use_portal () ? 110 : 10) #endif G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend, @@ -334,7 +334,7 @@ g_keyfile_settings_backend_write_one (gpointer key, gpointer user_data) { WriteManyData *data = user_data; - gboolean success; + gboolean success G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; success = set_to_keyfile (data->kfsb, key, value); g_assert (success); @@ -740,8 +740,7 @@ g_keyfile_settings_backend_set_property (GObject *object, case PROP_FILENAME: /* Construct only. */ g_assert (kfsb->file == NULL); - if (g_value_get_string (value)) - kfsb->file = g_file_new_for_path (g_value_get_string (value)); + kfsb->file = g_file_new_for_path (g_value_get_string (value)); break; case PROP_ROOT_PATH: diff --git a/gio/glib-compile-schemas.c b/gio/glib-compile-schemas.c index 5e1bebbba..8ad3c6be1 100644 --- a/gio/glib-compile-schemas.c +++ b/gio/glib-compile-schemas.c @@ -648,8 +648,10 @@ key_state_serialise (KeyState *state) else { GVariantBuilder builder; + gboolean checked G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; - g_assert (key_state_check (state, NULL)); + checked = key_state_check (state, NULL); + g_assert (checked); g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE); diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 59cfb9ba9..487f8cc1a 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -161,7 +161,7 @@ _g_local_file_info_create_fs_id (GLocalFileStat *statbuf) static gchar * read_link (const gchar *full_name) { -#if defined (HAVE_READLINK) || defined (G_OS_WIN32) +#if defined (HAVE_READLINK) gchar *buffer; guint size; @@ -171,12 +171,8 @@ read_link (const gchar *full_name) while (1) { int read_size; - -#ifndef G_OS_WIN32 + read_size = readlink (full_name, buffer, size); -#else - read_size = GLIB_PRIVATE_CALL (g_win32_readlink_utf8) (full_name, buffer, size); -#endif if (read_size < 0) { g_free (buffer); @@ -190,6 +186,17 @@ read_link (const gchar *full_name) size *= 2; buffer = g_realloc (buffer, size); } +#elif defined (G_OS_WIN32) + gchar *buffer; + int read_size; + + read_size = GLIB_PRIVATE_CALL (g_win32_readlink_utf8) (full_name, NULL, 0, &buffer, TRUE); + if (read_size < 0) + return NULL; + else if (read_size == 0) + return strdup (""); + else + return buffer; #else return NULL; #endif @@ -957,8 +964,8 @@ set_info_from_stat (GFileInfo *info, else if (S_ISLNK (statbuf->st_mode)) file_type = G_FILE_TYPE_SYMBOLIC_LINK; #elif defined (G_OS_WIN32) - if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK || - statbuf->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) + else if (statbuf->reparse_tag == IO_REPARSE_TAG_SYMLINK || + statbuf->reparse_tag == IO_REPARSE_TAG_MOUNT_POINT) file_type = G_FILE_TYPE_SYMBOLIC_LINK; #endif @@ -966,15 +973,17 @@ set_info_from_stat (GFileInfo *info, g_file_info_set_size (info, statbuf->st_size); _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_DEVICE, statbuf->st_dev); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_NLINK, statbuf->st_nlink); #ifndef G_OS_WIN32 /* Pointless setting these on Windows even if they exist in the struct */ _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_INODE, statbuf->st_ino); - _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_NLINK, statbuf->st_nlink); _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_UID, statbuf->st_uid); _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_GID, statbuf->st_gid); _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_RDEV, statbuf->st_rdev); #endif - /* FIXME: st_mode is mostly pointless on Windows, too. Set the attribute or not? */ + /* Mostly pointless on Windows. + * Still, it allows for S_ISREG/S_ISDIR and IWRITE (read-only) checks. + */ _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_MODE, statbuf->st_mode); #if defined (HAVE_STRUCT_STAT_ST_BLKSIZE) _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_UNIX_BLOCK_SIZE, statbuf->st_blksize); diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c index 8a4c4ec43..897d5f244 100644 --- a/gio/glocalfilemonitor.c +++ b/gio/glocalfilemonitor.c @@ -328,6 +328,7 @@ g_file_monitor_source_send_synthetic_created (GFileMonitorSource *fms, g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, child, NULL); } +#ifndef G_DISABLE_ASSERT static gboolean is_basename (const gchar *name) { @@ -336,6 +337,7 @@ is_basename (const gchar *name) return !strchr (name, '/'); } +#endif /* !G_DISABLE_ASSERT */ gboolean g_file_monitor_source_handle_event (GFileMonitorSource *fms, @@ -788,11 +790,11 @@ g_local_file_monitor_start (GLocalFileMonitor *local_monitor, #endif } + g_source_attach ((GSource *) source, context); + G_LOCAL_FILE_MONITOR_GET_CLASS (local_monitor)->start (local_monitor, source->dirname, source->basename, source->filename, source); - - g_source_attach ((GSource *) source, context); } static void diff --git a/gio/gmountoperation.c b/gio/gmountoperation.c index c3f5d25d8..76a5024ff 100644 --- a/gio/gmountoperation.c +++ b/gio/gmountoperation.c @@ -799,7 +799,7 @@ g_mount_operation_set_password_save (GMountOperation *op, * Gets a choice from the mount operation. * * Returns: an integer containing an index of the user's choice from - * the choice's list, or %0. + * the choice's list, or `0`. **/ int g_mount_operation_get_choice (GMountOperation *op) diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c index e46b5ac65..df1bc3158 100644 --- a/gio/gnetworkaddress.c +++ b/gio/gnetworkaddress.c @@ -52,10 +52,6 @@ * then attempt to connect to that host, handling the possibility of * multiple IP addresses and multiple address families. * - * The enumeration results of resolved addresses *may* be cached as long - * as this object is kept alive which may have unexpected results if - * alive for too long. - * * See #GSocketConnectable for an example of using the connectable * interface. */ @@ -70,7 +66,7 @@ struct _GNetworkAddressPrivate { gchar *hostname; guint16 port; - GList *cached_sockaddrs; + GList *sockaddrs; gchar *scheme; gint64 resolver_serial; @@ -109,7 +105,7 @@ g_network_address_finalize (GObject *object) g_free (addr->priv->hostname); g_free (addr->priv->scheme); - g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); + g_list_free_full (addr->priv->sockaddrs, g_object_unref); G_OBJECT_CLASS (g_network_address_parent_class)->finalize (object); } @@ -224,51 +220,30 @@ g_network_address_get_property (GObject *object, } -/** - * inet_addresses_to_inet_socket_addresses: - * @addresses: (transfer full): #GList of #GInetAddress +/* + * g_network_address_add_addresses: + * @addr: A #GNetworkAddress + * @addresses: (transfer full): List of #GSocketAddress + * @resolver_serial: Serial of #GResolver used * - * Returns: (transfer full): #GList of #GInetSocketAddress + * Consumes address list and adds them to internal list. */ -static GList * -inet_addresses_to_inet_socket_addresses (GNetworkAddress *addr, - GList *addresses) +static void +g_network_address_add_addresses (GNetworkAddress *addr, + GList *addresses, + guint64 resolver_serial) { - GList *a, *socket_addresses = NULL; + GList *a; + GSocketAddress *sockaddr; for (a = addresses; a; a = a->next) { - GSocketAddress *sockaddr = g_inet_socket_address_new (a->data, addr->priv->port); - socket_addresses = g_list_append (socket_addresses, g_steal_pointer (&sockaddr)); + sockaddr = g_inet_socket_address_new (a->data, addr->priv->port); + addr->priv->sockaddrs = g_list_append (addr->priv->sockaddrs, sockaddr); g_object_unref (a->data); } - g_list_free (addresses); - return socket_addresses; -} - -/* - * g_network_address_set_cached_addresses: - * @addr: A #GNetworkAddress - * @addresses: (transfer full): List of #GInetAddress or #GInetSocketAddress - * @resolver_serial: Serial of #GResolver used - * - * Consumes @addresses and uses them to replace the current internal list. - */ -static void -g_network_address_set_cached_addresses (GNetworkAddress *addr, - GList *addresses, - guint64 resolver_serial) -{ - g_assert (addresses != NULL); - if (addr->priv->cached_sockaddrs) - g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); - - if (G_IS_INET_SOCKET_ADDRESS (addresses->data)) - addr->priv->cached_sockaddrs = g_steal_pointer (&addresses); - else - addr->priv->cached_sockaddrs = inet_addresses_to_inet_socket_addresses (addr, g_steal_pointer (&addresses)); addr->priv->resolver_serial = resolver_serial; } @@ -277,13 +252,11 @@ g_network_address_parse_sockaddr (GNetworkAddress *addr) { GSocketAddress *sockaddr; - g_assert (addr->priv->cached_sockaddrs == NULL); - sockaddr = g_inet_socket_address_new_from_string (addr->priv->hostname, addr->priv->port); if (sockaddr) { - addr->priv->cached_sockaddrs = g_list_append (addr->priv->cached_sockaddrs, sockaddr); + addr->priv->sockaddrs = g_list_append (addr->priv->sockaddrs, sockaddr); return TRUE; } else @@ -333,7 +306,7 @@ g_network_address_new (const gchar *hostname, * resolving `localhost`, and an IPv6 address for `localhost6`. * * g_network_address_get_hostname() will always return `localhost` for - * #GNetworkAddresses created with this constructor. + * a #GNetworkAddress created with this constructor. * * Returns: (transfer full) (type GNetworkAddress): the new #GNetworkAddress * @@ -352,7 +325,7 @@ g_network_address_new_loopback (guint16 port) addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET6)); addrs = g_list_append (addrs, g_inet_address_new_loopback (AF_INET)); - g_network_address_set_cached_addresses (addr, g_steal_pointer (&addrs), 0); + g_network_address_add_addresses (addr, g_steal_pointer (&addrs), 0); return G_SOCKET_CONNECTABLE (addr); } @@ -921,6 +894,7 @@ typedef struct { GNetworkAddress *addr; /* (owned) */ GList *addresses; /* (owned) (nullable) */ + GList *last_tail; /* (unowned) (nullable) */ GList *current_item; /* (unowned) (nullable) */ GTask *queued_task; /* (owned) (nullable) */ GTask *waiting_task; /* (owned) (nullable) */ @@ -953,8 +927,8 @@ g_network_address_address_enumerator_finalize (GObject *object) g_clear_object (&addr_enum->waiting_task); g_clear_error (&addr_enum->last_error); g_object_unref (addr_enum->addr); + g_clear_pointer (&addr_enum->addresses, g_list_free); g_clear_pointer (&addr_enum->context, g_main_context_unref); - g_list_free_full (addr_enum->addresses, g_object_unref); G_OBJECT_CLASS (_g_network_address_address_enumerator_parent_class)->finalize (object); } @@ -1040,19 +1014,16 @@ list_copy_interleaved (GList *list) } /* list_concat_interleaved: - * @parent_list: (transfer container): Already existing list - * @current_item: (transfer container): Item after which to resort - * @new_list: (transfer container): New list to be interleaved and concatenated + * @current_item: (transfer container): Already existing list + * @new_list: (transfer none): New list to be interleaved and concatenated * * This differs from g_list_concat() + list_copy_interleaved() in that it sorts - * items in the previous list starting from @current_item and concats the results - * to @parent_list. + * items in the previous list starting from @current_item. * * Returns: (transfer container): New start of list */ static GList * -list_concat_interleaved (GList *parent_list, - GList *current_item, +list_concat_interleaved (GList *current_item, GList *new_list) { GList *ipv4 = NULL, *ipv6 = NULL, *interleaved, *trailing = NULL; @@ -1069,7 +1040,6 @@ list_concat_interleaved (GList *parent_list, list_split_families (trailing, &ipv4, &ipv6); list_split_families (new_list, &ipv4, &ipv6); - g_list_free (new_list); if (trailing) g_list_free (trailing); @@ -1079,73 +1049,7 @@ list_concat_interleaved (GList *parent_list, else interleaved = list_interleave_families (ipv4, ipv6); - return g_list_concat (parent_list, interleaved); -} - -static void -maybe_update_address_cache (GNetworkAddressAddressEnumerator *addr_enum, - GResolver *resolver) -{ - GList *addresses, *p; - - /* Only cache complete results */ - if (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4 || addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV6) - return; - - /* The enumerators list will not necessarily be fully sorted */ - addresses = list_copy_interleaved (addr_enum->addresses); - for (p = addresses; p; p = p->next) - g_object_ref (p->data); - - g_network_address_set_cached_addresses (addr_enum->addr, g_steal_pointer (&addresses), g_resolver_get_serial (resolver)); -} - -static void -g_network_address_address_enumerator_add_addresses (GNetworkAddressAddressEnumerator *addr_enum, - GList *addresses, - GResolver *resolver) -{ - GList *new_addresses = inet_addresses_to_inet_socket_addresses (addr_enum->addr, addresses); - - if (addr_enum->addresses == NULL) - addr_enum->addresses = g_steal_pointer (&new_addresses); - else - addr_enum->addresses = list_concat_interleaved (addr_enum->addresses, addr_enum->current_item, g_steal_pointer (&new_addresses)); - - maybe_update_address_cache (addr_enum, resolver); -} - -static gpointer -copy_object (gconstpointer src, - gpointer user_data) -{ - return g_object_ref (G_OBJECT (src)); -} - -static GSocketAddress * -init_and_query_next_address (GNetworkAddressAddressEnumerator *addr_enum) -{ - GList *next_item; - - if (addr_enum->addresses == NULL) - addr_enum->addresses = g_list_copy_deep (addr_enum->addr->priv->cached_sockaddrs, - copy_object, NULL); - - /* We always want to look at the next item at call time to get the latest results. - That means that sometimes ->next is NULL this call but is valid next call. - */ - if (addr_enum->current_item == NULL) - next_item = addr_enum->current_item = addr_enum->addresses; - else - next_item = g_list_next (addr_enum->current_item); - - if (next_item) - { - addr_enum->current_item = next_item; - return g_object_ref (addr_enum->current_item->data); - } - else - return NULL; + return g_list_concat (current_item, interleaved); } static GSocketAddress * @@ -1155,6 +1059,7 @@ g_network_address_address_enumerator_next (GSocketAddressEnumerator *enumerator { GNetworkAddressAddressEnumerator *addr_enum = G_NETWORK_ADDRESS_ADDRESS_ENUMERATOR (enumerator); + GSocketAddress *sockaddr; if (addr_enum->addresses == NULL) { @@ -1166,13 +1071,13 @@ g_network_address_address_enumerator_next (GSocketAddressEnumerator *enumerator addr->priv->resolver_serial != serial) { /* Resolver has reloaded, discard cached addresses */ - g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); - addr->priv->cached_sockaddrs = NULL; + g_list_free_full (addr->priv->sockaddrs, g_object_unref); + addr->priv->sockaddrs = NULL; } - if (!addr->priv->cached_sockaddrs) + if (!addr->priv->sockaddrs) g_network_address_parse_sockaddr (addr); - if (!addr->priv->cached_sockaddrs) + if (!addr->priv->sockaddrs) { GList *addresses; @@ -1185,13 +1090,62 @@ g_network_address_address_enumerator_next (GSocketAddressEnumerator *enumerator return NULL; } - g_network_address_set_cached_addresses (addr, g_steal_pointer (&addresses), serial); + g_network_address_add_addresses (addr, g_steal_pointer (&addresses), serial); } + addr_enum->current_item = addr_enum->addresses = list_copy_interleaved (addr->priv->sockaddrs); + addr_enum->last_tail = g_list_last (addr->priv->sockaddrs); g_object_unref (resolver); } - return init_and_query_next_address (addr_enum); + if (addr_enum->current_item == NULL) + return NULL; + + sockaddr = addr_enum->current_item->data; + addr_enum->current_item = g_list_next (addr_enum->current_item); + return g_object_ref (sockaddr); +} + +/* + * Each enumeration lazily initializes the internal address list from the + * master list. It does this since addresses come in asynchronously and + * they need to be resorted into the list already in use. + */ +static GSocketAddress * +init_and_query_next_address (GNetworkAddressAddressEnumerator *addr_enum) +{ + GNetworkAddress *addr = addr_enum->addr; + GSocketAddress *sockaddr; + + if (addr_enum->addresses == NULL) + { + addr_enum->current_item = addr_enum->addresses = list_copy_interleaved (addr->priv->sockaddrs); + addr_enum->last_tail = g_list_last (addr_enum->addr->priv->sockaddrs); + if (addr_enum->current_item) + sockaddr = g_object_ref (addr_enum->current_item->data); + else + sockaddr = NULL; + } + else + { + GList *parent_tail = g_list_last (addr_enum->addr->priv->sockaddrs); + + if (addr_enum->last_tail != parent_tail) + { + addr_enum->current_item = list_concat_interleaved (addr_enum->current_item, g_list_next (addr_enum->last_tail)); + addr_enum->last_tail = parent_tail; + } + + if (addr_enum->current_item->next) + { + addr_enum->current_item = g_list_next (addr_enum->current_item); + sockaddr = g_object_ref (addr_enum->current_item->data); + } + else + sockaddr = NULL; + } + + return sockaddr; } static void @@ -1199,13 +1153,12 @@ complete_queued_task (GNetworkAddressAddressEnumerator *addr_enum, GTask *task, GError *error) { + GSocketAddress *sockaddr = init_and_query_next_address (addr_enum); + if (error) g_task_return_error (task, error); else - { - GSocketAddress *sockaddr = init_and_query_next_address (addr_enum); - g_task_return_pointer (task, g_steal_pointer (&sockaddr), g_object_unref); - } + g_task_return_pointer (task, sockaddr, g_object_unref); g_object_unref (task); } @@ -1244,7 +1197,13 @@ got_ipv6_addresses (GObject *source_object, addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error); if (!error) - g_network_address_address_enumerator_add_addresses (addr_enum, g_steal_pointer (&addresses), resolver); + { + /* Regardless of which responds first we add them to the enumerator + * which does mean the timing of next_async() will potentially change + * the results */ + g_network_address_add_addresses (addr_enum->addr, g_steal_pointer (&addresses), + g_resolver_get_serial (resolver)); + } else g_debug ("IPv6 DNS error: %s", error->message); @@ -1261,8 +1220,13 @@ got_ipv6_addresses (GObject *source_object, */ if (error != NULL && !addr_enum->last_error && (addr_enum->state & RESOLVE_STATE_WAITING_ON_IPV4)) { - /* ipv6 lookup failed, but ipv4 is still outstanding. wait. */ addr_enum->last_error = g_steal_pointer (&error); + + addr_enum->wait_source = g_timeout_source_new (HAPPY_EYEBALLS_RESOLUTION_DELAY_MS); + g_source_set_callback (addr_enum->wait_source, + on_address_timeout, + addr_enum, NULL); + g_source_attach (addr_enum->wait_source, addr_enum->context); } else if (addr_enum->waiting_task != NULL) { @@ -1300,7 +1264,10 @@ got_ipv4_addresses (GObject *source_object, addresses = g_resolver_lookup_by_name_with_flags_finish (resolver, result, &error); if (!error) - g_network_address_address_enumerator_add_addresses (addr_enum, g_steal_pointer (&addresses), resolver); + { + g_network_address_add_addresses (addr_enum->addr, g_steal_pointer (&addresses), + g_resolver_get_serial (resolver)); + } else g_debug ("IPv4 DNS error: %s", error->message); @@ -1364,11 +1331,11 @@ g_network_address_address_enumerator_next_async (GSocketAddressEnumerator *enum addr->priv->resolver_serial != serial) { /* Resolver has reloaded, discard cached addresses */ - g_list_free_full (addr->priv->cached_sockaddrs, g_object_unref); - addr->priv->cached_sockaddrs = NULL; + g_list_free_full (addr->priv->sockaddrs, g_object_unref); + addr->priv->sockaddrs = NULL; } - if (addr->priv->cached_sockaddrs == NULL) + if (addr->priv->sockaddrs == NULL) { if (g_network_address_parse_sockaddr (addr)) complete_queued_task (addr_enum, task, NULL); diff --git a/gio/gnetworkmonitornm.c b/gio/gnetworkmonitornm.c index 9013fd49c..4e2a35e8a 100644 --- a/gio/gnetworkmonitornm.c +++ b/gio/gnetworkmonitornm.c @@ -52,19 +52,6 @@ typedef enum { NM_CONNECTIVITY_FULL } NMConnectivityState; -/* Copied from https://developer.gnome.org/libnm-util/stable/libnm-util-NetworkManager.html#NMState; - * used inline to avoid a NetworkManager dependency from GLib. */ -typedef enum { - NM_STATE_UNKNOWN = 0, - NM_STATE_ASLEEP = 10, - NM_STATE_DISCONNECTED = 20, - NM_STATE_DISCONNECTING = 30, - NM_STATE_CONNECTING = 40, - NM_STATE_CONNECTED_LOCAL = 50, - NM_STATE_CONNECTED_SITE = 60, - NM_STATE_CONNECTED_GLOBAL = 70, -} NMState; - struct _GNetworkMonitorNMPrivate { GDBusProxy *proxy; @@ -168,19 +155,11 @@ sync_properties (GNetworkMonitorNM *nm, gboolean emit_signals) { GVariant *v; - NMState nm_state; NMConnectivityState nm_connectivity; gboolean new_network_available; gboolean new_network_metered; GNetworkConnectivity new_connectivity; - v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "State"); - if (!v) - return; - - nm_state = g_variant_get_uint32 (v); - g_variant_unref (v); - v = g_dbus_proxy_get_cached_property (nm->priv->proxy, "Connectivity"); if (!v) return; @@ -188,26 +167,14 @@ sync_properties (GNetworkMonitorNM *nm, nm_connectivity = g_variant_get_uint32 (v); g_variant_unref (v); - if (nm_state <= NM_STATE_CONNECTED_LOCAL) + if (nm_connectivity == NM_CONNECTIVITY_UNKNOWN || + nm_connectivity == NM_CONNECTIVITY_NONE) { new_network_available = FALSE; new_network_metered = FALSE; new_connectivity = G_NETWORK_CONNECTIVITY_LOCAL; } - else if (nm_state <= NM_STATE_CONNECTED_SITE) - { - new_network_available = TRUE; - new_network_metered = FALSE; - if (nm_connectivity == NM_CONNECTIVITY_PORTAL) - { - new_connectivity = G_NETWORK_CONNECTIVITY_PORTAL; - } - else - { - new_connectivity = G_NETWORK_CONNECTIVITY_LIMITED; - } - } - else /* nm_state == NM_STATE_CONNECTED_FULL */ + else { /* this is only available post NM 1.0 */ diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c index be68569ed..b798d7cd1 100644 --- a/gio/gopenuriportal.c +++ b/gio/gopenuriportal.c @@ -279,7 +279,7 @@ g_openuri_portal_open_uri_async (const char *uri, if (sender[i] == '.') sender[i] = '_'; - handle = g_strdup_printf ("/org/freedesktop/portal/desktop/request/%s/%s", sender, token); + handle = g_strdup_printf ("/org/fredesktop/portal/desktop/request/%s/%s", sender, token); g_object_set_data_full (G_OBJECT (task), "handle", handle, g_free); g_free (sender); diff --git a/gio/gpollableoutputstream.h b/gio/gpollableoutputstream.h index c1e7ad889..c282afdec 100644 --- a/gio/gpollableoutputstream.h +++ b/gio/gpollableoutputstream.h @@ -49,6 +49,8 @@ typedef struct _GPollableOutputStreamInterface GPollableOutputStreamInterface; * @create_source: Creates a #GSource to poll the stream * @write_nonblocking: Does a non-blocking write or returns * %G_IO_ERROR_WOULD_BLOCK + * @writev_nonblocking: Does a vectored non-blocking write, or returns + * %G_POLLABLE_RETURN_WOULD_BLOCK * * The interface for pollable output streams. * @@ -61,6 +63,12 @@ typedef struct _GPollableOutputStreamInterface GPollableOutputStreamInterface; * implementation may return %TRUE when the stream is not actually * writable. * + * The default implementation of @writev_nonblocking calls + * g_pollable_output_stream_write_nonblocking() for each vector, and converts + * its return value and error (if set) to a #GPollableReturn. You should + * override this where possible to avoid having to allocate a #GError to return + * %G_IO_ERROR_WOULD_BLOCK. + * * Since: 2.28 */ struct _GPollableOutputStreamInterface diff --git a/gio/gportalsupport.c b/gio/gportalsupport.c index b0a94b360..2f1e82517 100644 --- a/gio/gportalsupport.c +++ b/gio/gportalsupport.c @@ -23,7 +23,6 @@ static gboolean flatpak_info_read; static gboolean use_portal; static gboolean network_available; -static gboolean dconf_access; static void read_flatpak_info (void) @@ -41,13 +40,11 @@ read_flatpak_info (void) use_portal = TRUE; network_available = FALSE; - dconf_access = FALSE; keyfile = g_key_file_new (); if (g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL)) { char **shared = NULL; - char *dconf_policy = NULL; shared = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); if (shared) @@ -55,14 +52,6 @@ read_flatpak_info (void) network_available = g_strv_contains ((const char * const *)shared, "network"); g_strfreev (shared); } - - dconf_policy = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); - if (dconf_policy) - { - if (strcmp (dconf_policy, "talk") == 0) - dconf_access = TRUE; - g_free (dconf_policy); - } } g_key_file_unref (keyfile); @@ -75,7 +64,6 @@ read_flatpak_info (void) if (var && var[0] == '1') use_portal = TRUE; network_available = TRUE; - dconf_access = TRUE; } } @@ -93,9 +81,3 @@ glib_network_available_in_sandbox (void) return network_available; } -gboolean -glib_has_dconf_access_in_sandbox (void) -{ - read_flatpak_info (); - return dconf_access; -} diff --git a/gio/gportalsupport.h b/gio/gportalsupport.h index 746f1fd6b..a331f45d3 100644 --- a/gio/gportalsupport.h +++ b/gio/gportalsupport.h @@ -24,7 +24,6 @@ G_BEGIN_DECLS gboolean glib_should_use_portal (void); gboolean glib_network_available_in_sandbox (void); -gboolean glib_has_dconf_access_in_sandbox (void); G_END_DECLS diff --git a/gio/gproxyaddressenumerator.h b/gio/gproxyaddressenumerator.h index de9fa833e..470f1dc66 100644 --- a/gio/gproxyaddressenumerator.h +++ b/gio/gproxyaddressenumerator.h @@ -40,7 +40,7 @@ G_BEGIN_DECLS * GProxyAddressEnumerator: * * A subclass of #GSocketAddressEnumerator that takes another address - * enumerator and wraps its results in #GProxyAddresses as + * enumerator and wraps each of its results in a #GProxyAddress as * directed by the default #GProxyResolver. */ diff --git a/gio/gresolver.c b/gio/gresolver.c index 6a33634c5..7f064322b 100644 --- a/gio/gresolver.c +++ b/gio/gresolver.c @@ -340,9 +340,18 @@ handle_ip_address (const char *hostname, if (inet_aton (hostname, &ip4addr)) #endif { +#ifdef G_OS_WIN32 + gchar *error_message = g_win32_error_message (WSAHOST_NOT_FOUND); +#else + gchar *error_message = g_locale_to_utf8 (gai_strerror (EAI_NONAME), -1, NULL, NULL, NULL); + if (error_message == NULL) + error_message = g_strdup ("[Invalid UTF-8]"); +#endif g_set_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND, _("Error resolving “%s”: %s"), - hostname, gai_strerror (EAI_NONAME)); + hostname, error_message); + g_free (error_message); + return TRUE; } diff --git a/gio/gschema.dtd b/gio/gschema.dtd index 3a903e7ab..1599f8de7 100644 --- a/gio/gschema.dtd +++ b/gio/gschema.dtd @@ -62,8 +62,7 @@ <!ELEMENT aliases (alias+) > <!-- each alias element specifies an alias for one of the possible values --> <!ELEMENT alias EMPTY > -<!ATTLIST alias value CDATA #REQUIRED - target CDATA #REQUIRED > +<!ATTLIST alias value CDATA #REQUIRED > <!ELEMENT child EMPTY > <!ATTLIST child name CDATA #REQUIRED diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c index f53a02392..18026ae56 100644 --- a/gio/gsettingsbackend.c +++ b/gio/gsettingsbackend.c @@ -122,13 +122,7 @@ is_path (const gchar *path) struct _GSettingsBackendWatch { - /* Always access the target via the weak reference */ - GWeakRef target; - /* The pointer is only for comparison from the weak notify, - * at which point the target might already be close to - * destroyed. It's not safe to use it for anything anymore - * at that point */ - GObject *target_ptr; + GObject *target; const GSettingsListenerVTable *vtable; GMainContext *context; GSettingsBackendWatch *next; @@ -143,7 +137,7 @@ struct _GSettingsBackendClosure gchar **names); GMainContext *context; - GObject *target; + GWeakRef *target_ref; GSettingsBackend *backend; gchar *name; gpointer origin_tag; @@ -160,12 +154,11 @@ g_settings_backend_watch_weak_notify (gpointer data, /* search and remove */ g_mutex_lock (&backend->priv->lock); for (ptr = &backend->priv->watches; *ptr; ptr = &(*ptr)->next) - if ((*ptr)->target_ptr == where_the_object_was) + if ((*ptr)->target == where_the_object_was) { GSettingsBackendWatch *tmp = *ptr; *ptr = tmp->next; - g_weak_ref_clear (&tmp->target); g_slice_free (GSettingsBackendWatch, tmp); g_mutex_unlock (&backend->priv->lock); @@ -215,10 +208,9 @@ g_settings_backend_watch (GSettingsBackend *backend, * GSettings object in a thread other than the one that is doing the * dispatching is as follows: * - * 1) hold a strong reference on the GSettings during an outstanding + * 1) hold a thread-safe GWeakRef on the GSettings during an outstanding * dispatch. This ensures that the delivery is always possible while - * the GSettings object is alive, and if this was the last reference - * then it will be dropped from the dispatch thread. + * the GSettings object is alive. * * 2) hold a weak reference on the GSettings at other times. This * allows us to receive early notification of pending destruction @@ -243,8 +235,7 @@ g_settings_backend_watch (GSettingsBackend *backend, watch = g_slice_new (GSettingsBackendWatch); watch->context = context; watch->vtable = vtable; - g_weak_ref_init (&watch->target, target); - watch->target_ptr = target; + watch->target = target; g_object_weak_ref (target, g_settings_backend_watch_weak_notify, backend); /* linked list prepend */ @@ -269,14 +260,20 @@ static gboolean g_settings_backend_invoke_closure (gpointer user_data) { GSettingsBackendClosure *closure = user_data; + GObject *target = g_weak_ref_get (closure->target_ref); - closure->function (closure->target, closure->backend, closure->name, - closure->origin_tag, closure->names); + if (target) + { + closure->function (target, closure->backend, closure->name, + closure->origin_tag, closure->names); + g_object_unref (target); + } if (closure->context) g_main_context_unref (closure->context); g_object_unref (closure->backend); - g_object_unref (closure->target); + g_weak_ref_clear (closure->target_ref); + g_free (closure->target_ref); g_strfreev (closure->names); g_free (closure->name); @@ -307,18 +304,14 @@ g_settings_backend_dispatch_signal (GSettingsBackend *backend, for (watch = backend->priv->watches; watch; watch = watch->next) { GSettingsBackendClosure *closure; - GObject *target = g_weak_ref_get (&watch->target); - - /* If the target was destroyed in the meantime, just skip it here */ - if (!target) - continue; closure = g_slice_new (GSettingsBackendClosure); closure->context = watch->context; if (closure->context) g_main_context_ref (closure->context); closure->backend = g_object_ref (backend); - closure->target = g_steal_pointer (&target); + closure->target_ref = g_new (GWeakRef, 1); + g_weak_ref_init (closure->target_ref, watch->target); closure->function = G_STRUCT_MEMBER (void *, watch->vtable, function_offset); closure->name = g_strdup (name); diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c index 60b3fe0b3..f7c50c210 100644 --- a/gio/gsettingsschema.c +++ b/gio/gsettingsschema.c @@ -1455,7 +1455,7 @@ gint g_settings_schema_key_to_enum (GSettingsSchemaKey *key, GVariant *value) { - gboolean it_worked; + gboolean it_worked G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; guint result; it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length, @@ -1499,7 +1499,7 @@ g_settings_schema_key_to_flags (GSettingsSchemaKey *key, g_variant_iter_init (&iter, value); while (g_variant_iter_next (&iter, "&s", &flag)) { - gboolean it_worked; + gboolean it_worked G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; guint flag_value; it_worked = strinfo_enum_from_string (key->strinfo, key->strinfo_length, flag, &flag_value); diff --git a/gio/gsocket.c b/gio/gsocket.c index fe869f5fb..d4372c544 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -5748,13 +5748,6 @@ g_socket_receive_message (GSocket *socket, * the %G_IO_ERROR_NOT_SUPPORTED error. On Linux this is implemented * by reading the %SO_PEERCRED option on the underlying socket. * - * This method can be expected to be available on the following platforms: - * - * - Linux since GLib 2.26 - * - OpenBSD since GLib 2.30 - * - Solaris, Illumos and OpenSolaris since GLib 2.40 - * - NetBSD since GLib 2.42 - * * Other ways to obtain credentials from a foreign peer includes the * #GUnixCredentialsMessage type and * g_unix_connection_send_credentials() / diff --git a/gio/gsocketaddressenumerator.c b/gio/gsocketaddressenumerator.c index 3defc7f89..ebbb5decf 100644 --- a/gio/gsocketaddressenumerator.c +++ b/gio/gsocketaddressenumerator.c @@ -30,7 +30,7 @@ * #GSocketAddressEnumerator is an enumerator type for #GSocketAddress * instances. It is returned by enumeration functions such as * g_socket_connectable_enumerate(), which returns a #GSocketAddressEnumerator - * to list all the #GSocketAddresses which could be used to connect to that + * to list each #GSocketAddress which could be used to connect to that * #GSocketConnectable. * * Enumeration is typically a blocking operation, so the asynchronous methods diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c index 81767c0d6..83cb945c7 100644 --- a/gio/gsocketclient.c +++ b/gio/gsocketclient.c @@ -457,7 +457,7 @@ g_socket_client_get_protocol (GSocketClient *client) * The sockets created by this object will use of the specified * protocol. * - * If @protocol is %0 that means to use the default + * If @protocol is %G_SOCKET_PROTOCOL_DEFAULT that means to use the default * protocol for the socket family and type. * * Since: 2.22 @@ -1006,6 +1006,7 @@ g_socket_client_connect (GSocketClient *client, if (g_cancellable_is_cancelled (cancellable)) { g_clear_error (error); + g_clear_error (&last_error); g_cancellable_set_error_if_cancelled (cancellable, error); break; } @@ -1426,24 +1427,15 @@ g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data) data->connection = (GIOStream *)wrapper_connection; } - if (!data->completed) + if (!g_task_return_error_if_cancelled (data->task)) { - GError *error = NULL; - - if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable (data->task), &error)) - { - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); - g_task_return_error (data->task, g_steal_pointer (&error)); - } - else - { - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, data->connection); - g_task_return_pointer (data->task, g_steal_pointer (&data->connection), g_object_unref); - } - - data->completed = TRUE; + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, data->connection); + g_task_return_pointer (data->task, g_steal_pointer (&data->connection), g_object_unref); } + else + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); + data->completed = TRUE; g_object_unref (data->task); } @@ -1615,7 +1607,6 @@ g_socket_client_connected_callback (GObject *source, set_last_error (data, error); connection_attempt_remove (attempt); enumerator_next_async (data, FALSE); - connection_attempt_unref (attempt); } else { diff --git a/gio/gsocketconnectable.c b/gio/gsocketconnectable.c index 76f349faf..e999e659c 100644 --- a/gio/gsocketconnectable.c +++ b/gio/gsocketconnectable.c @@ -121,7 +121,7 @@ g_socket_connectable_enumerate (GSocketConnectable *connectable) * @connectable: a #GSocketConnectable * * Creates a #GSocketAddressEnumerator for @connectable that will - * return #GProxyAddresses for addresses that you must connect + * return a #GProxyAddress for each of its addresses that you must connect * to via a proxy. * * If @connectable does not implement diff --git a/gio/gsocketconnectable.h b/gio/gsocketconnectable.h index 6528d4936..da882143a 100644 --- a/gio/gsocketconnectable.h +++ b/gio/gsocketconnectable.h @@ -35,7 +35,7 @@ G_BEGIN_DECLS /** * GSocketConnectable: * - * Interface for objects that contain or generate #GSocketAddresses. + * Interface for objects that contain or generate a #GSocketAddress. */ typedef struct _GSocketConnectableIface GSocketConnectableIface; diff --git a/gio/gsocketconnection.c b/gio/gsocketconnection.c index 5fab8f4f7..37d5d330c 100644 --- a/gio/gsocketconnection.c +++ b/gio/gsocketconnection.c @@ -389,7 +389,9 @@ g_socket_connection_set_property (GObject *object, static void g_socket_connection_constructed (GObject *object) { +#ifndef G_DISABLE_ASSERT GSocketConnection *connection = G_SOCKET_CONNECTION (object); +#endif g_assert (connection->priv->socket != NULL); } diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c index dcdb84d58..7630c7b45 100644 --- a/gio/gsubprocess.c +++ b/gio/gsubprocess.c @@ -575,7 +575,7 @@ initable_init (GInitable *initable, { guint64 identifier; - gint s; + gint s G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; #ifdef G_OS_WIN32 identifier = (guint64) GetProcessId (self->pid); diff --git a/gio/gthreadedresolver.c b/gio/gthreadedresolver.c index 9b7c396a1..7691b9124 100644 --- a/gio/gthreadedresolver.c +++ b/gio/gthreadedresolver.c @@ -154,11 +154,20 @@ do_lookup_by_name (GTask *task, } else { +#ifdef G_OS_WIN32 + gchar *error_message = g_win32_error_message (WSAGetLastError ()); +#else + gchar *error_message = g_locale_to_utf8 (gai_strerror (retval), -1, NULL, NULL, NULL); + if (error_message == NULL) + error_message = g_strdup ("[Invalid UTF-8]"); +#endif + g_task_return_new_error (task, G_RESOLVER_ERROR, g_resolver_error_from_addrinfo_error (retval), _("Error resolving “%s”: %s"), - hostname, gai_strerror (retval)); + hostname, error_message); + g_free (error_message); } if (res) @@ -310,14 +319,23 @@ do_lookup_by_address (GTask *task, { gchar *phys; +#ifdef G_OS_WIN32 + gchar *error_message = g_win32_error_message (WSAGetLastError ()); +#else + gchar *error_message = g_locale_to_utf8 (gai_strerror (retval), -1, NULL, NULL, NULL); + if (error_message == NULL) + error_message = g_strdup ("[Invalid UTF-8]"); +#endif + phys = g_inet_address_to_string (address); g_task_return_new_error (task, G_RESOLVER_ERROR, g_resolver_error_from_addrinfo_error (retval), _("Error reverse-resolving “%s”: %s"), phys ? phys : "(unknown)", - gai_strerror (retval)); + error_message); g_free (phys); + g_free (error_message); } } diff --git a/gio/gthreadedsocketservice.c b/gio/gthreadedsocketservice.c index e0c111c10..b330196e3 100644 --- a/gio/gthreadedsocketservice.c +++ b/gio/gthreadedsocketservice.c @@ -62,42 +62,45 @@ G_DEFINE_TYPE_WITH_PRIVATE (GThreadedSocketService, g_threaded_socket_service, G_TYPE_SOCKET_SERVICE) -enum +typedef enum { - PROP_0, - PROP_MAX_THREADS -}; + PROP_MAX_THREADS = 1, +} GThreadedSocketServiceProperty; G_LOCK_DEFINE_STATIC(job_count); typedef struct { - GSocketConnection *connection; - GObject *source_object; + GThreadedSocketService *service; /* (owned) */ + GSocketConnection *connection; /* (owned) */ + GObject *source_object; /* (owned) (nullable) */ } GThreadedSocketServiceData; static void -g_threaded_socket_service_func (gpointer _data, - gpointer user_data) +g_threaded_socket_service_data_free (GThreadedSocketServiceData *data) { - GThreadedSocketService *threaded = user_data; - GThreadedSocketServiceData *data = _data; + g_clear_object (&data->service); + g_clear_object (&data->connection); + g_clear_object (&data->source_object); + g_slice_free (GThreadedSocketServiceData, data); +} + +static void +g_threaded_socket_service_func (gpointer job_data, + gpointer user_data) +{ + GThreadedSocketServiceData *data = job_data; gboolean result; - g_signal_emit (threaded, g_threaded_socket_service_run_signal, + g_signal_emit (data->service, g_threaded_socket_service_run_signal, 0, data->connection, data->source_object, &result); - g_object_unref (data->connection); - if (data->source_object) - g_object_unref (data->source_object); - g_slice_free (GThreadedSocketServiceData, data); - G_LOCK (job_count); - if (threaded->priv->job_count-- == threaded->priv->max_threads) - g_socket_service_start (G_SOCKET_SERVICE (threaded)); + if (data->service->priv->job_count-- == data->service->priv->max_threads) + g_socket_service_start (G_SOCKET_SERVICE (data->service)); G_UNLOCK (job_count); - g_object_unref (threaded); + g_threaded_socket_service_data_free (data); } static gboolean @@ -107,28 +110,27 @@ g_threaded_socket_service_incoming (GSocketService *service, { GThreadedSocketService *threaded; GThreadedSocketServiceData *data; + GError *local_error = NULL; threaded = G_THREADED_SOCKET_SERVICE (service); - data = g_slice_new (GThreadedSocketServiceData); - - /* Ref the socket service for the thread */ - g_object_ref (service); - + data = g_slice_new0 (GThreadedSocketServiceData); + data->service = g_object_ref (threaded); data->connection = g_object_ref (connection); - if (source_object) - data->source_object = g_object_ref (source_object); - else - data->source_object = NULL; + data->source_object = (source_object != NULL) ? g_object_ref (source_object) : NULL; G_LOCK (job_count); if (++threaded->priv->job_count == threaded->priv->max_threads) g_socket_service_stop (service); G_UNLOCK (job_count); - g_thread_pool_push (threaded->priv->thread_pool, data, NULL); - + if (!g_thread_pool_push (threaded->priv->thread_pool, data, &local_error)) + { + g_warning ("Error handling incoming socket: %s", local_error->message); + g_threaded_socket_service_data_free (data); + } + g_clear_error (&local_error); return FALSE; } @@ -147,7 +149,7 @@ g_threaded_socket_service_constructed (GObject *object) service->priv->thread_pool = g_thread_pool_new (g_threaded_socket_service_func, - service, + NULL, service->priv->max_threads, FALSE, NULL); @@ -159,6 +161,8 @@ g_threaded_socket_service_finalize (GObject *object) { GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); + /* All jobs in the pool hold a reference to this #GThreadedSocketService, so + * this should only be called once the pool is empty: */ g_thread_pool_free (service->priv->thread_pool, FALSE, FALSE); G_OBJECT_CLASS (g_threaded_socket_service_parent_class) @@ -173,7 +177,7 @@ g_threaded_socket_service_get_property (GObject *object, { GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); - switch (prop_id) + switch ((GThreadedSocketServiceProperty) prop_id) { case PROP_MAX_THREADS: g_value_set_int (value, service->priv->max_threads); @@ -192,7 +196,7 @@ g_threaded_socket_service_set_property (GObject *object, { GThreadedSocketService *service = G_THREADED_SOCKET_SERVICE (object); - switch (prop_id) + switch ((GThreadedSocketServiceProperty) prop_id) { case PROP_MAX_THREADS: service->priv->max_threads = g_value_get_int (value); diff --git a/gio/gtlsdatabase.c b/gio/gtlsdatabase.c index 821af97e0..58da11df3 100644 --- a/gio/gtlsdatabase.c +++ b/gio/gtlsdatabase.c @@ -744,7 +744,7 @@ g_tls_database_lookup_certificate_for_handle_async (GTlsDatabase *sel * @error: a #GError pointer, or %NULL * * Finish an asynchronous lookup of a certificate by its handle. See - * g_tls_database_lookup_certificate_by_handle() for more information. + * g_tls_database_lookup_certificate_for_handle() for more information. * * If the handle is no longer valid, or does not point to a certificate in * this database, then %NULL will be returned. diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c index e9e2f75f0..c85ac3650 100644 --- a/gio/gunixconnection.c +++ b/gio/gunixconnection.c @@ -300,14 +300,6 @@ gboolean g_unix_connection_create_pair (GUnixCo * byte to the stream, as this is required for credentials passing to * work on some implementations. * - * This method can be expected to be available on the following platforms: - * - * - Linux since GLib 2.26 - * - FreeBSD since GLib 2.26 - * - GNU/kFreeBSD since GLib 2.36 - * - Solaris, Illumos and OpenSolaris since GLib 2.40 - * - GNU/Hurd since GLib 2.40 - * * Other ways to exchange credentials with a foreign peer includes the * #GUnixCredentialsMessage type and g_socket_get_credentials() function. * @@ -458,14 +450,6 @@ g_unix_connection_send_credentials_finish (GUnixConnection *connection, * single byte from the stream, as this is required for credentials * passing to work on some implementations. * - * This method can be expected to be available on the following platforms: - * - * - Linux since GLib 2.26 - * - FreeBSD since GLib 2.26 - * - GNU/kFreeBSD since GLib 2.36 - * - Solaris, Illumos and OpenSolaris since GLib 2.40 - * - GNU/Hurd since GLib 2.40 - * * Other ways to exchange credentials with a foreign peer includes the * #GUnixCredentialsMessage type and g_socket_get_credentials() function. * diff --git a/gio/gunixfdlist.c b/gio/gunixfdlist.c index 6cb7df684..e8c4ac55e 100644 --- a/gio/gunixfdlist.c +++ b/gio/gunixfdlist.c @@ -23,7 +23,7 @@ * descriptors that it contains, closing them when finalized. * * It may be wrapped in a #GUnixFDMessage and sent over a #GSocket in - * the %G_SOCKET_ADDRESS_UNIX family by using g_socket_send_message() + * the %G_SOCKET_FAMILY_UNIX family by using g_socket_send_message() * and received using g_socket_receive_message(). * * Note that `<gio/gunixfdlist.h>` belongs to the UNIX-specific GIO diff --git a/gio/gunixfdmessage.c b/gio/gunixfdmessage.c index b80283b0b..3324651f7 100644 --- a/gio/gunixfdmessage.c +++ b/gio/gunixfdmessage.c @@ -22,7 +22,7 @@ * This #GSocketControlMessage contains a #GUnixFDList. * It may be sent using g_socket_send_message() and received using * g_socket_receive_message() over UNIX sockets (ie: sockets in the - * %G_SOCKET_ADDRESS_UNIX family). The file descriptors are copied + * %G_SOCKET_FAMILY_UNIX family). The file descriptors are copied * between processes by the kernel. * * For an easier way to send and receive file descriptors over diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c index cc905f2fc..44a4b113d 100644 --- a/gio/gunixmounts.c +++ b/gio/gunixmounts.c @@ -1552,6 +1552,9 @@ g_unix_mounts_get (guint64 *time_read) * is set, it will be filled with a unix timestamp for checking * if the mounts have changed since with g_unix_mounts_changed_since(). * + * If more mounts have the same mount path, the last matching mount + * is returned. + * * Returns: (transfer full): a #GUnixMountEntry. **/ GUnixMountEntry * @@ -1568,8 +1571,13 @@ g_unix_mount_at (const char *mount_path, { mount_entry = l->data; - if (!found && strcmp (mount_path, mount_entry->mount_path) == 0) - found = mount_entry; + if (strcmp (mount_path, mount_entry->mount_path) == 0) + { + if (found != NULL) + g_unix_mount_free (found); + + found = mount_entry; + } else g_unix_mount_free (mount_entry); } @@ -1587,6 +1595,9 @@ g_unix_mount_at (const char *mount_path, * is set, it will be filled with a unix timestamp for checking * if the mounts have changed since with g_unix_mounts_changed_since(). * + * If more mounts have the same mount path, the last matching mount + * is returned. + * * Returns: (transfer full): a #GUnixMountEntry. * * Since: 2.52 diff --git a/gio/gvfs.c b/gio/gvfs.c index 3475624cf..5805a7904 100644 --- a/gio/gvfs.c +++ b/gio/gvfs.c @@ -236,7 +236,7 @@ g_vfs_get_file_for_uri (GVfs *vfs, const char *uri) { GVfsClass *class; - GFile *ret = NULL; + GFile *ret; g_return_val_if_fail (G_IS_VFS (vfs), NULL); g_return_val_if_fail (uri != NULL, NULL); @@ -244,12 +244,10 @@ g_vfs_get_file_for_uri (GVfs *vfs, class = G_VFS_GET_CLASS (vfs); ret = get_file_for_uri_internal (vfs, uri); - if (!ret) - ret = (* class->get_file_for_uri) (vfs, uri); - - g_assert (ret != NULL); + if (ret) + return ret; - return g_steal_pointer (&ret); + return (* class->get_file_for_uri) (vfs, uri); } /** diff --git a/gio/inotify/ginotifyfilemonitor.c b/gio/inotify/ginotifyfilemonitor.c index 4c95e87fb..b2364cc2c 100644 --- a/gio/inotify/ginotifyfilemonitor.c +++ b/gio/inotify/ginotifyfilemonitor.c @@ -55,7 +55,7 @@ g_inotify_file_monitor_start (GLocalFileMonitor *local_monitor, GFileMonitorSource *source) { GInotifyFileMonitor *inotify_monitor = G_INOTIFY_FILE_MONITOR (local_monitor); - gboolean success; + gboolean success G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; /* should already have been called, from is_supported() */ success = _ih_startup (); @@ -83,7 +83,9 @@ g_inotify_file_monitor_cancel (GFileMonitor *monitor) static void g_inotify_file_monitor_finalize (GObject *object) { +#ifndef G_DISABLE_ASSERT GInotifyFileMonitor *inotify_monitor = G_INOTIFY_FILE_MONITOR (object); +#endif /* must surely have been cancelled already */ g_assert (!inotify_monitor->sub); diff --git a/gio/tests/.gitignore b/gio/tests/.gitignore index 69e02d573..e6c9124a4 100644 --- a/gio/tests/.gitignore +++ b/gio/tests/.gitignore @@ -76,7 +76,7 @@ gdbus-test-codegen-old gdbus-test-fixture gdbus-testserver gdbus-threading -gdbus-unix-addresses +gdbus-address-get-session glistmodel gio-du giomodule diff --git a/gio/tests/actions.c b/gio/tests/actions.c index 1e175c625..3d438fc5d 100644 --- a/gio/tests/actions.c +++ b/gio/tests/actions.c @@ -36,11 +36,11 @@ test_basic (void) GVariant *state; action = g_simple_action_new ("foo", NULL); - g_assert (g_action_get_enabled (G_ACTION (action))); - g_assert (g_action_get_parameter_type (G_ACTION (action)) == NULL); - g_assert (g_action_get_state_type (G_ACTION (action)) == NULL); - g_assert (g_action_get_state_hint (G_ACTION (action)) == NULL); - g_assert (g_action_get_state (G_ACTION (action)) == NULL); + g_assert_true (g_action_get_enabled (G_ACTION (action))); + g_assert_null (g_action_get_parameter_type (G_ACTION (action))); + g_assert_null (g_action_get_state_type (G_ACTION (action))); + g_assert_null (g_action_get_state_hint (G_ACTION (action))); + g_assert_null (g_action_get_state (G_ACTION (action))); g_object_get (action, "name", &name, "parameter-type", ¶meter_type, @@ -49,21 +49,21 @@ test_basic (void) "state", &state, NULL); g_assert_cmpstr (name, ==, "foo"); - g_assert (parameter_type == NULL); - g_assert (enabled); - g_assert (state_type == NULL); - g_assert (state == NULL); + g_assert_null (parameter_type); + g_assert_true (enabled); + g_assert_null (state_type); + g_assert_null (state); g_free (name); g_signal_connect (action, "activate", G_CALLBACK (activate), &a); - g_assert (!a.did_run); + g_assert_false (a.did_run); g_action_activate (G_ACTION (action), NULL); - g_assert (a.did_run); + g_assert_true (a.did_run); a.did_run = FALSE; g_simple_action_set_enabled (action, FALSE); g_action_activate (G_ACTION (action), NULL); - g_assert (!a.did_run); + g_assert_false (a.did_run); if (g_test_undefined ()) { @@ -74,19 +74,19 @@ test_basic (void) } g_object_unref (action); - g_assert (!a.did_run); + g_assert_false (a.did_run); action = g_simple_action_new ("foo", G_VARIANT_TYPE_STRING); - g_assert (g_action_get_enabled (G_ACTION (action))); - g_assert (g_variant_type_equal (g_action_get_parameter_type (G_ACTION (action)), G_VARIANT_TYPE_STRING)); - g_assert (g_action_get_state_type (G_ACTION (action)) == NULL); - g_assert (g_action_get_state_hint (G_ACTION (action)) == NULL); - g_assert (g_action_get_state (G_ACTION (action)) == NULL); + g_assert_true (g_action_get_enabled (G_ACTION (action))); + g_assert_true (g_variant_type_equal (g_action_get_parameter_type (G_ACTION (action)), G_VARIANT_TYPE_STRING)); + g_assert_null (g_action_get_state_type (G_ACTION (action))); + g_assert_null (g_action_get_state_hint (G_ACTION (action))); + g_assert_null (g_action_get_state (G_ACTION (action))); g_signal_connect (action, "activate", G_CALLBACK (activate), &a); - g_assert (!a.did_run); + g_assert_false (a.did_run); g_action_activate (G_ACTION (action), g_variant_new_string ("Hello world")); - g_assert (a.did_run); + g_assert_true (a.did_run); g_assert_cmpstr (g_variant_get_string (a.params, NULL), ==, "Hello world"); g_variant_unref (a.params); a.did_run = FALSE; @@ -100,18 +100,18 @@ test_basic (void) } g_object_unref (action); - g_assert (!a.did_run); + g_assert_false (a.did_run); } static void test_name (void) { - g_assert (!g_action_name_is_valid ("")); - g_assert (!g_action_name_is_valid ("(")); - g_assert (!g_action_name_is_valid ("%abc")); - g_assert (!g_action_name_is_valid ("$x1")); - g_assert (g_action_name_is_valid ("abc.def")); - g_assert (g_action_name_is_valid ("ABC-DEF")); + g_assert_false (g_action_name_is_valid ("")); + g_assert_false (g_action_name_is_valid ("(")); + g_assert_false (g_action_name_is_valid ("%abc")); + g_assert_false (g_action_name_is_valid ("$x1")); + g_assert_true (g_action_name_is_valid ("abc.def")); + g_assert_true (g_action_name_is_valid ("ABC-DEF")); } static gboolean @@ -193,41 +193,41 @@ test_simple_group (void) simple = g_simple_action_new ("foo", NULL); g_signal_connect (simple, "activate", G_CALLBACK (activate), &a); - g_assert (!a.did_run); + g_assert_false (a.did_run); g_action_activate (G_ACTION (simple), NULL); - g_assert (a.did_run); + g_assert_true (a.did_run); a.did_run = FALSE; group = g_simple_action_group_new (); g_simple_action_group_insert (group, G_ACTION (simple)); g_object_unref (simple); - g_assert (!a.did_run); + g_assert_false (a.did_run); g_action_group_activate_action (G_ACTION_GROUP (group), "foo", NULL); - g_assert (a.did_run); + g_assert_true (a.did_run); simple = g_simple_action_new_stateful ("bar", G_VARIANT_TYPE_STRING, g_variant_new_string ("hihi")); g_simple_action_group_insert (group, G_ACTION (simple)); g_object_unref (simple); - g_assert (g_action_group_has_action (G_ACTION_GROUP (group), "foo")); - g_assert (g_action_group_has_action (G_ACTION_GROUP (group), "bar")); - g_assert (!g_action_group_has_action (G_ACTION_GROUP (group), "baz")); + g_assert_true (g_action_group_has_action (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_action_group_has_action (G_ACTION_GROUP (group), "bar")); + g_assert_false (g_action_group_has_action (G_ACTION_GROUP (group), "baz")); actions = g_action_group_list_actions (G_ACTION_GROUP (group)); g_assert_cmpint (g_strv_length (actions), ==, 2); - g_assert (strv_set_equal (actions, "foo", "bar", NULL)); + g_assert_true (strv_set_equal (actions, "foo", "bar", NULL)); g_strfreev (actions); - g_assert (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "foo")); - g_assert (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar")); - g_assert (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "foo") == NULL); - g_assert (g_variant_type_equal (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING)); - g_assert (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "foo") == NULL); - g_assert (g_variant_type_equal (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING)); - g_assert (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "foo") == NULL); - g_assert (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "bar") == NULL); - g_assert (g_action_group_get_action_state (G_ACTION_GROUP (group), "foo") == NULL); + g_assert_true (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar")); + g_assert_null (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_variant_type_equal (g_action_group_get_action_parameter_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING)); + g_assert_null (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "foo")); + g_assert_true (g_variant_type_equal (g_action_group_get_action_state_type (G_ACTION_GROUP (group), "bar"), G_VARIANT_TYPE_STRING)); + g_assert_null (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "foo")); + g_assert_null (g_action_group_get_action_state_hint (G_ACTION_GROUP (group), "bar")); + g_assert_null (g_action_group_get_action_state (G_ACTION_GROUP (group), "foo")); state = g_action_group_get_action_state (G_ACTION_GROUP (group), "bar"); - g_assert (g_variant_type_equal (g_variant_get_type (state), G_VARIANT_TYPE_STRING)); + g_assert_true (g_variant_type_equal (g_variant_get_type (state), G_VARIANT_TYPE_STRING)); g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi"); g_variant_unref (state); @@ -238,13 +238,13 @@ test_simple_group (void) action = g_simple_action_group_lookup (group, "bar"); g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); - g_assert (!g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar")); + g_assert_false (g_action_group_get_action_enabled (G_ACTION_GROUP (group), "bar")); g_simple_action_group_remove (group, "bar"); action = g_simple_action_group_lookup (group, "foo"); g_assert_cmpstr (g_action_get_name (action), ==, "foo"); action = g_simple_action_group_lookup (group, "bar"); - g_assert (action == NULL); + g_assert_null (action); simple = g_simple_action_new ("foo", NULL); g_simple_action_group_insert (group, G_ACTION (simple)); @@ -252,7 +252,7 @@ test_simple_group (void) a.did_run = FALSE; g_object_unref (group); - g_assert (!a.did_run); + g_assert_false (a.did_run); } G_GNUC_END_IGNORE_DEPRECATIONS @@ -264,11 +264,11 @@ test_stateful (void) GVariant *state; action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_string ("hihi")); - g_assert (g_action_get_enabled (G_ACTION (action))); - g_assert (g_action_get_parameter_type (G_ACTION (action)) == NULL); - g_assert (g_action_get_state_hint (G_ACTION (action)) == NULL); - g_assert (g_variant_type_equal (g_action_get_state_type (G_ACTION (action)), - G_VARIANT_TYPE_STRING)); + g_assert_true (g_action_get_enabled (G_ACTION (action))); + g_assert_null (g_action_get_parameter_type (G_ACTION (action))); + g_assert_null (g_action_get_state_hint (G_ACTION (action))); + g_assert_true (g_variant_type_equal (g_action_get_state_type (G_ACTION (action)), + G_VARIANT_TYPE_STRING)); state = g_action_get_state (G_ACTION (action)); g_assert_cmpstr (g_variant_get_string (state, NULL), ==, "hihi"); g_variant_unref (state); @@ -319,12 +319,12 @@ test_default_activate (void) action = g_simple_action_new_stateful ("foo", NULL, g_variant_new_boolean (FALSE)); g_action_activate (G_ACTION (action), NULL); state = g_action_get_state (G_ACTION (action)); - g_assert (g_variant_get_boolean (state)); + g_assert_true (g_variant_get_boolean (state)); g_variant_unref (state); /* and back again */ g_action_activate (G_ACTION (action), NULL); state = g_action_get_state (G_ACTION (action)); - g_assert (!g_variant_get_boolean (state)); + g_assert_false (g_variant_get_boolean (state)); g_variant_unref (state); g_object_unref (action); } @@ -337,8 +337,8 @@ activate_foo (GSimpleAction *simple, GVariant *parameter, gpointer user_data) { - g_assert (user_data == GINT_TO_POINTER (123)); - g_assert (parameter == NULL); + g_assert_true (user_data == GINT_TO_POINTER (123)); + g_assert_null (parameter); foo_activated = TRUE; } @@ -347,7 +347,7 @@ activate_bar (GSimpleAction *simple, GVariant *parameter, gpointer user_data) { - g_assert (user_data == GINT_TO_POINTER (123)); + g_assert_true (user_data == GINT_TO_POINTER (123)); g_assert_cmpstr (g_variant_get_string (parameter, NULL), ==, "param"); bar_activated = TRUE; } @@ -385,16 +385,16 @@ test_entries (void) G_N_ELEMENTS (entries), GINT_TO_POINTER (123)); - g_assert (!foo_activated); + g_assert_false (foo_activated); g_action_group_activate_action (G_ACTION_GROUP (actions), "foo", NULL); - g_assert (foo_activated); + g_assert_true (foo_activated); foo_activated = FALSE; - g_assert (!bar_activated); + g_assert_false (bar_activated); g_action_group_activate_action (G_ACTION_GROUP (actions), "bar", g_variant_new_string ("param")); - g_assert (bar_activated); - g_assert (!foo_activated); + g_assert_true (bar_activated); + g_assert_false (foo_activated); if (g_test_undefined ()) { @@ -478,7 +478,7 @@ test_parse_detailed (void) gchar *name; success = g_action_parse_detailed_name (testcases[i].detailed, &name, &target, &error); - g_assert (success == (error == NULL)); + g_assert_true (success == (error == NULL)); if (success && testcases[i].expected_error) g_error ("Unexpected success on '%s'. Expected error containing '%s'", testcases[i].detailed, testcases[i].expected_error); @@ -497,7 +497,7 @@ test_parse_detailed (void) } g_assert_cmpstr (name, ==, testcases[i].expected_name); - g_assert ((target == NULL) == (testcases[i].expected_target == NULL)); + g_assert_true ((target == NULL) == (testcases[i].expected_target == NULL)); if (success) { @@ -513,7 +513,7 @@ test_parse_detailed (void) GVariant *expected; expected = g_variant_parse (NULL, testcases[i].expected_target, NULL, NULL, NULL); - g_assert (expected); + g_assert_true (expected); g_assert_cmpvariant (expected, target); g_variant_unref (expected); @@ -659,7 +659,7 @@ list_cb (GObject *source, gchar **actions; v = g_dbus_connection_call_finish (bus, res, &error); - g_assert (v); + g_assert_nonnull (v); g_variant_get (v, "(^a&s)", &actions); g_assert_cmpint (g_strv_length (actions), ==, G_N_ELEMENTS (exported_entries)); g_free (actions); @@ -704,10 +704,10 @@ describe_cb (GObject *source, GVariantIter *iter; v = g_dbus_connection_call_finish (bus, res, &error); - g_assert (v); + g_assert_nonnull (v); /* FIXME: there's an extra level of tuplelization in here */ g_variant_get (v, "((bgav))", &enabled, ¶m, &iter); - g_assert (enabled == TRUE); + g_assert_true (enabled); g_assert_cmpstr (param, ==, ""); g_assert_cmpint (g_variant_iter_n_children (iter), ==, 0); g_free (param); @@ -791,8 +791,8 @@ test_dbus_export (void) g_main_loop_run (loop); /* test that the initial transfer works */ - g_assert (G_IS_DBUS_ACTION_GROUP (proxy)); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (G_IS_DBUS_ACTION_GROUP (proxy)); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); /* test that various changes get propagated from group to proxy */ action = g_simple_action_new_stateful ("italic", NULL, g_variant_new_boolean (FALSE)); @@ -802,7 +802,7 @@ test_dbus_export (void) g_timeout_add (100, stop_loop, loop); g_main_loop_run (loop); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "cut")); g_simple_action_set_enabled (action, FALSE); @@ -810,7 +810,7 @@ test_dbus_export (void) g_timeout_add (100, stop_loop, loop); g_main_loop_run (loop); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); action = G_SIMPLE_ACTION (g_simple_action_group_lookup (group, "bold")); g_simple_action_set_state (action, g_variant_new_boolean (FALSE)); @@ -818,14 +818,14 @@ test_dbus_export (void) g_timeout_add (100, stop_loop, loop); g_main_loop_run (loop); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); g_simple_action_group_remove (group, "italic"); g_timeout_add (100, stop_loop, loop); g_main_loop_run (loop); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); /* test that activations and state changes propagate the other way */ @@ -836,7 +836,7 @@ test_dbus_export (void) g_main_loop_run (loop); g_assert_cmpint (activation_count ("copy"), ==, 1); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); g_assert_cmpint (activation_count ("bold"), ==, 0); g_action_group_activate_action (G_ACTION_GROUP (proxy), "bold", NULL); @@ -845,9 +845,9 @@ test_dbus_export (void) g_main_loop_run (loop); g_assert_cmpint (activation_count ("bold"), ==, 1); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold"); - g_assert (g_variant_get_boolean (v)); + g_assert_true (g_variant_get_boolean (v)); g_variant_unref (v); g_action_group_change_action_state (G_ACTION_GROUP (proxy), "bold", g_variant_new_boolean (FALSE)); @@ -856,9 +856,9 @@ test_dbus_export (void) g_main_loop_run (loop); g_assert_cmpint (activation_count ("bold"), ==, 1); - g_assert (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); + g_assert_true (compare_action_groups (G_ACTION_GROUP (group), G_ACTION_GROUP (proxy))); v = g_action_group_get_action_state (G_ACTION_GROUP (group), "bold"); - g_assert (!g_variant_get_boolean (v)); + g_assert_false (g_variant_get_boolean (v)); g_variant_unref (v); g_dbus_connection_unexport_action_group (bus, id); @@ -980,7 +980,7 @@ state_changed (GActionGroup *group, { GString *string; - g_assert (!state_change_log); + g_assert_false (state_change_log); string = g_string_new (action_name); g_string_append_c (string, ':'); @@ -1038,7 +1038,7 @@ test_property_actions (void) action = g_property_action_new ("keepalive", app, "inactivity-timeout"); g_object_get (action, "name", &name, "parameter-type", &ptype, "enabled", &enabled, "state-type", &stype, "state", &state, NULL); g_assert_cmpstr (name, ==, "keepalive"); - g_assert (enabled); + g_assert_true (enabled); g_free (name); g_variant_type_free (ptype); g_variant_type_free (stype); @@ -1112,24 +1112,24 @@ test_property_actions (void) /* bool tests */ g_action_group_change_action_state (G_ACTION_GROUP (group), "tls", g_variant_new ("b", TRUE)); verify_changed ("tls:true"); - g_assert (g_socket_client_get_tls (client)); + g_assert_true (g_socket_client_get_tls (client)); ensure_state (group, "tls", "true"); g_action_group_change_action_state (G_ACTION_GROUP (group), "disable-proxy", g_variant_new ("b", TRUE)); verify_changed ("disable-proxy:true"); ensure_state (group, "disable-proxy", "true"); - g_assert (!g_socket_client_get_enable_proxy (client)); + g_assert_false (g_socket_client_get_enable_proxy (client)); /* test toggle true->false */ g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL); verify_changed ("tls:false"); - g_assert (!g_socket_client_get_tls (client)); + g_assert_false (g_socket_client_get_tls (client)); ensure_state (group, "tls", "false"); /* and now back false->true */ g_action_group_activate_action (G_ACTION_GROUP (group), "tls", NULL); verify_changed ("tls:true"); - g_assert (g_socket_client_get_tls (client)); + g_assert_true (g_socket_client_get_tls (client)); ensure_state (group, "tls", "true"); g_socket_client_set_tls (client, FALSE); @@ -1139,12 +1139,12 @@ test_property_actions (void) /* now do the same for the inverted action */ g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL); verify_changed ("disable-proxy:false"); - g_assert (g_socket_client_get_enable_proxy (client)); + g_assert_true (g_socket_client_get_enable_proxy (client)); ensure_state (group, "disable-proxy", "false"); g_action_group_activate_action (G_ACTION_GROUP (group), "disable-proxy", NULL); verify_changed ("disable-proxy:true"); - g_assert (!g_socket_client_get_enable_proxy (client)); + g_assert_false (g_socket_client_get_enable_proxy (client)); ensure_state (group, "disable-proxy", "true"); g_socket_client_set_enable_proxy (client, TRUE); diff --git a/gio/tests/cancellable.c b/gio/tests/cancellable.c index e06650ed8..044628228 100644 --- a/gio/tests/cancellable.c +++ b/gio/tests/cancellable.c @@ -216,12 +216,19 @@ test_cancel_multiple_concurrent (void) g_main_loop_unref (loop); } +static void +test_cancel_null (void) +{ + g_cancellable_cancel (NULL); +} + int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/cancellable/multiple-concurrent", test_cancel_multiple_concurrent); + g_test_add_func ("/cancellable/null", test_cancel_null); return g_test_run (); } diff --git a/gio/tests/dbus-launch.c b/gio/tests/dbus-launch.c index 90d8d069e..ef5721941 100644 --- a/gio/tests/dbus-launch.c +++ b/gio/tests/dbus-launch.c @@ -1,5 +1,5 @@ /* - * Mock version of dbus-launch, for gdbus-unix-addresses test + * Mock version of dbus-launch, for gdbus-address-get-session test * * Copyright © 2015 Collabora Ltd. * diff --git a/gio/tests/file.c b/gio/tests/file.c index 658d17549..efb2eaadd 100644 --- a/gio/tests/file.c +++ b/gio/tests/file.c @@ -523,6 +523,11 @@ test_create_delete (gconstpointer d) g_free (data); } +static const gchar *original_data = + "/**\n" + " * g_file_replace_contents_async:\n" + "**/\n"; + static const gchar *replace_data = "/**\n" " * g_file_replace_contents_async:\n" @@ -675,7 +680,8 @@ test_replace_cancel (void) GFileInfo *info; GCancellable *cancellable; gchar *path; - gsize nwrote; + gchar *contents; + gsize nwrote, length; guint count; GError *error = NULL; @@ -688,8 +694,8 @@ test_replace_cancel (void) file = g_file_get_child (tmpdir, "file"); g_file_replace_contents (file, - replace_data, - strlen (replace_data), + original_data, + strlen (original_data), NULL, FALSE, 0, NULL, NULL, &error); g_assert_no_error (error); @@ -777,6 +783,17 @@ test_replace_cancel (void) g_object_unref (cancellable); g_object_unref (ostream); + /* Make sure that file contents wasn't actually replaced. */ + g_file_load_contents (file, + NULL, + &contents, + &length, + NULL, + &error); + g_assert_no_error (error); + g_assert_cmpstr (contents, ==, original_data); + g_free (contents); + g_file_delete (file, NULL, &error); g_assert_no_error (error); g_object_unref (file); diff --git a/gio/tests/g-file-info.c b/gio/tests/g-file-info.c index 28a2426a8..f21d1b7e2 100644 --- a/gio/tests/g-file-info.c +++ b/gio/tests/g-file-info.c @@ -291,10 +291,10 @@ test_internal_enhanced_stdio (void) ft_programdata = g_file_info_get_file_type (fi_programdata); ft_commondata = g_file_info_get_file_type (fi_commondata); - g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_SYMBOLIC_LINK); + g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_DIRECTORY); g_assert_cmpint (ft_allusers_target, ==, G_FILE_TYPE_DIRECTORY); g_assert_cmpint (ft_programdata, ==, G_FILE_TYPE_DIRECTORY); - g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_SYMBOLIC_LINK); + g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_DIRECTORY); allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK); allusers_reparse_tag = g_file_info_get_attribute_uint32 (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG); diff --git a/gio/tests/gdbus-unix-addresses.c b/gio/tests/gdbus-address-get-session.c index 531ce7a85..72de2c79f 100644 --- a/gio/tests/gdbus-unix-addresses.c +++ b/gio/tests/gdbus-address-get-session.c @@ -18,9 +18,12 @@ #include <glib.h> -#ifndef G_OS_UNIX -#error This is a Unix-specific test -#endif +/* This test does NOT depend on any dbus binaries preinstalled on test host. + * On Unix it uses mock environment (test_xdg_runtime) + * or mock dbus-launch binary (test_x11_autolaunch). + * On Windows it relies on the fact that libgio provides + * internal session dbus-server on win32. + */ #include <errno.h> @@ -43,6 +46,8 @@ print_address (void) g_free (addr); } +#ifdef G_OS_UNIX + static GSocket *mock_bus = NULL; static gchar *mock_bus_path = NULL; /* this is deliberately something that needs escaping */ @@ -166,14 +171,57 @@ test_xdg_runtime (void) g_test_trap_assert_passed (); } +#endif + +#ifdef G_OS_WIN32 +static void +check_and_cleanup_autolaunched_win32_bus (void) +{ + /* win32 autostarted bus runs infinitely if no client ever connected. + * However it exits in several seconds if the last client disconnects. + * _This_ test only checks successful launching and connectivity, + * and don't bother on bus termination behavior (being it a bug or not). + * So connect+disconnect here is not only connectivity test, + * but also the workaround the bus process infinite run. + */ + GError *err = NULL; + GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &err); + g_assert_no_error (err); + g_object_unref (bus); +} + +static void +test_win32_autolaunch (void) +{ + if (g_test_subprocess ()) + { + print_address (); + + check_and_cleanup_autolaunched_win32_bus (); + return; + } + + g_test_trap_subprocess (NULL, 0, 0); + /* stderr is not checked: coverage prints warnings there */ + g_test_trap_assert_stdout ("nonce-tcp:host=localhost,port=*,noncefile=*\\gdbus-nonce-file-*\n"); + g_test_trap_assert_passed (); +} +#endif + int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); +#ifdef G_OS_UNIX g_test_add_func ("/gdbus/x11-autolaunch", test_x11_autolaunch); g_test_add_func ("/gdbus/xdg-runtime", test_xdg_runtime); +#endif + +#ifdef G_OS_WIN32 + g_test_add_func ("/gdbus/win32-autolaunch", test_win32_autolaunch); +#endif - return g_test_run(); + return g_test_run (); } diff --git a/gio/tests/gdbus-addresses.c b/gio/tests/gdbus-addresses.c index 0ab05661a..d6a5c2360 100644 --- a/gio/tests/gdbus-addresses.c +++ b/gio/tests/gdbus-addresses.c @@ -39,11 +39,25 @@ test_empty_address (void) g_error_free (error); } +/* Test that g_dbus_is_supported_address() returns FALSE for an unparseable + * address. */ +static void +test_unsupported_address (void) +{ + GError *error = NULL; + + g_assert_false (g_dbus_is_supported_address (";", &error)); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); + g_clear_error (&error); +} + static void assert_is_supported_address (const gchar *address) { GError *error = NULL; + g_assert_true (g_dbus_is_address (address)); + g_assert_true (g_dbus_is_supported_address (address, NULL)); g_assert_true (g_dbus_is_supported_address (address, &error)); g_assert_no_error (error); @@ -54,30 +68,57 @@ assert_not_supported_address (const gchar *address) { GError *error = NULL; + g_assert_true (g_dbus_is_address (address)); + g_assert_false (g_dbus_is_supported_address (address, NULL)); g_assert_false (g_dbus_is_supported_address (address, &error)); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); g_clear_error (&error); } -#ifdef G_OS_UNIX +/* Test that g_dbus_is_address() returns FALSE for various differently invalid + * input strings. */ static void -test_unix_address (void) +test_address_parsing (void) { assert_not_supported_address ("some-imaginary-transport:foo=bar"); + g_assert_true (g_dbus_is_address ("some-imaginary-transport:foo=bar")); + + assert_not_supported_address ("some-imaginary-transport:foo=bar;unix:path=/this/is/valid"); + + g_assert_false (g_dbus_is_address ("")); + g_assert_false (g_dbus_is_address (";")); + g_assert_false (g_dbus_is_address (":")); + g_assert_false (g_dbus_is_address ("=:;")); + g_assert_false (g_dbus_is_address (":=;:=")); + g_assert_false (g_dbus_is_address ("transport-name:=")); + g_assert_false (g_dbus_is_address ("transport-name:=bar")); + + g_assert_false (g_dbus_is_address ("transport-name:foo")); + g_assert_false (g_dbus_is_address ("transport-name:foo=%00")); + g_assert_false (g_dbus_is_address ("transport-name:%00=bar")); + + assert_not_supported_address ("magic-tractor:"); +} + +static void +test_unix_address (void) +{ +#ifndef G_OS_UNIX + g_test_skip ("unix transport is not supported on non-Unix platforms"); +#else assert_is_supported_address ("unix:path=/tmp/dbus-test"); assert_is_supported_address ("unix:abstract=/tmp/dbus-another-test"); - g_assert (g_dbus_is_address ("unix:foo=bar")); assert_not_supported_address ("unix:foo=bar"); - g_assert (!g_dbus_is_address ("unix:path=/foo;abstract=/bar")); - assert_not_supported_address ("unix:path=/foo;abstract=/bar"); + g_assert_false (g_dbus_is_address ("unix:path=/foo;abstract=/bar")); assert_is_supported_address ("unix:path=/tmp/concrete;unix:abstract=/tmp/abstract"); - g_assert (g_dbus_is_address ("some-imaginary-transport:foo=bar")); - - g_assert (g_dbus_is_address ("some-imaginary-transport:foo=bar;unix:path=/this/is/valid")); - assert_not_supported_address ("some-imaginary-transport:foo=bar;unix:path=/this/is/valid"); -} + assert_is_supported_address ("unix:tmpdir=/tmp"); + assert_not_supported_address ("unix:tmpdir=/tmp,path=/tmp"); + assert_not_supported_address ("unix:tmpdir=/tmp,abstract=/tmp/foo"); + assert_not_supported_address ("unix:path=/tmp,abstract=/tmp/foo"); + assert_not_supported_address ("unix:"); #endif +} static void test_nonce_tcp_address (void) @@ -85,12 +126,18 @@ test_nonce_tcp_address (void) assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar"); assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv6"); assert_is_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=ipv4"); + assert_is_supported_address ("nonce-tcp:host=localhost"); assert_not_supported_address ("nonce-tcp:host=localhost,port=42,noncefile=/foo/bar,family=blah"); assert_not_supported_address ("nonce-tcp:host=localhost,port=420000,noncefile=/foo/bar,family=ipv4"); assert_not_supported_address ("nonce-tcp:host=,port=x42,noncefile=/foo/bar,family=ipv4"); assert_not_supported_address ("nonce-tcp:host=,port=42x,noncefile=/foo/bar,family=ipv4"); assert_not_supported_address ("nonce-tcp:host=,port=420000,noncefile=/foo/bar,family=ipv4"); + assert_not_supported_address ("nonce-tcp:meaningless-key=blah"); + assert_not_supported_address ("nonce-tcp:host=localhost,port=-1"); + assert_not_supported_address ("nonce-tcp:host=localhost,port=420000"); + assert_not_supported_address ("nonce-tcp:host=localhost,port=42x"); + assert_not_supported_address ("nonce-tcp:host=localhost,port="); } static void @@ -102,6 +149,7 @@ test_tcp_address (void) assert_not_supported_address ("tcp:host=localhost,port=-1"); assert_not_supported_address ("tcp:host=localhost,port=420000"); assert_not_supported_address ("tcp:host=localhost,port=42x"); + assert_not_supported_address ("tcp:host=localhost,port="); assert_is_supported_address ("tcp:host=localhost,port=42,family=ipv4"); assert_is_supported_address ("tcp:host=localhost,port=42,family=ipv6"); assert_not_supported_address ("tcp:host=localhost,port=42,family=sopranos"); @@ -151,9 +199,9 @@ main (int argc, g_test_init (&argc, &argv, NULL); g_test_add_func ("/gdbus/empty-address", test_empty_address); -#ifdef G_OS_UNIX + g_test_add_func ("/gdbus/unsupported-address", test_unsupported_address); + g_test_add_func ("/gdbus/address-parsing", test_address_parsing); g_test_add_func ("/gdbus/unix-address", test_unix_address); -#endif g_test_add_func ("/gdbus/nonce-tcp-address", test_nonce_tcp_address); g_test_add_func ("/gdbus/tcp-address", test_tcp_address); g_test_add_func ("/gdbus/autolaunch-address", test_autolaunch_address); diff --git a/gio/tests/gdbus-example-peer.c b/gio/tests/gdbus-example-peer.c index 9d5de32a6..bf151cfcf 100755 --- a/gio/tests/gdbus-example-peer.c +++ b/gio/tests/gdbus-example-peer.c @@ -169,74 +169,6 @@ on_new_connection (GDBusServer *server, /* ---------------------------------------------------------------------------------------------------- */ -static gboolean -allow_mechanism_cb (GDBusAuthObserver *observer, - const gchar *mechanism, - G_GNUC_UNUSED gpointer user_data) -{ - /* - * In a production GDBusServer that only needs to work on modern Unix - * platforms, consider requiring EXTERNAL (credentials-passing), - * which is the recommended authentication mechanism for AF_UNIX - * sockets: - * - * if (g_strcmp0 (mechanism, "EXTERNAL") == 0) - * return TRUE; - * - * return FALSE; - * - * For this example we accept everything. - */ - - g_print ("Considering whether to accept %s authentication...\n", mechanism); - return TRUE; -} - -static gboolean -authorize_authenticated_peer_cb (GDBusAuthObserver *observer, - G_GNUC_UNUSED GIOStream *stream, - GCredentials *credentials, - G_GNUC_UNUSED gpointer user_data) -{ - gboolean authorized = FALSE; - - g_print ("Considering whether to authorize authenticated peer...\n"); - - if (credentials != NULL) - { - GCredentials *own_credentials; - gchar *credentials_string = NULL; - - credentials_string = g_credentials_to_string (credentials); - g_print ("Peer's credentials: %s\n", credentials_string); - g_free (credentials_string); - - own_credentials = g_credentials_new (); - - credentials_string = g_credentials_to_string (own_credentials); - g_print ("Server's credentials: %s\n", credentials_string); - g_free (credentials_string); - - if (g_credentials_is_same_user (credentials, own_credentials, NULL)) - authorized = TRUE; - - g_object_unref (own_credentials); - } - - if (!authorized) - { - /* In most servers you'd want to reject this, but for this example - * we allow it. */ - g_print ("A server would often not want to authorize this identity\n"); - g_print ("Authorizing it anyway for demonstration purposes\n"); - authorized = TRUE; - } - - return authorized; -} - -/* ---------------------------------------------------------------------------------------------------- */ - int main (int argc, char *argv[]) { @@ -289,7 +221,6 @@ main (int argc, char *argv[]) if (opt_server) { - GDBusAuthObserver *observer; GDBusServer *server; gchar *guid; GMainLoop *loop; @@ -301,20 +232,14 @@ main (int argc, char *argv[]) if (opt_allow_anonymous) server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS; - observer = g_dbus_auth_observer_new (); - g_signal_connect (observer, "allow-mechanism", G_CALLBACK (allow_mechanism_cb), NULL); - g_signal_connect (observer, "authorize-authenticated-peer", G_CALLBACK (authorize_authenticated_peer_cb), NULL); - error = NULL; server = g_dbus_server_new_sync (opt_address, server_flags, guid, - observer, + NULL, /* GDBusAuthObserver */ NULL, /* GCancellable */ &error); g_dbus_server_start (server); - - g_object_unref (observer); g_free (guid); if (server == NULL) diff --git a/gio/tests/gdbus-proxy.c b/gio/tests/gdbus-proxy.c index 6e092f42b..05b22ea1c 100644 --- a/gio/tests/gdbus-proxy.c +++ b/gio/tests/gdbus-proxy.c @@ -49,7 +49,7 @@ test_methods (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "(s)"); g_variant_get (result, "(&s)", &str); g_assert_cmpstr (str, ==, "You greeted me with 'Hey'. Thanks!"); @@ -64,13 +64,13 @@ test_methods (GDBusProxy *proxy) NULL, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR); - g_assert (g_dbus_error_is_remote_error (error)); - g_assert (g_dbus_error_is_remote_error (error)); - g_assert (result == NULL); + g_assert_true (g_dbus_error_is_remote_error (error)); + g_assert_true (g_dbus_error_is_remote_error (error)); + g_assert_null (result); dbus_error_name = g_dbus_error_get_remote_error (error); g_assert_cmpstr (dbus_error_name, ==, "com.example.TestException"); g_free (dbus_error_name); - g_assert (g_dbus_error_strip_remote_error (error)); + g_assert_true (g_dbus_error_strip_remote_error (error)); g_assert_cmpstr (error->message, ==, "Yo is not a proper greeting"); g_clear_error (&error); @@ -88,8 +88,8 @@ test_methods (GDBusProxy *proxy) NULL, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); - g_assert (!g_dbus_error_is_remote_error (error)); - g_assert (result == NULL); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_assert_null (result); g_clear_error (&error); /* Check that proxy-default timeouts work. */ @@ -104,7 +104,7 @@ test_methods (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); @@ -121,8 +121,8 @@ test_methods (GDBusProxy *proxy) NULL, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT); - g_assert (!g_dbus_error_is_remote_error (error)); - g_assert (result == NULL); + g_assert_false (g_dbus_error_is_remote_error (error)); + g_assert_null (result); g_clear_error (&error); /* clean up after ourselves */ @@ -179,7 +179,7 @@ test_properties (GDBusProxy *proxy) if (g_dbus_proxy_get_flags (proxy) & G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES) { - g_assert (g_dbus_proxy_get_cached_property_names (proxy) == NULL); + g_assert_null (g_dbus_proxy_get_cached_property_names (proxy)); return; } @@ -188,32 +188,32 @@ test_properties (GDBusProxy *proxy) */ names = g_dbus_proxy_get_cached_property_names (proxy); - g_assert (strv_equal (names, - "PropertyThatWillBeInvalidated", - "ab", - "ad", - "ai", - "an", - "ao", - "aq", - "as", - "at", - "au", - "ax", - "ay", - "b", - "d", - "foo", - "i", - "n", - "o", - "q", - "s", - "t", - "u", - "x", - "y", - NULL)); + g_assert_true (strv_equal (names, + "PropertyThatWillBeInvalidated", + "ab", + "ad", + "ai", + "an", + "ao", + "aq", + "as", + "at", + "au", + "ax", + "ay", + "b", + "d", + "foo", + "i", + "n", + "o", + "q", + "s", + "t", + "u", + "x", + "y", + NULL)); g_strfreev (names); @@ -223,11 +223,11 @@ test_properties (GDBusProxy *proxy) * No need to test all properties - GVariant has already been tested */ variant = g_dbus_proxy_get_cached_property (proxy, "y"); - g_assert (variant != NULL); + g_assert_nonnull (variant); g_assert_cmpint (g_variant_get_byte (variant), ==, 1); g_variant_unref (variant); variant = g_dbus_proxy_get_cached_property (proxy, "o"); - g_assert (variant != NULL); + g_assert_nonnull (variant); g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "/some/path"); g_variant_unref (variant); @@ -246,31 +246,31 @@ test_properties (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); _g_assert_signal_received (proxy, "g-properties-changed"); variant = g_dbus_proxy_get_cached_property (proxy, "y"); - g_assert (variant != NULL); + g_assert_nonnull (variant); g_assert_cmpint (g_variant_get_byte (variant), ==, 42); g_variant_unref (variant); g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_byte (142)); variant = g_dbus_proxy_get_cached_property (proxy, "y"); - g_assert (variant != NULL); + g_assert_nonnull (variant); g_assert_cmpint (g_variant_get_byte (variant), ==, 142); g_variant_unref (variant); g_dbus_proxy_set_cached_property (proxy, "y", NULL); variant = g_dbus_proxy_get_cached_property (proxy, "y"); - g_assert (variant == NULL); + g_assert_null (variant); /* Check that the invalidation feature of the PropertiesChanged() * signal works... First, check that we have a cached value of the * property (from the initial GetAll() call) */ variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated"); - g_assert (variant != NULL); + g_assert_nonnull (variant); g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "InitialValue"); g_variant_unref (variant); /* now ask to invalidate the property - this causes a @@ -292,14 +292,14 @@ test_properties (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); /* ... hence we wait for the g-properties-changed signal to be delivered */ _g_assert_signal_received (proxy, "g-properties-changed"); /* ... and now we finally, check that the cached value has been invalidated */ variant = g_dbus_proxy_get_cached_property (proxy, "PropertyThatWillBeInvalidated"); - g_assert (variant == NULL); + g_assert_null (variant); /* Now test that G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES works - we need a new proxy for that */ error = NULL; @@ -314,11 +314,11 @@ test_properties (GDBusProxy *proxy) g_assert_no_error (error); name_owner = g_dbus_proxy_get_name_owner (proxy2); - g_assert (name_owner != NULL); + g_assert_nonnull (name_owner); g_free (name_owner); variant = g_dbus_proxy_get_cached_property (proxy2, "PropertyThatWillBeInvalidated"); - g_assert (variant != NULL); + g_assert_nonnull (variant); g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "OMGInvalidated"); /* from previous test */ g_variant_unref (variant); @@ -330,7 +330,7 @@ test_properties (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); @@ -338,7 +338,7 @@ test_properties (GDBusProxy *proxy) _g_assert_signal_received (proxy2, "g-properties-changed"); variant = g_dbus_proxy_get_cached_property (proxy2, "PropertyThatWillBeInvalidated"); - g_assert (variant != NULL); + g_assert_nonnull (variant); g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "OMGInvalidated2"); g_variant_unref (variant); @@ -384,12 +384,12 @@ test_proxy_signals_on_emit_signal_cb (GDBusProxy *proxy, res, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); /* check that the signal was recieved before we got the method result */ - g_assert (strlen (data->s->str) > 0); + g_assert_cmpuint (strlen (data->s->str), >, 0); /* break out of the loop */ g_main_loop_quit (data->internal_loop); @@ -428,11 +428,11 @@ test_signals (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); /* check that we haven't received the signal just yet */ - g_assert (strlen (s->str) == 0); + g_assert_cmpuint (strlen (s->str), ==, 0); /* and now wait for the signal */ _g_assert_signal_received (proxy, "g-signal"); g_assert_cmpstr (s->str, @@ -487,7 +487,7 @@ test_bogus_method_return (GDBusProxy *proxy) &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); g_error_free (error); - g_assert (result == NULL); + g_assert_null (result); } #if 0 /* Disabled: see https://bugzilla.gnome.org/show_bug.cgi?id=658999 */ @@ -506,7 +506,7 @@ test_bogus_signal (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); @@ -546,7 +546,7 @@ test_bogus_property (GDBusProxy *proxy) NULL, &error); g_assert_no_error (error); - g_assert (result != NULL); + g_assert_nonnull (result); g_assert_cmpstr (g_variant_get_type_string (result), ==, "()"); g_variant_unref (result); @@ -626,7 +626,9 @@ test_expected_interface (GDBusProxy *proxy) /* Also check that we complain if setting a cached property of the wrong type */ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*Trying to set property y of type s but according to the expected interface the type is y*"); - g_dbus_proxy_set_cached_property (proxy, "y", g_variant_new_string ("error_me_out!")); + value = g_variant_ref_sink (g_variant_new_string ("error_me_out!")); + g_dbus_proxy_set_cached_property (proxy, "y", value); + g_variant_unref (value); g_test_assert_expected_messages (); } @@ -652,16 +654,16 @@ test_expected_interface (GDBusProxy *proxy) * See https://bugzilla.gnome.org/show_bug.cgi?id=660886 */ value = g_dbus_proxy_get_cached_property (proxy, "d"); - g_assert (value != NULL); - g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); + g_assert_nonnull (value); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); g_assert_cmpfloat (g_variant_get_double (value), ==, 7.5); g_variant_unref (value); /* update it via the cached property... */ g_dbus_proxy_set_cached_property (proxy, "d", g_variant_new_double (75.0)); /* ... and finally check that it has changed */ value = g_dbus_proxy_get_cached_property (proxy, "d"); - g_assert (value != NULL); - g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); + g_assert_nonnull (value); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); g_assert_cmpfloat (g_variant_get_double (value), ==, 75.0); g_variant_unref (value); /* now update it via the D-Bus interface... */ @@ -671,15 +673,15 @@ test_expected_interface (GDBusProxy *proxy) G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_assert_no_error (error); - g_assert (value != NULL); + g_assert_nonnull (value); g_assert_cmpstr (g_variant_get_type_string (value), ==, "()"); g_variant_unref (value); /* ...ensure we receive the ::PropertiesChanged signal... */ _g_assert_signal_received (proxy, "g-properties-changed"); /* ... and finally check that it has changed */ value = g_dbus_proxy_get_cached_property (proxy, "d"); - g_assert (value != NULL); - g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); + g_assert_nonnull (value); + g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE_DOUBLE)); g_assert_cmpfloat (g_variant_get_double (value), ==, 85.0); g_variant_unref (value); } @@ -698,9 +700,9 @@ test_basic (GDBusProxy *proxy) connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); - g_assert (g_dbus_proxy_get_connection (proxy) == connection); - g_assert (g_dbus_proxy_get_flags (proxy) == G_DBUS_PROXY_FLAGS_NONE); - g_assert (g_dbus_proxy_get_interface_info (proxy) == NULL); + g_assert_true (g_dbus_proxy_get_connection (proxy) == connection); + g_assert_cmpint (g_dbus_proxy_get_flags (proxy), ==, G_DBUS_PROXY_FLAGS_NONE); + g_assert_null (g_dbus_proxy_get_interface_info (proxy)); g_assert_cmpstr (g_dbus_proxy_get_name (proxy), ==, "com.example.TestService"); g_assert_cmpstr (g_dbus_proxy_get_object_path (proxy), ==, "/com/example/TestObject"); g_assert_cmpstr (g_dbus_proxy_get_interface_name (proxy), ==, "com.example.Frob"); @@ -716,8 +718,8 @@ test_basic (GDBusProxy *proxy) "g-default-timeout", &timeout, NULL); - g_assert (conn == connection); - g_assert (info == NULL); + g_assert_true (conn == connection); + g_assert_null (info); g_assert_cmpint (flags, ==, G_DBUS_PROXY_FLAGS_NONE); g_assert_cmpstr (name, ==, "com.example.TestService"); g_assert_cmpstr (path, ==, "/com/example/TestObject"); @@ -785,7 +787,7 @@ test_proxy (void) g_assert_no_error (error); /* this is safe; we explicitly kill the service later on */ - g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); _g_assert_property_notify (proxy, "g-name-owner"); @@ -827,7 +829,7 @@ proxy_ready (GObject *source, g_free (owner); /* this is safe; we explicitly kill the service later on */ - g_assert (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); + g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL)); _g_assert_property_notify (proxy, "g-name-owner"); @@ -901,7 +903,7 @@ check_error (GObject *source, reply = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED); - g_assert (reply == NULL); + g_assert_null (reply); g_error_free (error); g_main_loop_quit (loop); @@ -919,7 +921,7 @@ test_wellknown_noauto (void) NULL, "some.name.that.does.not.exist", "/", "some.interface", NULL, &error); g_assert_no_error (error); - g_assert (proxy != NULL); + g_assert_nonnull (proxy); g_dbus_proxy_call (proxy, "method", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, check_error, NULL); id = g_timeout_add (10000, fail_test, NULL); @@ -938,7 +940,7 @@ main (int argc, g_test_init (&argc, &argv, NULL); introspection_data = g_dbus_node_info_new_for_xml (frob_dbus_interface_xml, NULL); - g_assert (introspection_data != NULL); + g_assert_nonnull (introspection_data); frob_dbus_interface_info = introspection_data->interfaces[0]; /* all the tests rely on a shared main loop */ @@ -952,6 +954,7 @@ main (int argc, ret = session_bus_run(); g_dbus_node_info_unref (introspection_data); + g_main_loop_unref (loop); return ret; } diff --git a/gio/tests/gdbus-test-codegen.c b/gio/tests/gdbus-test-codegen.c index 8db555781..985cb1095 100644 --- a/gio/tests/gdbus-test-codegen.c +++ b/gio/tests/gdbus-test-codegen.c @@ -583,10 +583,8 @@ on_name_acquired (GDBusConnection *connection, gpointer user_data) { GMainLoop *loop = user_data; - - g_thread_new ("check-proxies", - check_proxies_in_thread, - loop); + GThread *thread = g_thread_new ("check-proxies", check_proxies_in_thread, loop); + g_thread_unref (thread); } static void diff --git a/gio/tests/gdbus-testserver.c b/gio/tests/gdbus-testserver.c index 7f99a1946..dd0d5ba5a 100644 --- a/gio/tests/gdbus-testserver.c +++ b/gio/tests/gdbus-testserver.c @@ -884,6 +884,7 @@ main (int argc, char *argv[]) g_bus_unown_name (owner_id); g_dbus_node_info_unref (introspection_data); + g_hash_table_unref (properties); return 0; } diff --git a/gio/tests/gmenumodel.c b/gio/tests/gmenumodel.c index 53e701360..fc0fcea48 100644 --- a/gio/tests/gmenumodel.c +++ b/gio/tests/gmenumodel.c @@ -752,11 +752,11 @@ typedef struct GDBusServer *server; GThread *service_thread; + /* Protects server_connection and service_loop. */ GMutex service_loop_lock; GCond service_loop_cond; GMainLoop *service_loop; - GMainLoop *loop; } PeerConnection; static gboolean @@ -766,9 +766,10 @@ on_new_connection (GDBusServer *server, { PeerConnection *data = user_data; + g_mutex_lock (&data->service_loop_lock); data->server_connection = g_object_ref (connection); - - g_main_loop_quit (data->loop); + g_cond_broadcast (&data->service_loop_cond); + g_mutex_unlock (&data->service_loop_lock); return TRUE; } @@ -801,6 +802,15 @@ await_service_loop (PeerConnection *data) g_mutex_unlock (&data->service_loop_lock); } +static void +await_server_connection (PeerConnection *data) +{ + g_mutex_lock (&data->service_loop_lock); + while (data->server_connection == NULL) + g_cond_wait (&data->service_loop_cond, &data->service_loop_lock); + g_mutex_unlock (&data->service_loop_lock); +} + static gpointer service_thread_func (gpointer user_data) { @@ -874,7 +884,6 @@ peer_connection_up (PeerConnection *data) GError *error; memset (data, '\0', sizeof (PeerConnection)); - data->loop = g_main_loop_new (NULL, FALSE); g_mutex_init (&data->service_loop_lock); g_cond_init (&data->service_loop_cond); @@ -897,8 +906,7 @@ peer_connection_up (PeerConnection *data) &error); g_assert_no_error (error); g_assert (data->client_connection != NULL); - while (data->server_connection == NULL) - g_main_loop_run (data->loop); + await_server_connection (data); } static void @@ -915,8 +923,6 @@ peer_connection_down (PeerConnection *data) g_mutex_clear (&data->service_loop_lock); g_cond_clear (&data->service_loop_cond); - - g_main_loop_unref (data->loop); } struct roundtrip_state diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c index f0b36b764..52b06a2e6 100644 --- a/gio/tests/gsubprocess.c +++ b/gio/tests/gsubprocess.c @@ -73,11 +73,11 @@ test_noop (void) g_ptr_array_free (args, TRUE); g_assert_no_error (local_error); id = g_subprocess_get_identifier (proc); - g_assert (id != NULL); + g_assert_nonnull (id); g_subprocess_wait_check (proc, NULL, error); g_assert_no_error (local_error); - g_assert (g_subprocess_get_successful (proc)); + g_assert_true (g_subprocess_get_successful (proc)); g_object_unref (proc); } @@ -93,7 +93,7 @@ check_ready (GObject *source, ret = g_subprocess_wait_check_finish (G_SUBPROCESS (source), res, &error); - g_assert (ret); + g_assert_true (ret); g_assert_no_error (error); g_object_unref (source); @@ -218,7 +218,7 @@ test_exit1_cancel_wait_check_cb (GObject *source, data->cb_called = TRUE; ret = g_subprocess_wait_check_finish (subprocess, result, &error); - g_assert (!ret); + g_assert_false (ret); g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); g_clear_error (&error); @@ -271,7 +271,7 @@ test_exit1_cancel_in_cb_wait_check_cb (GObject *source, data->cb_called = TRUE; ret = g_subprocess_wait_check_finish (subprocess, result, &error); - g_assert (!ret); + g_assert_false (ret); g_assert_error (error, G_SPAWN_EXIT_ERROR, 1); g_clear_error (&error); @@ -501,7 +501,7 @@ test_cat_eof (void) /* Spawn 'cat' */ cat = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error, "cat", NULL); g_assert_no_error (error); - g_assert (cat); + g_assert_nonnull (cat); /* Make sure that reading stdout blocks (until we cancel) */ cancellable = g_cancellable_new (); @@ -515,19 +515,19 @@ test_cat_eof (void) /* Close the stream (EOF on cat's stdin) */ result = g_output_stream_close (g_subprocess_get_stdin_pipe (cat), NULL, &error); g_assert_no_error (error); - g_assert (result); + g_assert_true (result); /* Now check that reading cat's stdout gets us an EOF (since it quit) */ s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, NULL, &error); g_assert_no_error (error); - g_assert (!s); + g_assert_false (s); /* Check that the process has exited as a result of the EOF */ result = g_subprocess_wait (cat, NULL, &error); g_assert_no_error (error); - g_assert (g_subprocess_get_if_exited (cat)); + g_assert_true (g_subprocess_get_if_exited (cat)); g_assert_cmpint (g_subprocess_get_exit_status (cat), ==, 0); - g_assert (result); + g_assert_true (result); g_object_unref (cat); } @@ -686,7 +686,7 @@ test_multi_1 (void) g_main_loop_run (data.loop); - g_assert (!data.caught_error); + g_assert_false (data.caught_error); g_assert_no_error (data.error); g_assert_cmpint (g_memory_output_stream_get_data_size ((GMemoryOutputStream*)membuf), ==, SPLICELEN); @@ -1279,11 +1279,11 @@ on_request_quit_exited (GObject *object, g_subprocess_wait_finish (subprocess, result, &error); g_assert_no_error (error); #ifdef G_OS_UNIX - g_assert (g_subprocess_get_if_signaled (subprocess)); - g_assert (g_subprocess_get_term_sig (subprocess) == 9); + g_assert_true (g_subprocess_get_if_signaled (subprocess)); + g_assert_cmpint (g_subprocess_get_term_sig (subprocess), ==, 9); #endif g_spawn_check_exit_status (g_subprocess_get_status (subprocess), &error); - g_assert (error != NULL); + g_assert_nonnull (error); g_clear_error (&error); g_main_loop_quit ((GMainLoop*)user_data); @@ -1473,7 +1473,7 @@ test_cwd (void) result = splice_to_string (stdout_stream, error); basename = g_strrstr (result, G_DIR_SEPARATOR_S); - g_assert (basename != NULL); + g_assert_nonnull (basename); g_assert_cmpstr (basename, ==, tmp_lineend_basename); g_free (tmp_lineend); @@ -1726,7 +1726,7 @@ test_launcher_environment (void) args = get_test_subprocess_args ("printenv", "A", "C", "E", NULL); proc = g_subprocess_launcher_spawnv (launcher, (const gchar **) args->pdata, &error); g_assert_no_error (error); - g_assert (proc); + g_assert_nonnull (proc); g_subprocess_communicate_utf8 (proc, NULL, NULL, &out, NULL, &error); g_assert_no_error (error); diff --git a/gio/tests/meson.build b/gio/tests/meson.build index 65f43e267..f13458181 100644 --- a/gio/tests/meson.build +++ b/gio/tests/meson.build @@ -10,6 +10,7 @@ test_c_args = [ '-DTEST_SERVICES="@0@/gio/tests/services"'.format(meson.build_root()), '-DGLIB_MKENUMS="@0@"'.format(glib_mkenums), '-DGLIB_COMPILE_SCHEMAS="@0@"'.format(glib_compile_schemas.full_path()), + '-UG_DISABLE_ASSERT', ] if host_machine.system() == 'windows' @@ -78,6 +79,7 @@ gio_tests = { 'tls-certificate' : {'extra_sources' : ['gtesttlsbackend.c']}, 'tls-interaction' : {'extra_sources' : ['gtesttlsbackend.c']}, 'tls-database' : {'extra_sources' : ['gtesttlsbackend.c']}, + 'gdbus-address-get-session' : {}, } test_extra_programs = { @@ -134,27 +136,32 @@ if host_machine.system() != 'windows' 'unix-mounts' : {}, 'unix-streams' : {}, 'g-file-info-filesystem-readonly' : {}, - 'gsocketclient-slow' : { - 'depends' : [ - shared_library('slow-connect-preload', - 'slow-connect-preload.c', - name_prefix : '', - dependencies: cc.find_library('dl'), - install_dir : installed_tests_execdir, - install: installed_tests_enabled, - ) - ], - 'env' : { - 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(meson.current_build_dir()) - }, - 'installed_tests_env' : { - 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(installed_tests_execdir), - }, - }, 'gschema-compile' : {'install' : false}, 'trash' : {}, } + if have_rtld_next + gio_tests += { + 'gsocketclient-slow' : { + 'depends' : [ + shared_library('slow-connect-preload', + 'slow-connect-preload.c', + name_prefix : '', + dependencies: cc.find_library('dl'), + install_dir : installed_tests_execdir, + install: installed_tests_enabled, + ) + ], + 'env' : { + 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(meson.current_build_dir()) + }, + 'installed_tests_env' : { + 'LD_PRELOAD': '@0@/slow-connect-preload.so'.format(installed_tests_execdir), + }, + }, + } + endif + # Uninstalled because of the check-for-executable logic in DesktopAppInfo # unable to find the installed executable if not glib_have_cocoa @@ -241,10 +248,10 @@ if host_machine.system() != 'windows' 'extra_sources' : extra_sources, 'suite' : ['slow'], }, - 'gdbus-auth' : {'extra_sources' : extra_sources, 'suite': ['flaky']}, - 'gdbus-bz627724' : {'extra_sources' : extra_sources, 'suite': ['flaky']}, + 'gdbus-auth' : {'extra_sources' : extra_sources}, + 'gdbus-bz627724' : {'extra_sources' : extra_sources}, 'gdbus-close-pending' : {'extra_sources' : extra_sources}, - 'gdbus-connection' : {'extra_sources' : extra_sources, 'suite': ['flaky']}, + 'gdbus-connection' : {'extra_sources' : extra_sources}, 'gdbus-connection-loss' : {'extra_sources' : extra_sources}, 'gdbus-connection-slow' : {'extra_sources' : extra_sources}, 'gdbus-error' : {'extra_sources' : extra_sources}, @@ -283,7 +290,6 @@ if host_machine.system() != 'windows' '-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_36'], }, 'gapplication' : {'extra_sources' : extra_sources}, - 'gdbus-unix-addresses' : {}, } if not glib_have_cocoa diff --git a/gio/tests/network-address.c b/gio/tests/network-address.c index 395734b1b..c62afccd2 100644 --- a/gio/tests/network-address.c +++ b/gio/tests/network-address.c @@ -426,9 +426,7 @@ typedef struct { } AsyncData; static void -got_addr (GObject *source_object, - GAsyncResult *result, - gpointer user_data) +got_addr (GObject *source_object, GAsyncResult *result, gpointer user_data) { GSocketAddressEnumerator *enumerator; AsyncData *data; @@ -468,30 +466,6 @@ got_addr (GObject *source_object, } static void -got_addr_ignored (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -{ - GSocketAddressEnumerator *enumerator; - GSocketAddress *a; /* owned */ - GError *error = NULL; - - /* This function simply ignores the returned addresses but keeps enumerating */ - - enumerator = G_SOCKET_ADDRESS_ENUMERATOR (source_object); - - a = g_socket_address_enumerator_next_finish (enumerator, result, &error); - g_assert_no_error (error); - if (a != NULL) - { - g_object_unref (a); - g_socket_address_enumerator_next_async (enumerator, NULL, - got_addr_ignored, user_data); - } -} - - -static void test_loopback_async (void) { GSocketConnectable *addr; /* owned */ @@ -673,39 +647,6 @@ test_happy_eyeballs_basic (HappyEyeballsFixture *fixture, } static void -test_happy_eyeballs_parallel (HappyEyeballsFixture *fixture, - gconstpointer user_data) -{ - AsyncData data = { 0 }; - GSocketAddressEnumerator *enumerator2; - - enumerator2 = g_socket_connectable_enumerate (fixture->addr); - - data.delay_ms = FAST_DELAY_LESS_THAN_TIMEOUT; - data.loop = fixture->loop; - - /* We run multiple enumerations at once, the results shouldn't be affected. */ - - g_socket_address_enumerator_next_async (enumerator2, NULL, got_addr_ignored, &data); - g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); - g_main_loop_run (fixture->loop); - - assert_list_matches_expected (data.addrs, fixture->input_all_results); - - /* Run again to ensure the cache from the previous one is correct */ - - data.addrs = NULL; - g_object_unref (enumerator2); - - enumerator2 = g_socket_connectable_enumerate (fixture->addr); - g_socket_address_enumerator_next_async (enumerator2, NULL, got_addr, &data); - g_main_loop_run (fixture->loop); - - assert_list_matches_expected (data.addrs, fixture->input_all_results); - g_object_unref (enumerator2); -} - -static void test_happy_eyeballs_slow_ipv4 (HappyEyeballsFixture *fixture, gconstpointer user_data) { @@ -820,30 +761,6 @@ test_happy_eyeballs_ipv6_error_ipv6_first (HappyEyeballsFixture *fixture, } static void -test_happy_eyeballs_ipv6_error_ipv4_very_slow (HappyEyeballsFixture *fixture, - gconstpointer user_data) -{ - AsyncData data = { 0 }; - GError *ipv6_error; - - g_test_bug ("merge_requests/865"); - - /* If ipv6 fails, ensuring that ipv6 errors before ipv4 finishes, we still get ipv4. */ - - data.loop = fixture->loop; - ipv6_error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_TIMED_OUT, "IPv6 Broken"); - mock_resolver_set_ipv6_error (fixture->mock_resolver, ipv6_error); - mock_resolver_set_ipv4_delay_ms (fixture->mock_resolver, SLOW_DELAY_MORE_THAN_TIMEOUT); - - g_socket_address_enumerator_next_async (fixture->enumerator, NULL, got_addr, &data); - g_main_loop_run (fixture->loop); - - assert_list_matches_expected (data.addrs, fixture->input_ipv4_results); - - g_error_free (ipv6_error); -} - -static void test_happy_eyeballs_ipv4_error_ipv4_first (HappyEyeballsFixture *fixture, gconstpointer user_data) { @@ -1001,7 +918,6 @@ main (int argc, char *argv[]) gchar *path; g_test_init (&argc, &argv, NULL); - g_test_bug_base ("https://gitlab.gnome.org/GNOME/glib/"); g_test_add_func ("/network-address/basic", test_basic); @@ -1042,8 +958,6 @@ main (int argc, char *argv[]) g_test_add ("/network-address/happy-eyeballs/basic", HappyEyeballsFixture, NULL, happy_eyeballs_setup, test_happy_eyeballs_basic, happy_eyeballs_teardown); - g_test_add ("/network-address/happy-eyeballs/parallel", HappyEyeballsFixture, NULL, - happy_eyeballs_setup, test_happy_eyeballs_parallel, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/slow-ipv4", HappyEyeballsFixture, NULL, happy_eyeballs_setup, test_happy_eyeballs_slow_ipv4, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/slow-ipv6", HappyEyeballsFixture, NULL, @@ -1056,8 +970,6 @@ main (int argc, char *argv[]) happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv4_first, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/ipv6-error-ipv6-first", HappyEyeballsFixture, NULL, happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv6_first, happy_eyeballs_teardown); - g_test_add ("/network-address/happy-eyeballs/ipv6-error-ipv4-very-slow", HappyEyeballsFixture, NULL, - happy_eyeballs_setup, test_happy_eyeballs_ipv6_error_ipv4_very_slow, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/ipv4-error-ipv6-first", HappyEyeballsFixture, NULL, happy_eyeballs_setup, test_happy_eyeballs_ipv4_error_ipv6_first, happy_eyeballs_teardown); g_test_add ("/network-address/happy-eyeballs/ipv4-error-ipv4-first", HappyEyeballsFixture, NULL, diff --git a/gio/tests/task.c b/gio/tests/task.c index 9f7ae2563..9b2c6912c 100644 --- a/gio/tests/task.c +++ b/gio/tests/task.c @@ -1317,6 +1317,7 @@ test_run_in_thread_nested (void) * tasks, they won't all run at once. */ static GMutex overflow_mutex; +static guint overflow_completed; static void run_overflow_task_thread (GTask *task, @@ -1329,16 +1330,19 @@ run_overflow_task_thread (GTask *task, if (g_task_return_error_if_cancelled (task)) { *result = 'X'; - return; } + else + { + /* Block until the main thread is ready. */ + g_mutex_lock (&overflow_mutex); + g_mutex_unlock (&overflow_mutex); - /* Block until the main thread is ready. */ - g_mutex_lock (&overflow_mutex); - g_mutex_unlock (&overflow_mutex); + *result = '.'; - *result = '.'; + g_task_return_boolean (task, TRUE); + } - g_task_return_boolean (task, TRUE); + g_atomic_int_inc (&overflow_completed); } #define NUM_OVERFLOW_TASKS 1024 @@ -1382,9 +1386,11 @@ test_run_in_thread_overflow (void) g_mutex_unlock (&overflow_mutex); /* Wait for all tasks to complete. */ - while (strlen (buf) != NUM_OVERFLOW_TASKS) + while (g_atomic_int_get (&overflow_completed) != NUM_OVERFLOW_TASKS) g_usleep (1000); + g_assert_cmpint (strlen (buf), ==, NUM_OVERFLOW_TASKS); + i = strspn (buf, "."); /* Given the sleep times above, i should be 14 for normal, 40 for * slow. But if the machine is too slow/busy then the scheduling diff --git a/gio/win32/gwinhttpfile.c b/gio/win32/gwinhttpfile.c index d6acab7b8..d5df16d91 100644 --- a/gio/win32/gwinhttpfile.c +++ b/gio/win32/gwinhttpfile.c @@ -80,7 +80,7 @@ g_winhttp_file_init (GWinHttpFile *winhttp) * @vfs: GWinHttpVfs to use * @uri: URI of the GWinHttpFile to create. * - * Returns: (nullable): new winhttp #GFile, or %NULL if there was an error constructing it. + * Returns: new winhttp #GFile. */ GFile * _g_winhttp_file_new (GWinHttpVfs *vfs, diff --git a/gio/win32/gwinhttpvfs.c b/gio/win32/gwinhttpvfs.c index 91d7fed9d..038368f81 100644 --- a/gio/win32/gwinhttpvfs.c +++ b/gio/win32/gwinhttpvfs.c @@ -165,25 +165,15 @@ g_winhttp_vfs_get_file_for_uri (GVfs *vfs, { GWinHttpVfs *winhttp_vfs = G_WINHTTP_VFS (vfs); int i; - GFile *ret = NULL; /* If it matches one of "our" schemes, handle it */ for (i = 0; i < G_N_ELEMENTS (winhttp_uri_schemes); i++) - { - if (g_ascii_strncasecmp (uri, winhttp_uri_schemes[i], strlen (winhttp_uri_schemes[i])) == 0 && - uri[strlen (winhttp_uri_schemes[i])] == ':') - { - ret = _g_winhttp_file_new (winhttp_vfs, uri); - } - } + if (g_ascii_strncasecmp (uri, winhttp_uri_schemes[i], strlen (winhttp_uri_schemes[i])) == 0 && + uri[strlen (winhttp_uri_schemes[i])] == ':') + return _g_winhttp_file_new (winhttp_vfs, uri); /* For other URIs fallback to the wrapped GVfs */ - if (ret == NULL) - ret = g_vfs_get_file_for_uri (winhttp_vfs->wrapped_vfs, uri); - - g_assert (ret != NULL); - - return g_steal_pointer (&ret); + return g_vfs_get_file_for_uri (winhttp_vfs->wrapped_vfs, uri); } static const gchar * const * |