Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cinnamon-session/csm-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
* want to wait, at least for something happening more than once.
* We can get deployed on very slow media though like CDROM devices,
* often with complex stacking/compressing filesystems on top, which
* is not a recipie for speed. Particularly now that we throw up

Check failure on line 70 in cinnamon-session/csm-manager.c

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22.3-amd64, Mint 22, true) / Mint 22

recipie ==> recipe
* a fail whale if required components don't show up quickly enough,
* let's make this fairly long.
*/
Expand Down Expand Up @@ -953,6 +953,8 @@
static void
do_phase_exit (CsmManager *manager)
{
csm_util_stop_systemd_unit ("cinnamon-session.target", NULL);

if (csm_store_size (manager->priv->clients) > 0) {
csm_store_foreach (manager->priv->clients,
(CsmStoreFunc)_client_stop,
Expand Down Expand Up @@ -1523,6 +1525,7 @@
csm_xsmp_server_start_accepting_new_clients (manager->priv->xsmp_server);
csm_exported_manager_emit_session_running (manager->priv->skeleton);
update_idle (manager);
csm_util_start_systemd_unit ("cinnamon-session.target", NULL);
break;
case CSM_MANAGER_PHASE_QUERY_END_SESSION:
csm_xsmp_server_stop_accepting_new_clients (manager->priv->xsmp_server);
Expand Down
195 changes: 195 additions & 0 deletions cinnamon-session/csm-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,201 @@ csm_util_update_user_environment (const char *variable,
return environment_updated;
}

static const char * const csm_systemd_env_denylist[] = {
"XDG_SESSION_ID",
"XDG_SESSION_TYPE",
"XDG_SESSION_CLASS",
"XDG_SESSION_DESKTOP",
"XDG_SEAT",
"XDG_VTNR",
"NOTIFY_SOCKET",
NULL
};

gboolean
csm_util_export_systemd_activation_environment (GError **error)
{
GDBusConnection *connection;
GVariantBuilder builder;
GVariant *reply;
GError *bus_error = NULL;
GRegex *name_regex, *value_regex;
char **entry_names;
int i = 0;
gboolean environment_updated = FALSE;

if (access ("/run/systemd/private", F_OK) != 0)
return TRUE;

connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
if (connection == NULL)
return FALSE;

name_regex = g_regex_new ("^[a-zA-Z_][a-zA-Z0-9_]*$",
G_REGEX_OPTIMIZE, 0, error);
if (name_regex == NULL) {
g_object_unref (connection);
return FALSE;
}

value_regex = g_regex_new ("^([[:blank:]]|[^[:cntrl:]])*$",
G_REGEX_OPTIMIZE, 0, error);
if (value_regex == NULL) {
g_regex_unref (name_regex);
g_object_unref (connection);
return FALSE;
}

g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));

entry_names = g_listenv ();
for (i = 0; entry_names[i] != NULL; i++) {
const char *entry_name = entry_names[i];
const char *entry_value = g_getenv (entry_name);

if (g_strv_contains (csm_systemd_env_denylist, entry_name))
continue;

if (!g_utf8_validate (entry_name, -1, NULL))
continue;

if (!g_regex_match (name_regex, entry_name, 0, NULL))
continue;

if (entry_value == NULL)
continue;

if (!g_utf8_validate (entry_value, -1, NULL))
continue;

if (!g_regex_match (value_regex, entry_value, 0, NULL))
continue;

g_variant_builder_add (&builder, "s",
g_strdup_printf ("%s=%s",
entry_name,
entry_value));
}
g_regex_unref (name_regex);
g_regex_unref (value_regex);
g_strfreev (entry_names);

reply = g_dbus_connection_call_sync (connection,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"SetEnvironment",
g_variant_new ("(@as)",
g_variant_builder_end (&builder)),
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, &bus_error);

if (bus_error != NULL) {
g_warning ("csm_util_export_systemd_activation_environment: "
"failed to export to systemd: %s",
bus_error->message);
if (error != NULL)
g_propagate_error (error, bus_error);
else
g_error_free (bus_error);
} else {
environment_updated = TRUE;
g_variant_unref (reply);
}

g_object_unref (connection);
return environment_updated;
}

gboolean
csm_util_start_systemd_unit (const char *unit,
GError **error)
{
GDBusConnection *connection;
GVariant *reply;
GError *bus_error = NULL;
gboolean ret = FALSE;

if (access ("/run/systemd/private", F_OK) != 0)
return TRUE;

connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
if (connection == NULL)
return FALSE;

g_debug ("csm_util_start_systemd_unit: starting %s", unit);

reply = g_dbus_connection_call_sync (connection,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StartUnit",
g_variant_new ("(ss)", unit, "replace"),
G_VARIANT_TYPE ("(o)"),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, &bus_error);

if (bus_error != NULL) {
g_warning ("csm_util_start_systemd_unit: failed to start %s: %s",
unit, bus_error->message);
if (error != NULL)
g_propagate_error (error, bus_error);
else
g_error_free (bus_error);
} else {
ret = TRUE;
g_variant_unref (reply);
}

g_object_unref (connection);
return ret;
}

gboolean
csm_util_stop_systemd_unit (const char *unit,
GError **error)
{
GDBusConnection *connection;
GVariant *reply;
GError *bus_error = NULL;
gboolean ret = FALSE;

if (access ("/run/systemd/private", F_OK) != 0)
return TRUE;

connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, error);
if (connection == NULL)
return FALSE;

g_debug ("csm_util_stop_systemd_unit: stopping %s", unit);

reply = g_dbus_connection_call_sync (connection,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StopUnit",
g_variant_new ("(ss)", unit, "replace"),
G_VARIANT_TYPE ("(o)"),
G_DBUS_CALL_FLAGS_NONE,
-1, NULL, &bus_error);

if (bus_error != NULL) {
g_debug ("csm_util_stop_systemd_unit: failed to stop %s: %s",
unit, bus_error->message);
if (error != NULL)
g_propagate_error (error, bus_error);
else
g_error_free (bus_error);
} else {
ret = TRUE;
g_variant_unref (reply);
}

g_object_unref (connection);
return ret;
}

