Update to 2.73.3 and drop gdesktopappinfo patch

Unfortunatenly, the gdesktopappinfo patch rebase requires some effort.
This patch will need to be integrated upstream rather than carried in
Fedora indefinitely.
This commit is contained in:
Michael Catanzaro 2022-08-26 13:24:43 -05:00
parent aba250710a
commit 11e5538af6
6 changed files with 2 additions and 1022 deletions

View File

@ -1,40 +0,0 @@
From b62745fe8e1699473f87caff328ac2c6ce394c55 Mon Sep 17 00:00:00 2001
From: Christian Hergert <chergert@redhat.com>
Date: Tue, 2 Aug 2022 12:35:40 -0700
Subject: [PATCH] gmain: close pidfd when finalizing GChildWatchSource
A file-descriptor was created with the introduction of pidfd_getfd() but
nothing is closing it when the source finalizes. The GChildWatchSource is
the creator and consumer of this FD and therefore responsible for closing
it on finalization.
The pidfd leak was introduced in !2408.
This fixes issues with Builder where anon_inode:[pidfd] exhaust the
available FD limit for the process.
Fixes #2708
---
glib/gmain.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/glib/gmain.c b/glib/gmain.c
index a6f9b168e..dba5f40e4 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -5804,7 +5804,11 @@ g_child_watch_finalize (GSource *source)
GChildWatchSource *child_watch_source = (GChildWatchSource *) source;
if (child_watch_source->using_pidfd)
- return;
+ {
+ if (child_watch_source->poll.fd >= 0)
+ close (child_watch_source->poll.fd);
+ return;
+ }
G_LOCK (unix_signal_lock);
unix_child_watches = g_slist_remove (unix_child_watches, source);
--
2.37.1

View File

@ -1,70 +0,0 @@
From 6535c77b00a444750148d9d658e4d47214bb4562 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
Date: Mon, 25 Jul 2022 16:48:03 +0200
Subject: [PATCH 1/2] gregex: do not set match and recursion limits on match
context
These are not really necessary, and cause breakages (e.g. #2700).
pcre2_set_recursion_limit is also deprecated.
Fixes: #2700
---
glib/gregex.c | 2 --
glib/tests/regex.c | 3 +++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 6741d2479f..dd61dc4813 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -769,8 +769,6 @@ match_info_new (const GRegex *regex,
&match_info->n_subpatterns);
match_info->match_context = pcre2_match_context_create (NULL);
- pcre2_set_match_limit (match_info->match_context, 65536); /* should be plenty */
- pcre2_set_recursion_limit (match_info->match_context, 64); /* should be plenty */
if (is_dfa)
{
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index bb1a5ff762..5839465fae 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -2493,6 +2493,9 @@ main (int argc, char *argv[])
TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "dž", -1, 0, 0, TRUE);
TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "Dž", -1, 0, 0, TRUE);
+ /* see https://gitlab.gnome.org/GNOME/glib/-/issues/2700 */
+ TEST_MATCH("(\n.+)+", G_REGEX_DEFAULT, 0, "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", -1, 0, 0, TRUE);
+
/* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */
TEST_MATCH_NEXT0("a", "x", -1, 0);
TEST_MATCH_NEXT0("a", "ax", -1, 1);
--
GitLab
From a2b5b9e906256f43b0bac702424613ea0e7ddcb0 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
Date: Mon, 25 Jul 2022 16:57:06 +0200
Subject: [PATCH 2/2] gregex: add original test case for issue #2700
---
glib/tests/regex.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 5839465fae..acb082b704 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -2495,6 +2495,7 @@ main (int argc, char *argv[])
/* see https://gitlab.gnome.org/GNOME/glib/-/issues/2700 */
TEST_MATCH("(\n.+)+", G_REGEX_DEFAULT, 0, "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", -1, 0, 0, TRUE);
+ TEST_MATCH("\n([\\-\\.a-zA-Z]+[\\-\\.0-9]*) +connected ([^(\n ]*)[^\n]*((\n +[0-9]+x[0-9]+[^\n]+)+)", G_REGEX_DEFAULT, 0, "Screen 0: minimum 1 x 1, current 3840 x 1080, maximum 8192 x 8192\nVirtual1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 0mm x 0mm\n 1920x1080 60.00*+ 59.96 \n 3840x2400 59.97 \n 3840x2160 59.97 \n 2880x1800 59.95 \n 2560x1600 59.99 \n 2560x1440 59.95 \n 1920x1440 60.00 \n 1856x1392 60.00 \n 1792x1344 60.00 \n 1920x1200 59.88 \n 1600x1200 60.00 \n 1680x1050 59.95 \n 1400x1050 59.98 \n 1280x1024 60.02 \n 1440x900 59.89 \n 1280x960 60.00 \n 1360x768 60.02 \n 1280x800 59.81 \n 1152x864 75.00 \n 1280x768 59.87 \n 1280x720 59.86 \n 1024x768 60.00 \n 800x600 60.32 \n 640x480 59.94 \nVirtual2 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 0mm x 0mm\n 1920x1080 60.00*+ 59.96 \n 3840x2400 59.97 \n 3840x2160 59.97 \n 2880x1800 59.95 \n 2560x1600 59.99 \n 2560x1440 59.95 \n 1920x1440 60.00 \n 1856x1392 60.00 \n 1792x1344 60.00 \n 1920x1200 59.88 \n 1600x1200 60.00 \n 1680x1050 59.95 \n 1400x1050 59.98 \n 1280x1024 60.02 \n 1440x900 59.89 \n 1280x960 60.00 \n 1360x768 60.02 \n 1280x800 59.81 \n 1152x864 75.00 \n 1280x768 59.87 \n 1280x720 59.86 \n 1024x768 60.00 \n 800x600 60.32 \n 640x480 59.94 \nVirtual3 disconnected (normal left inverted right x axis y axis)\nVirtual4 disconnected (normal left inverted right x axis y axis)\nVirtual5 disconnected (normal left inverted right x axis y axis)\nVirtual6 disconnected (normal left inverted right x axis y axis)\nVirtual7 disconnected (normal left inverted right x axis y axis)\nVirtual8 disconnected (normal left inverted right x axis y axis)\n", -1, 0, 0, TRUE);
/* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */
TEST_MATCH_NEXT0("a", "x", -1, 0);
--
GitLab

