From 6dedc6d8656d8d0891fac87af4e5a603590b865c Mon Sep 17 00:00:00 2001 From: r0chd Date: Thu, 16 Jul 2026 23:54:56 +0200 Subject: [PATCH] source /etc/profile when starting dinit --- protocols/session_management_v2.xml | 24 ++++++++----- src/main.rs | 54 +++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 18 deletions(-) diff --git a/protocols/session_management_v2.xml b/protocols/session_management_v2.xml index 3a6325a..709c5d2 100644 --- a/protocols/session_management_v2.xml +++ b/protocols/session_management_v2.xml @@ -8,10 +8,10 @@ Returns a session_management_session object bound to the calling - connection. The session is not created yet: the client may send vt - and remote_host on the returned object to stage optional fields, then - must send done to commit. The daemon then pushes session_id and seat, - followed by done, or error if creation failed. + connection. The session is not created yet: the client may send vt, + remote_host, and env on the returned object to stage optional fields, + then must send done to commit. The daemon then pushes session_id and + seat, followed by done, or error if creation failed. @@ -26,9 +26,10 @@ Bound to the connection that created the session. Before done is sent, the session is only staged: vt and remote_host may be sent to set optional fields. is_local is not a field; the session is treated - as remote if remote_host was set, local otherwise. Once created, - destroying this object, explicitly or by disconnecting, tears the - session down if it has not already been destroyed. + as remote if remote_host was set, local otherwise. Environment + variables may also be staged before done. Once created, destroying + this object, explicitly or by disconnecting, tears the session down if + it has not already been destroyed. @@ -43,9 +44,16 @@ + + + Optional. Must be sent before done. May be sent multiple times. + + + + - Creates the session using uid and any staged vt/remote_host. The + Creates the session using uid and any staged vt/remote_host/env. The daemon responds with session_id and seat, followed by done, or with error if creation failed. diff --git a/src/main.rs b/src/main.rs index 9239154..43ceaf9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -177,17 +177,51 @@ impl hyprwire::Dispatch fo } let user = uzers::get_user_by_uid(session.uid).unwrap(); - let mut cmd = process::Command::new(DINIT); - cmd.arg("--user") + let mut envs = BTreeMap::from([ + ( + "HOME".to_string(), + user.home_dir().to_string_lossy().into_owned(), + ), + ( + "USER".to_string(), + user.name().to_string_lossy().into_owned(), + ), + ( + "LOGNAME".to_string(), + user.name().to_string_lossy().into_owned(), + ), + ( + "SHELL".to_string(), + user.shell().to_string_lossy().into_owned(), + ), + ]); + envs.extend( + session + .envs + .iter() + .map(|(key, value)| (key.clone(), value.clone())), + ); + + let mut cmd = process::Command::new("/bin/sh"); + + cmd.arg("-c") + .arg( + r#" + [ -r /etc/profile ] && . /etc/profile + + exec env "$@" + "#, + ) + .arg("dinit-session"); + for (key, value) in envs.iter() { + cmd.arg(format!("{key}={value}")); + } + cmd.arg(DINIT) + .arg("--user") .arg("--services-dir") .arg("/etc/dinit.d/user"); - cmd.uid(session.uid) - .gid(user.primary_group_id()) - .env("HOME", user.home_dir()) - .env("USER", user.name()) - .env("LOGNAME", user.name()) - .env("SHELL", user.shell()); - for (key, value) in session.envs.iter() { + cmd.uid(session.uid).gid(user.primary_group_id()); + for (key, value) in envs.iter() { cmd.env(key, value); } @@ -195,7 +229,7 @@ impl hyprwire::Dispatch fo "spawning {DINIT:?} --user for session {} uid {} with {} environment variables", session.id, session.uid, - session.envs.len() + envs.len() ); let dinit = match cmd.spawn() { Ok(dinit) => dinit, -- 2.54.0