void
csm_util_setenv (const char *variable,
const char *value)
Expand Down
7 changes: 7 additions & 0 deletions cinnamon-session/csm-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ gboolean csm_util_export_user_environment (GError **error);
void csm_util_setenv (const char *variable,
const char *value);

gboolean csm_util_export_systemd_activation_environment (GError **error);

gboolean csm_util_start_systemd_unit (const char *unit,
GError **error);
gboolean csm_util_stop_systemd_unit (const char *unit,
GError **error);

// main.c, exit mainloop
void csm_quit (void);

Expand Down
7 changes: 7 additions & 0 deletions cinnamon-session/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,13 @@ main (int argc, char **argv)
csm_util_export_activation_environment (NULL);
csm_util_export_user_environment (NULL);

if (!csm_util_export_systemd_activation_environment (NULL)) {
g_warning ("main: failed to export environment to systemd --user; "
"some systemd-managed services may not start correctly");
}

csm_util_start_systemd_unit ("cinnamon-session.target", NULL);

{
gchar *ibus_path;

Expand Down
3 changes: 3 additions & 0 deletions data/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ install_data(

# Re-compile gsettings
meson.add_install_script('meson_install_schemas.py')

subdir('systemd/user')

10 changes: 10 additions & 0 deletions data/systemd/user/cinnamon-session.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Cinnamon graphical session
Documentation=man:systemd.special(7)
Wants=graphical-session.target
Wants=graphical-session-pre.target
After=graphical-session-pre.target
After=graphical-session.target
PropagatesStopTo=graphical-session.target
PropagatesStopTo=graphical-session-pre.target
CollectMode=inactive-or-failed
6 changes: 6 additions & 0 deletions data/systemd/user/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
install_data(
[
'cinnamon-session.target',
],
install_dir: systemduserunitdir,
)
9 changes: 9 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@
endif
conf.set('HAVE_LOGIND', logind.found())

if libsystemdl.found()
systemduserunitdir = libsystemdl.get_variable(
pkgconfig: 'systemduserunitdir',
default_value: join_paths(get_option('prefix'), 'lib', 'systemd', 'user'),
)
else
systemduserunitdir = join_paths(get_option('prefix'), 'lib', 'systemd', 'user')
endif

if gio_unix.found() and libelogind.found()
elogind = declare_dependency(dependencies: [ gio_unix, libelogind ])
else
Expand Down Expand Up @@ -119,7 +128,7 @@
conf.set('ENABLE_IPV6', have_ipv6)

################################################################################
# Additionnal flags

Check failure on line 131 in meson.build

View workflow job for this annotation

GitHub Actions / build / build (mint22, linuxmintd/mint22.3-amd64, Mint 22, true) / Mint 22

Additionnal ==> Additional

rootInclude = include_directories('.')

Expand Down
Loading