View File

@ -1,31 +0,0 @@
From 710ccee65c010e4548ded487cdc191658f6a1f35 Mon Sep 17 00:00:00 2001
From: Mamoru TASAKA <mtasaka@fedoraproject.org>
Date: Tue, 26 Jul 2022 21:51:45 +0900
Subject: [PATCH] gregex: use correct size for pcre2_pattern_info
man pcre2_pattern_info says that the 3rd argument must
point to uint32_t variable (except for some 2nd argument value),
so correctly use it. Especially using wrong size can cause
unexpected result on big endian.
closes: #2699
---
glib/gregex.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index dd61dc4813..08c43ef4b5 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -1701,7 +1701,7 @@ regex_compile (const gchar *pattern,
PCRE2_SIZE erroffset;
gint errcode;
GRegexCompileFlags nonpcre_compile_options;
- unsigned long int pcre_compile_options;
+ uint32_t pcre_compile_options;
nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK;
--
GitLab

View File

@ -1,864 +0,0 @@
From 19f690a7aa6a942b804a7e13aedff38066cb0a8b Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Fri, 23 Oct 2020 18:20:01 +0200
Subject: [PATCH 1/4] tests: Iterate mainloop during launch test
When launching an application, we wait for the DBus response from
systemd before executing the binary. Because of this the main loop needs
to be iterated for spawning to completed and the file to be created.
Without this the test will time out if GLib was able to connect to the
session bus.
---
gio/tests/desktop-app-info.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/tests/desktop-app-info.c b/gio/tests/desktop-app-info.c
index 6d3f4e853..9d3166075 100644
--- a/gio/tests/desktop-app-info.c
+++ b/gio/tests/desktop-app-info.c
@@ -532,6 +532,7 @@ wait_for_file (const gchar *want_this,
*/
while (access (want_this, F_OK) != 0)
{
+ g_main_context_iteration (NULL, FALSE);
g_usleep (100000); /* 100ms */
g_assert_cmpuint (retries, >, 0);
retries--;
--
2.36.1
From 517d565fd1b0b0ac6a1b480153ee1440dd37974c Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Mon, 27 Jul 2020 22:22:32 +0200
Subject: [PATCH 2/4] gdesktopappinfo: Move launched applications into
transient scope
Try to move the spawned executable into its own systemd scope. To avoid
possible race conditions and ensure proper accounting, we delay the
execution of the real command until after the DBus call to systemd has
finished.
From the two approaches we can take here, this is better in the sense
that we have a child that the API consumer can watch. API consumers
should not be doing this, however, gnome-session needs to watch children
during session startup. Until gnome-session is fixed, we will not be
able to change this.
The alternative approach is to delegate launching itself to systemd by
creating a transient .service unit instead. This is cleaner and has e.g.
the advantage that systemd will take care of log redirection and similar
issues.
Note that this patch is incomplete. The DBus call is done in a "fire and
forget" manner, which is fine in most cases, but means that "gio open"
will fail to move the child into the new scope as gio quits before the
DBus call finishes.
---
gio/gdesktopappinfo.c | 264 ++++++++++++++++++++++++++++++++++++------
1 file changed, 227 insertions(+), 37 deletions(-)
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index c0950ae75..570e49e57 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -2827,6 +2827,148 @@ emit_launch_started (GAppLaunchContext *context,
#define _SPAWN_FLAGS_DEFAULT (G_SPAWN_SEARCH_PATH)
+#if defined(__linux__) && !defined(__BIONIC__)
+typedef struct {
+ int pipe[2];
+ GSpawnChildSetupFunc user_setup;
+ gpointer user_setup_data;
+} SpawnWrapperData;
+
+static void
+launch_uris_with_spawn_delay_exec (gpointer user_data)
+{
+ SpawnWrapperData *data = user_data;
+
+ /* Clear CLOEXEC again, as that was set due to
+ * G_SPAWN_LEAVE_DESCRIPTORS_OPEN not being set. */
+ fcntl (data->pipe[0], F_SETFD, 0);
+
+ /* No need to close read side, we have CLOEXEC set. */
+
+ if (data->user_setup)
+ data->user_setup (data->user_setup_data);
+}
+
+static gchar *
+systemd_unit_name_escape (const gchar *in)
+{
+ /* Adapted from systemd source */
+ GString * const str = g_string_sized_new (strlen (in));
+
+ for (; *in; in++)
+ {
+ if (g_ascii_isalnum (*in) || *in == ':' || *in == '_' || *in == '.')
+ g_string_append_c (str, *in);
+ else
+ g_string_append_printf (str, "\\x%02x", *in);
+ }
+ return g_string_free (str, FALSE);
+}
+
+static void
+create_systemd_scope (GDBusConnection *session_bus,
+ GDesktopAppInfo *info,
+ gint pid,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GVariantBuilder builder;
+ const char *app_name = g_get_application_name ();
+ char *appid = NULL;
+ char *appid_escaped = NULL;
+ char *snid_escaped = NULL;
+ char *unit_name = NULL;
+
+ /* In this order:
+ * 1. Actual application ID from file
+ * 2. Stripping the .desktop from the desktop ID
+ * 3. Fall back to using the binary name
+ */
+ if (info->app_id)
+ appid = g_strdup (info->app_id);
+ else if (info->desktop_id && g_str_has_suffix (info->desktop_id, ".desktop"))
+ appid = g_strndup (info->desktop_id, strlen (info->desktop_id) - 8);
+ else
+ appid = g_path_get_basename (info->binary);
+
+ appid_escaped = systemd_unit_name_escape (appid);
+
+ /* Generate a name conforming to
+ * https://systemd.io/DESKTOP_ENVIRONMENTS/
+ * We use the PID to disambiguate, as that should be unique enough.
+ */
+ unit_name = g_strdup_printf ("app-glib-%s-%d.scope", appid_escaped, pid);
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ssa(sv)a(sa(sv)))"));
+ g_variant_builder_add (&builder, "s", unit_name);
+ g_variant_builder_add (&builder, "s", "fail");
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(sv)"));
+
+ /* Add a generic human readable description, can be changed at will. */
+ if (app_name)
+ g_variant_builder_add (&builder,
+ "(sv)",
+ "Description",
+ g_variant_new_take_string (g_strdup_printf ("Application launched by %s",
+ app_name)));
+ g_variant_builder_add (&builder,
+ "(sv)",
+ "PIDs",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, &pid, 1, 4));
+ /* Default to let systemd garbage collect failed applications we launched. */
+ g_variant_builder_add (&builder,
+ "(sv)",
+ "CollectMode",
+ g_variant_new_string ("inactive-or-failed"));
+
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(sa(sv))"));
+ g_variant_builder_close (&builder);
+
+ g_dbus_connection_call (session_bus,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartTransientUnit",
+ g_variant_builder_end (&builder),
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ 1000,
+ NULL,
+ callback,
+ user_data);
+
+ g_free (appid);
+ g_free (appid_escaped);
+ g_free (snid_escaped);
+ g_free (unit_name);
+}
+
+static void
+systemd_scope_created_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GVariant *res = NULL;
+ GError *error = NULL;
+
+ res = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
+ if (error != NULL)
+ {
+ g_debug ("Failed to move new child into scope: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* Unblock the waiting wrapper binary. */
+ close (GPOINTER_TO_INT (user_data));
+
+ if (res)
+ g_variant_unref (res);
+}
+#endif
+
static gboolean
g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
GDBusConnection *session_bus,
@@ -2847,13 +2989,14 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
GList *old_uris;
GList *dup_uris;
- char **argv, **envp;
+ GStrv argv = NULL, envp = NULL;
+ GStrv wrapped_argv = NULL;
+ GList *launched_uris = NULL;
+ char *sn_id = NULL;
int argc;
g_return_val_if_fail (info != NULL, FALSE);
- argv = NULL;
-
if (launch_context)
envp = g_app_launch_context_get_environment (launch_context);
else
@@ -2867,27 +3010,19 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
do
{
GPid pid;
- GList *launched_uris;
GList *iter;
- char *sn_id = NULL;
- char **wrapped_argv;
int i;
- gsize j;
- const gchar * const wrapper_argv[] =
- {
- "/bin/sh",
- "-e",
- "-u",
- "-c", "export GIO_LAUNCHED_DESKTOP_FILE_PID=$$; exec \"$@\"",
- "sh", /* argv[0] for sh */
- };
+#if defined(__linux__) && !defined(__BIONIC__)
+ SpawnWrapperData wrapper_data;
+#endif
+ GSpawnChildSetupFunc setup = user_setup;
+ gpointer setup_data = user_setup_data;
old_uris = dup_uris;
if (!expand_application_parameters (info, exec_line, &dup_uris, &argc, &argv, error))
- goto out;
+ return FALSE;
/* Get the subset of URIs we're launching with this process */
- launched_uris = NULL;
for (iter = old_uris; iter != NULL && iter != dup_uris; iter = iter->next)
launched_uris = g_list_prepend (launched_uris, iter->data);
launched_uris = g_list_reverse (launched_uris);
@@ -2896,7 +3031,7 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Unable to find terminal required for application"));
- goto out;
+ return FALSE;
}
if (info->filename)
@@ -2905,7 +3040,6 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
info->filename,
TRUE);
- sn_id = NULL;
if (launch_context)
{
GList *launched_files = create_files_for_uris (launched_uris);
@@ -2936,38 +3070,93 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
* with a wrapper program (grep the GLib git history for
* `gio-launch-desktop` for an example of this which could be
* resurrected). */
- wrapped_argv = g_new (char *, argc + G_N_ELEMENTS (wrapper_argv) + 1);
+ wrapped_argv = g_new (char *, argc + 6 + 1);
+
+ wrapped_argv[0] = g_strdup ("/bin/sh");
+ wrapped_argv[1] = g_strdup ("-e");
+ wrapped_argv[2] = g_strdup ("-u");
+ wrapped_argv[3] = g_strdup ("-c");
+ /* argument 4 is filled in below */
+ wrapped_argv[5] = g_strdup ("sh");
- for (j = 0; j < G_N_ELEMENTS (wrapper_argv); j++)
- wrapped_argv[j] = g_strdup (wrapper_argv[j]);
for (i = 0; i < argc; i++)
- wrapped_argv[i + G_N_ELEMENTS (wrapper_argv)] = g_steal_pointer (&argv[i]);
+ wrapped_argv[i + 6] = g_steal_pointer (&argv[i]);
+
+ wrapped_argv[i + 6] = NULL;
+ g_clear_pointer (&argv, g_free);
+
+#if defined(__linux__) && !defined(__BIONIC__)
+ /* Create pipes, if we use a setup func, then set cloexec,
+ * otherwise our wrapper script will close both sides. */
+ if (!g_unix_open_pipe (wrapper_data.pipe, 0, NULL))
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unable to create pipe for systemd synchronization"));
+ return FALSE;
+ }
+
+ /* Set CLOEXEC on the write pipe, so we don't need to deal with it in the child. */
+ fcntl (wrapper_data.pipe[1], F_SETFD, FD_CLOEXEC);
- wrapped_argv[i + G_N_ELEMENTS (wrapper_argv)] = NULL;
- g_free (argv);
- argv = NULL;
+ if (!(spawn_flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN))
+ {
+ /* In this case, we use a setup function (which could probably also
+ * overwrite envp to set GIO_LAUNCHED_DESKTOP_FILE_PID).
+ *
+ * Note that this does not incur an additional cost because
+ * G_SPAWN_LEAVE_DESCRIPTOR_OPEN must be set in order to use
+ * posix_spawn. */
+ wrapper_data.user_setup = setup;
+ wrapper_data.user_setup_data = setup_data;
+
+ setup = launch_uris_with_spawn_delay_exec;
+ setup_data = &wrapper_data;
+ }
+
+ wrapped_argv[4] = g_strdup_printf ("export GIO_LAUNCHED_DESKTOP_FILE_PID=$$; cat <&%1$d; exec \"$@\" %1$d<&-",
+ wrapper_data.pipe[0]);
+#else
+ wrapped_argv[4] = g_strdup ("export GIO_LAUNCHED_DESKTOP_FILE_PID=$$; exec \"$@\"");
+#endif
if (!g_spawn_async_with_fds (info->path,
wrapped_argv,
envp,
spawn_flags,
- user_setup,
- user_setup_data,
+ setup,
+ setup_data,
&pid,
stdin_fd,
stdout_fd,
stderr_fd,
error))
{
+#if defined(__linux__) && !defined(__BIONIC__)
+ close (wrapper_data.pipe[0]);
+ close (wrapper_data.pipe[1]);
+#endif
+
if (sn_id)
g_app_launch_context_launch_failed (launch_context, sn_id);
- g_free (sn_id);
- g_list_free (launched_uris);
-
goto out;
}
+#if defined(__linux__) && !defined(__BIONIC__)
+ /* We close write side asynchronously later on when the dbus call
+ * to systemd finishes. */
+ close (wrapper_data.pipe[0]);
+
+ if (session_bus)
+ create_systemd_scope (session_bus,
+ info,
+ pid,
+ systemd_scope_created_cb,
+ GINT_TO_POINTER (wrapper_data.pipe[1]));
+ else
+ close (wrapper_data.pipe[1]);
+#endif
+
if (pid_callback != NULL)
pid_callback (info, pid, pid_callback_data);
@@ -2992,19 +3181,20 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
sn_id,
launched_uris);
- g_free (sn_id);
- g_list_free (launched_uris);
-
- g_strfreev (wrapped_argv);
- wrapped_argv = NULL;
+ g_clear_pointer (&sn_id, g_free);
+ g_clear_pointer (&launched_uris, g_list_free);
+ g_clear_pointer (&wrapped_argv, g_strfreev);
}
while (dup_uris != NULL);
completed = TRUE;
- out:
+out:
g_strfreev (argv);
g_strfreev (envp);
+ g_clear_pointer (&wrapped_argv, g_strfreev);
+ g_list_free (launched_uris);
+ g_free (sn_id);
return completed;
}
--
2.36.1
From 17d4021c1f38ae35f3eda0f0b44085e4bca97a58 Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Tue, 28 Jul 2020 12:11:13 +0200
Subject: [PATCH 3/4] gdesktopappinfo: Handle task completion from spawn
function
This allows delaying the return of the task until all dbus calls (in
particular the ones to setup the scope) have finished.
This fixes the behaviour of the previous commit which would not
correctly move the process into the scope if the application exited
right after the task returned.
---
gio/gdesktopappinfo.c | 217 ++++++++++++++++++++++++++++--------------
1 file changed, 146 insertions(+), 71 deletions(-)
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 570e49e57..62c93e671 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -2946,11 +2946,17 @@ create_systemd_scope (GDBusConnection *session_bus,
g_free (unit_name);
}
+typedef struct {
+ GTask *task;
+ int fd;
+} ScopeCreatedData;
+
static void
systemd_scope_created_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
+ ScopeCreatedData *data = user_data;
GVariant *res = NULL;
GError *error = NULL;
@@ -2962,13 +2968,47 @@ systemd_scope_created_cb (GObject *object,
}
/* Unblock the waiting wrapper binary. */
- close (GPOINTER_TO_INT (user_data));
+
+ close (data->fd);
+
+ if (data->task)
+ {
+ gint pending;
+ pending = GPOINTER_TO_INT (g_task_get_task_data (data->task));
+ pending -= 1;
+ g_task_set_task_data (data->task, GINT_TO_POINTER (pending), NULL);
+
+ if (pending == 0 && !g_task_get_completed (data->task))
+ g_task_return_boolean (data->task, TRUE);
+ }
if (res)
g_variant_unref (res);
+ g_clear_object (&data->task);
+ g_free (data);
}
#endif
+static void
+launch_uris_with_spawn_flush_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GTask *task = G_TASK (user_data);
+ gint pending;
+
+ g_dbus_connection_flush_finish (G_DBUS_CONNECTION (object), result, NULL);
+
+ pending = GPOINTER_TO_INT (g_task_get_task_data (task));
+ pending -= 1;
+ g_task_set_task_data (task, GINT_TO_POINTER (pending), NULL);
+
+ if (pending == 0 && !g_task_get_completed (task))
+ g_task_return_boolean (task, TRUE);
+
+ g_object_unref (task);
+}
+
static gboolean
g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
GDBusConnection *session_bus,
@@ -2983,9 +3023,10 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
gint stdin_fd,
gint stdout_fd,
gint stderr_fd,
- GError **error)
+ GTask *task,
+ GError **error_out)
{
- gboolean completed = FALSE;
+ GError *error = NULL;
GList *old_uris;
GList *dup_uris;
@@ -2995,8 +3036,15 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
char *sn_id = NULL;
int argc;
+ /* We may get a task to report back on or an error. But never both. */
+ g_assert (!(task && error_out));
g_return_val_if_fail (info != NULL, FALSE);
+ /* Surrounding code must not have set any data on the task
+ * (it is cleared before calling this function). */
+ if (session_bus && task)
+ g_assert (g_task_get_task_data (task) == NULL);
+
if (launch_context)
envp = g_app_launch_context_get_environment (launch_context);
else
@@ -3019,8 +3067,8 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
gpointer setup_data = user_setup_data;
old_uris = dup_uris;
- if (!expand_application_parameters (info, exec_line, &dup_uris, &argc, &argv, error))
- return FALSE;
+ if (!expand_application_parameters (info, exec_line, &dup_uris, &argc, &argv, &error))
+ goto out;
/* Get the subset of URIs we're launching with this process */
for (iter = old_uris; iter != NULL && iter != dup_uris; iter = iter->next)
@@ -3029,9 +3077,9 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
if (info->terminal && !prepend_terminal_to_vector (&argc, &argv))
{
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unable to find terminal required for application"));
- return FALSE;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unable to find terminal required for application"));
+ goto out;
}
if (info->filename)
@@ -3090,9 +3138,9 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
* otherwise our wrapper script will close both sides. */
if (!g_unix_open_pipe (wrapper_data.pipe, 0, NULL))
{
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unable to create pipe for systemd synchronization"));
- return FALSE;
+ error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unable to create pipe for systemd synchronization"));
+ goto out;
}
/* Set CLOEXEC on the write pipe, so we don't need to deal with it in the child. */
@@ -3129,7 +3177,7 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
stdin_fd,
stdout_fd,
stderr_fd,
- error))
+ &error))
{
#if defined(__linux__) && !defined(__BIONIC__)
close (wrapper_data.pipe[0]);
@@ -3148,11 +3196,29 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
close (wrapper_data.pipe[0]);
if (session_bus)
- create_systemd_scope (session_bus,
- info,
- pid,
- systemd_scope_created_cb,
- GINT_TO_POINTER (wrapper_data.pipe[1]));
+ {
+ ScopeCreatedData *data;
+
+ data = g_new0 (ScopeCreatedData, 1);
+
+ if (task)
+ {
+ gint pending;
+ pending = GPOINTER_TO_INT (g_task_get_task_data (task));
+ pending += 1;
+ g_task_set_task_data (task, GINT_TO_POINTER (pending), NULL);
+
+ data->task = g_object_ref (task);
+ }
+
+ data->fd = wrapper_data.pipe[1];
+
+ create_systemd_scope (session_bus,
+ info,
+ pid,
+ systemd_scope_created_cb,
+ data);
+ }
else
close (wrapper_data.pipe[1]);
#endif
@@ -3187,8 +3253,6 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo *info,
}
while (dup_uris != NULL);
- completed = TRUE;
-
out:
g_strfreev (argv);
g_strfreev (envp);
@@ -3196,7 +3260,52 @@ out:
g_list_free (launched_uris);
g_free (sn_id);
- return completed;
+ if (!error)
+ {
+ if (session_bus && task)
+ {
+ GCancellable *cancellable = g_task_get_cancellable (task);
+ gint pending;
+ pending = GPOINTER_TO_INT (g_task_get_task_data (task));
+ pending += 1;
+ g_task_set_task_data (task, GINT_TO_POINTER (pending), NULL);
+
+ /* FIXME: The D-Bus message from the notify_desktop_launch() function
+ * can be still lost even if flush is called later. See:
+ * https://gitlab.freedesktop.org/dbus/dbus/issues/72
+ */
+ g_dbus_connection_flush (session_bus,
+ cancellable,
+ launch_uris_with_spawn_flush_cb,
+ g_steal_pointer (&task));
+ }
+ else if (session_bus)
+ {
+ /* No task available. */
+ g_dbus_connection_flush (session_bus,
+ NULL,
+ NULL,
+ NULL);
+ }
+ else if (task)
+ {
+ /* Return the given task. */
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ }
+ }
+ else
+ {
+ if (task)
+ {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ }
+ else
+ g_propagate_error (error_out, error);
+ }
+
+ return !error;
}
static gchar *
@@ -3421,17 +3530,9 @@ g_desktop_app_info_launch_uris_internal (GAppInfo *appinfo,
success = g_desktop_app_info_launch_uris_with_spawn (info, session_bus, info->exec, uris, launch_context,
spawn_flags, user_setup, user_setup_data,
pid_callback, pid_callback_data,
- stdin_fd, stdout_fd, stderr_fd, error);
+ stdin_fd, stdout_fd, stderr_fd, NULL, error);
- if (session_bus != NULL)
- {
- /* This asynchronous flush holds a reference until it completes,
- * which ensures that the following unref won't immediately kill
- * the connection if we were the initial owner.
- */
- g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
- g_object_unref (session_bus);
- }
+ g_clear_object (&session_bus);
return success;
}
@@ -3485,18 +3586,6 @@ launch_uris_with_dbus_cb (GObject *object,
g_object_unref (task);
}
-static void
-launch_uris_flush_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GTask *task = G_TASK (user_data);
-
- g_dbus_connection_flush_finish (G_DBUS_CONNECTION (object), result, NULL);
- g_task_return_boolean (task, TRUE);
- g_object_unref (task);
-}
-
static void
launch_uris_bus_get_cb (GObject *object,
GAsyncResult *result,
@@ -3505,12 +3594,20 @@ launch_uris_bus_get_cb (GObject *object,
GTask *task = G_TASK (user_data);
GDesktopAppInfo *info = G_DESKTOP_APP_INFO (g_task_get_source_object (task));
LaunchUrisData *data = g_task_get_task_data (task);
+ LaunchUrisData *data_copy = NULL;
GCancellable *cancellable = g_task_get_cancellable (task);
GDBusConnection *session_bus;
- GError *error = NULL;
session_bus = g_bus_get_finish (result, NULL);
+ data_copy = g_new0 (LaunchUrisData, 1);
+ data_copy->appinfo = g_steal_pointer (&data->appinfo);
+ data_copy->uris = g_steal_pointer (&data->uris);
+ data_copy->context = g_steal_pointer (&data->context);
+
+ /* Allow other data to be attached to the task. */
+ g_task_set_task_data (task, NULL, NULL);
+
if (session_bus && info->app_id)
{
/* FIXME: The g_document_portal_add_documents() function, which is called
@@ -3518,39 +3615,21 @@ launch_uris_bus_get_cb (GObject *object,
* uses blocking calls.
*/
g_desktop_app_info_launch_uris_with_dbus (info, session_bus,
- data->uris, data->context,
+ data_copy->uris, data_copy->context,
cancellable,
launch_uris_with_dbus_cb,
g_steal_pointer (&task));
}
else
{
- /* FIXME: The D-Bus message from the notify_desktop_launch() function
- * can be still lost even if flush is called later. See:
- * https://gitlab.freedesktop.org/dbus/dbus/issues/72
- */
g_desktop_app_info_launch_uris_with_spawn (info, session_bus, info->exec,
- data->uris, data->context,
+ data_copy->uris, data_copy->context,
_SPAWN_FLAGS_DEFAULT, NULL,
NULL, NULL, NULL, -1, -1, -1,
- &error);
- if (error != NULL)
- {
- g_task_return_error (task, g_steal_pointer (&error));
- g_object_unref (task);
- }
- else if (session_bus)
- g_dbus_connection_flush (session_bus,
- cancellable,
- launch_uris_flush_cb,
- g_steal_pointer (&task));
- else
- {
- g_task_return_boolean (task, TRUE);
- g_clear_object (&task);
- }
+ g_steal_pointer (&task), NULL);
}
+ launch_uris_data_free (data_copy);
g_clear_object (&session_bus);
}
@@ -5368,16 +5447,12 @@ g_desktop_app_info_launch_action (GDesktopAppInfo *info,
if (exec_line)
g_desktop_app_info_launch_uris_with_spawn (info, session_bus, exec_line, NULL, launch_context,
_SPAWN_FLAGS_DEFAULT, NULL, NULL, NULL, NULL,
- -1, -1, -1, NULL);
+ -1, -1, -1, NULL, NULL);
g_free (exec_line);
}
- if (session_bus != NULL)
- {
- g_dbus_connection_flush (session_bus, NULL, NULL, NULL);
- g_object_unref (session_bus);
- }
+ g_clear_object (&session_bus);
}
/* Epilogue {{{1 */
--
2.36.1
From 5ca7b700ab906a663220434659483c140f2d170a Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Thu, 17 Sep 2020 17:35:58 +0200
Subject: [PATCH 4/4] gdesktopappinfo: Add SourcePath= to transient systemd
units
systemd allows setting a SourcePath= which shows the file that the unit
has been generated from. KDE is starting to set this and it seems like a
good idea, so do the same here.
See https://invent.kde.org/frameworks/kio/-/merge_requests/124
---
gio/gdesktopappinfo.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 62c93e671..1091d3859 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -2874,6 +2874,7 @@ create_systemd_scope (GDBusConnection *session_bus,
{
GVariantBuilder builder;
const char *app_name = g_get_application_name ();
+ const char *source_path = NULL;
char *appid = NULL;
char *appid_escaped = NULL;
char *snid_escaped = NULL;
@@ -2899,6 +2900,8 @@ create_systemd_scope (GDBusConnection *session_bus,
*/
unit_name = g_strdup_printf ("app-glib-%s-%d.scope", appid_escaped, pid);
+ source_path = g_desktop_app_info_get_filename (info);
+
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ssa(sv)a(sa(sv)))"));
g_variant_builder_add (&builder, "s", unit_name);
g_variant_builder_add (&builder, "s", "fail");
@@ -2912,6 +2915,16 @@ create_systemd_scope (GDBusConnection *session_bus,
"Description",
g_variant_new_take_string (g_strdup_printf ("Application launched by %s",
app_name)));
+
+ /* If we have a .desktop file, document that the scope has been "generated"
+ * from it.
+ */
+ if (source_path && g_utf8_validate (source_path, -1, NULL))
+ g_variant_builder_add (&builder,
+ "(sv)",
+ "SourcePath",
+ g_variant_new_string (source_path));
+
g_variant_builder_add (&builder,
"(sv)",
"PIDs",
--
2.36.1

View File

@ -1,5 +1,5 @@
Name: glib2
Version: 2.73.2
Version: 2.73.3
Release: %autorelease
Summary: A library of handy utility functions
@ -12,21 +12,6 @@ Source0: https://download.gnome.org/sources/glib/2.72/glib-%{version}.tar.xz
# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903
Patch0: gnutls-hmac.patch
# Add patches to move applications into systemd scopes in compliance with
# https://systemd.io/DESKTOP_ENVIRONMENTS/
# Proposed upstream at https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1596
Patch1: gdesktopappinfo.patch
# Backported from upstream to fix GRegex on s390x
# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2840
Patch2: 2840.patch
# https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2838
Patch3: 2838.patch
# Backported from upstream
# https://bugzilla.redhat.com/show_bug.cgi?id=2109145
Patch4: 0001-gmain-close-pidfd-when-finalizing-GChildWatchSource.patch
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: gettext

View File

@ -1 +1 @@
SHA512 (glib-2.73.2.tar.xz) = ae980c0aac89cde1298efeb0c174a122c23113e671405dc30c882b7237622c7c0f5cdf896852015b6f55ae09a756c293d7a57061a874014ac42c2d3e4450aab9
SHA512 (glib-2.73.3.tar.xz) = f965323be1d17dbc322ae329748b99365720977bd313519279a5236973532fed36a63726a3bffd2795eb5a627776cda3ebcbd3456cc2388f65ffe8afacbcc167