From 179d9e966708e25e9424b2cab7376f4303d708a0 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Thu, 5 Dec 2019 11:43:49 +0100 Subject: [PATCH] Add upstream patch adding new API that is already in stable https://gitlab.gnome.org/GNOME/gnome-desktop/merge_requests/58 --- ...ild-Remove-stray-from-config.h.meson.patch | 25 ++ ...ity-function-to-start-a-transient-sy.patch | 424 ++++++++++++++++++ gnome-desktop3.spec | 9 +- 3 files changed, 457 insertions(+), 1 deletion(-) create mode 100644 0001-build-Remove-stray-from-config.h.meson.patch create mode 100644 0002-systemd-Add-utility-function-to-start-a-transient-sy.patch diff --git a/0001-build-Remove-stray-from-config.h.meson.patch b/0001-build-Remove-stray-from-config.h.meson.patch new file mode 100644 index 0000000..91596e3 --- /dev/null +++ b/0001-build-Remove-stray-from-config.h.meson.patch @@ -0,0 +1,25 @@ +From 5331b019c572de39be6242a58bd613e81de49df6 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Sat, 30 Nov 2019 19:12:00 +0100 +Subject: [PATCH 1/2] build: Remove stray # from config.h.meson + +--- + config.h.meson | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/config.h.meson b/config.h.meson +index 2c72485a..3818c9e6 100644 +--- a/config.h.meson ++++ b/config.h.meson +@@ -12,7 +12,7 @@ + + /* we have the timerfd_create(2) system call */ + #mesondefine HAVE_TIMERFD +-# ++ + /* Define to 1 if you have the `openat' function. */ + #mesondefine HAVE_OPENAT + +-- +2.23.0 + diff --git a/0002-systemd-Add-utility-function-to-start-a-transient-sy.patch b/0002-systemd-Add-utility-function-to-start-a-transient-sy.patch new file mode 100644 index 0000000..e5f3463 --- /dev/null +++ b/0002-systemd-Add-utility-function-to-start-a-transient-sy.patch @@ -0,0 +1,424 @@ +From 791200e749f069087d040fd6248be636de539e44 Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Sat, 30 Nov 2019 16:49:10 +0100 +Subject: [PATCH 2/2] systemd: Add utility function to start a transient + systemd scope + +In a systemd world, it is often a good idea to move launched +applications outside of the own unit into one of their own. This helper +allows to do so in a safe and consistent way. +--- + config.h.meson | 3 + + libgnome-desktop/gnome-systemd.c | 270 +++++++++++++++++++++++++++++++ + libgnome-desktop/gnome-systemd.h | 41 +++++ + libgnome-desktop/meson.build | 3 + + meson.build | 3 + + meson_options.txt | 4 + + 6 files changed, 324 insertions(+) + create mode 100644 libgnome-desktop/gnome-systemd.c + create mode 100644 libgnome-desktop/gnome-systemd.h + +diff --git a/config.h.meson b/config.h.meson +index 3818c9e6..7a8d8d96 100644 +--- a/config.h.meson ++++ b/config.h.meson +@@ -16,6 +16,9 @@ + /* Define to 1 if you have the `openat' function. */ + #mesondefine HAVE_OPENAT + ++/* define if libsystemd is available */ ++#mesondefine HAVE_SYSTEMD ++ + /* define if udev is available */ + #mesondefine HAVE_UDEV + +diff --git a/libgnome-desktop/gnome-systemd.c b/libgnome-desktop/gnome-systemd.c +new file mode 100644 +index 00000000..4c875583 +--- /dev/null ++++ b/libgnome-desktop/gnome-systemd.c +@@ -0,0 +1,270 @@ ++/* gnome-systemd.c ++ * ++ * Copyright 2019 Benjamin Berg ++ * ++ * This file is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 3 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program. If not, see . ++ * ++ * SPDX-License-Identifier: LGPL-3.0-or-later ++ */ ++ ++#include "config.h" ++ ++#define GNOME_DESKTOP_USE_UNSTABLE_API ++#include "gnome-systemd.h" ++ ++#ifdef HAVE_SYSTEMD ++#include ++#include ++#endif ++ ++#ifdef HAVE_SYSTEMD ++typedef struct { ++ char *name; ++ char *description; ++ gint32 pid; ++} StartSystemdScopeData; ++ ++static void ++start_systemd_scope_data_free (StartSystemdScopeData *data) ++{ ++ g_clear_pointer (&data->name, g_free); ++ g_clear_pointer (&data->description, g_free); ++ g_free (data); ++} ++ ++static void ++on_start_transient_unit_cb (GObject *source, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ g_autoptr (GTask) task = G_TASK (user_data); ++ g_autoptr (GVariant) reply = NULL; ++ GError *error = NULL; ++ StartSystemdScopeData *task_data = g_task_get_task_data (task); ++ ++ reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), ++ res, &error); ++ if (error && !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ { ++ g_warning ("Could not create transient scope for PID %d: %s", ++ task_data->pid, error->message); ++ g_task_return_error (task, error); ++ return; ++ } ++ ++ g_debug ("Created transient scope for PID %d", task_data->pid); ++ ++ g_task_return_boolean (task, TRUE); ++} ++ ++static void ++start_systemd_scope (GDBusConnection *connection, GTask *task) ++{ ++ GVariantBuilder builder; ++ g_autofree char *unit_name = NULL; ++ StartSystemdScopeData *task_data = g_task_get_task_data (task); ++ ++ g_assert (task_data != NULL); ++ ++ /* This needs to be unique, hopefully the pid will be enough. */ ++ unit_name = g_strdup_printf ("gnome-launched-%s-%d.scope", task_data->name, task_data->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"); ++ ++ /* Note that gnome-session ships a drop-in to control further defaults. */ ++ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(sv)")); ++ if (task_data->description) ++ g_variant_builder_add (&builder, ++ "(sv)", ++ "Description", ++ g_variant_new_string (task_data->description)); ++ g_variant_builder_add (&builder, ++ "(sv)", ++ "PIDs", ++ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, &task_data->pid, 1, 4)); ++ 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 (connection, ++ "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, ++ g_task_get_cancellable (task), ++ on_start_transient_unit_cb, ++ task); ++} ++ ++static void ++on_bus_gotten_cb (GObject *source, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ g_autoptr(GTask) task = G_TASK (user_data); ++ g_autoptr(GDBusConnection) connection = NULL; ++ GError *error = NULL; ++ ++ connection = g_bus_get_finish (res, &error); ++ if (error) ++ { ++ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ g_warning ("Could not get session bus: %s", error->message); ++ ++ g_task_return_error (task, error); ++ return; ++ } ++ ++ start_systemd_scope (connection, g_steal_pointer (&task)); ++} ++#endif ++ ++/** ++ * gnome_start_systemd_scope: ++ * @name: Name for the application ++ * @pid: The PID of the application ++ * @description: (nullable): A description to use for the unit, or %NULL ++ * @connection: (nullable): An #GDBusConnection to the session bus, or %NULL ++ * @cancellable: (nullable): #GCancellable to use ++ * @callback: (nullable): Callback to call when the operation is done ++ * @user_data: Data to be passed to @callback ++ * ++ * If the current process is running inside a user systemd instance, then move ++ * the launched PID into a transient scope. The given @name will be used to ++ * create a unit name. It should be the application ID for desktop files or ++ * the executable in all other cases. ++ * ++ * It is advisable to use this function every time where the started application ++ * can be considered reasonably independent of the launching application. Placing ++ * it in a scope creates proper separation between the programs rather than being ++ * considered a single entity by systemd. ++ * ++ * It is always safe to call this function. Note that a successful return code ++ * does not imply that a unit has been created. It solely means that no error ++ * condition was hit sending the request. ++ * ++ * If @connection is %NULL then g_dbus_get() will be called internally. ++ * ++ * Note that most callers will not need to handle errors. As such, it is normal ++ * to pass a %NULL @callback. ++ * ++ * Stability: unstable ++ */ ++void ++gnome_start_systemd_scope (const char *name, ++ gint32 pid, ++ const char *description, ++ GDBusConnection *connection, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data) ++{ ++ g_autoptr(GTask) task = NULL; ++ ++#ifdef HAVE_SYSTEMD ++ g_autofree char *own_unit = NULL; ++ const char *valid_chars = ++ "-._1234567890" ++ "abcdefghijklmnopqrstuvwxyz" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; ++ StartSystemdScopeData *task_data; ++ gint res; ++ ++ task = g_task_new (NULL, cancellable, callback, user_data); ++ task_data = g_new0 (StartSystemdScopeData, 1); ++ ++ task_data->pid = pid; ++ ++ /* Create a nice and (mangled) name to embed into the unit */ ++ if (name == NULL) ++ name = "anonymous"; ++ ++ if (name[0] == '/') ++ name++; ++ ++ task_data->name = g_str_to_ascii (name, "C"); ++ g_strdelimit (task_data->name, "/", '-'); ++ g_strcanon (task_data->name, valid_chars, '_'); ++ ++ task_data->description = g_strdup (description); ++ if (task_data->description == NULL) ++ { ++ const char *app_name = g_get_application_name(); ++ ++ if (app_name) ++ task_data->description = g_strdup_printf ("Application launched by %s", ++ app_name); ++ } ++ ++ g_task_set_task_data (task, task_data, (GDestroyNotify) start_systemd_scope_data_free); ++ ++ /* We cannot do anything if this process is not managed by the ++ * systemd user instance. */ ++ res = sd_pid_get_user_unit (getpid (), &own_unit); ++ if (res == -ENODATA) ++ { ++ g_debug ("Not systemd managed, will not move PID %d into transient scope\n", pid); ++ g_task_return_boolean (task, TRUE); ++ ++ return; ++ } ++ if (res < 0) ++ { ++ g_warning ("Error fetching user unit for own pid: %d\n", -res); ++ g_task_return_new_error (task, ++ G_IO_ERROR, ++ g_io_error_from_errno (-res), ++ "Error fetching user unit for own pid: %d", -res); ++ ++ return; ++ } ++ ++ if (connection == NULL) ++ g_bus_get (G_BUS_TYPE_SESSION, cancellable, on_bus_gotten_cb, g_steal_pointer (&task)); ++ else ++ start_systemd_scope (connection, g_steal_pointer (&task)); ++#else ++ g_debug ("Not creating transient scope for PID %d. Systemd support not compiled in.", pid); ++ ++ task = g_task_new (NULL, cancellable, callback, user_data); ++ g_task_return_boolean (task, TRUE); ++#endif ++} ++ ++/** ++ * gnome_start_systemd_scope_finish: ++ * @res: A #GAsyncResult ++ * @error: Return location for errors, or %NULL to ignore ++ * ++ * Finish an asynchronous operation to create a transient scope that was ++ * started with gnome_start_systemd_scope(). ++ * ++ * Note that a successful return code does not imply that a unit has been ++ * created. It solely means that no error condition was hit sending the request. ++ * ++ * Returns: %FALSE on error, %TRUE otherwise ++ */ ++gboolean ++gnome_start_systemd_scope_finish (GAsyncResult *res, ++ GError **error) ++{ ++ return g_task_propagate_boolean (G_TASK (res), error); ++} +diff --git a/libgnome-desktop/gnome-systemd.h b/libgnome-desktop/gnome-systemd.h +new file mode 100644 +index 00000000..5d403b4f +--- /dev/null ++++ b/libgnome-desktop/gnome-systemd.h +@@ -0,0 +1,41 @@ ++/* gnome-systemd.h ++ * ++ * Copyright 2019 Benjamin Berg ++ * ++ * This file is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 3 of the ++ * License, or (at your option) any later version. ++ * ++ * This file is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this program. If not, see . ++ * ++ * SPDX-License-Identifier: LGPL-3.0-or-later ++ */ ++ ++#ifndef _GNOME_SYSTEMD_H ++#define _GNOME_SYSTEMD_H ++ ++#ifndef GNOME_DESKTOP_USE_UNSTABLE_API ++#error GnomeDesktopSystemd is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-systemd.h ++#endif ++ ++#include ++ ++void gnome_start_systemd_scope (const char *name, ++ gint32 pid, ++ const char *description, ++ GDBusConnection *connection, ++ GCancellable *cancellable, ++ GAsyncReadyCallback callback, ++ gpointer user_data); ++ ++gboolean gnome_start_systemd_scope_finish (GAsyncResult *res, ++ GError **error); ++ ++#endif /* _GNOME_SYSTEMD_H */ +diff --git a/libgnome-desktop/meson.build b/libgnome-desktop/meson.build +index 8503215f..01d10b7e 100644 +--- a/libgnome-desktop/meson.build ++++ b/libgnome-desktop/meson.build +@@ -17,6 +17,7 @@ introspection_sources = [ + 'gnome-rr.c', + 'gnome-rr-config.c', + 'gnome-rr-output-info.c', ++ 'gnome-systemd.c', + 'gnome-pnp-ids.c', + 'gnome-wall-clock.c', + 'gnome-xkb-info.c', +@@ -57,6 +58,7 @@ libgnome_desktop_headers = [ + 'gnome-desktop-thumbnail.h', + 'gnome-rr.h', + 'gnome-rr-config.h', ++ 'gnome-systemd.h', + 'gnome-pnp-ids.h', + 'gnome-wall-clock.h', + 'gnome-xkb-info.h', +@@ -75,6 +77,7 @@ gnome_desktop_deps = [ + glib_dep, + gio_dep, + gio_unix_dep, ++ libsystemd_dep, + schemas_dep, + xkb_config_dep, + iso_codes_dep, +diff --git a/meson.build b/meson.build +index 6876c2c3..360d6600 100644 +--- a/meson.build ++++ b/meson.build +@@ -50,6 +50,8 @@ xkb_config_dep = dependency('xkeyboard-config') + iso_codes_dep = dependency('iso-codes') + x_dep = dependency('x11') + ++libsystemd_dep = dependency('libsystemd', required: get_option('systemd')) ++ + udev_dep = dependency('libudev', required: get_option('udev')) + + # Check for bubblewrap compatible platform +@@ -85,6 +87,7 @@ conf.set('ENABLE_SECCOMP', seccomp_dep.found()) + conf.set('HAVE_BWRAP', seccomp_dep.found()) + conf.set('_GNU_SOURCE', seccomp_dep.found()) + ++conf.set('HAVE_SYSTEMD', libsystemd_dep.found()) + conf.set('HAVE_UDEV', udev_dep.found()) + + conf.set('HAVE_TIMERFD', cc.has_function('timerfd_create')) +diff --git a/meson_options.txt b/meson_options.txt +index e3402a11..c0fea3f8 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -21,6 +21,10 @@ option('udev', + type: 'feature', description: 'Udev support' + ) + ++option('systemd', ++ type: 'feature', description: 'Systemd integration support' ++) ++ + option('gtk_doc', + type: 'boolean', value: false, description: 'Build API reference' + ) +-- +2.23.0 + diff --git a/gnome-desktop3.spec b/gnome-desktop3.spec index 184329b..2f42920 100644 --- a/gnome-desktop3.spec +++ b/gnome-desktop3.spec @@ -6,13 +6,16 @@ Name: gnome-desktop3 Version: 3.35.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Library with common API for various GNOME modules License: GPLv2+ and LGPLv2+ URL: http://www.gnome.org Source0: http://download.gnome.org/sources/gnome-desktop/3.35/gnome-desktop-%{version}.tar.xz +Patch0001: 0001-build-Remove-stray-from-config.h.meson.patch +Patch0002: 0002-systemd-Add-utility-function-to-start-a-transient-sy.patch + BuildRequires: gcc BuildRequires: gettext BuildRequires: gtk-doc @@ -102,6 +105,10 @@ the functionality of the installed %{name} package. %{_datadir}/installed-tests %changelog +* Thu Dec 05 2019 Benjamin Berg - 3.35.2-2 +- Add upstream patch adding new API that is already in stable + https://gitlab.gnome.org/GNOME/gnome-desktop/merge_requests/58 + * Mon Dec 02 2019 Kalev Lember - 3.35.2-1 - Update to 3.35.2