fix, wayland --server, envs

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2023-10-06 21:31:37 +08:00
parent 3907cc679a
commit da7bcf89d4
2 changed files with 88 additions and 28 deletions

View File

@ -14,6 +14,7 @@ use hbb_common::{
}; };
use std::{ use std::{
cell::RefCell, cell::RefCell,
ffi::OsStr,
io::Write, io::Write,
path::{Path, PathBuf}, path::{Path, PathBuf},
process::{Child, Command}, process::{Child, Command},
@ -195,17 +196,29 @@ fn start_uinput_service() {
} }
#[inline] #[inline]
fn try_start_server_(user: Option<(String, String)>) -> ResultType<Option<Child>> { fn try_start_server_(desktop: Option<&Desktop>) -> ResultType<Option<Child>> {
if user.is_some() { match desktop {
run_as_user(vec!["--server"], user) Some(desktop) => {
} else { let mut envs = vec![];
Ok(Some(crate::run_me(vec!["--server"])?)) if !desktop.display.is_empty() {
envs.push(("DISPLAY", desktop.display.clone()));
}
if !desktop.xauth.is_empty() {
envs.push(("XAUTHORITY", desktop.xauth.clone()));
}
run_as_user(
vec!["--server"],
Some((desktop.uid.clone(), desktop.username.clone())),
envs,
)
}
None => Ok(Some(crate::run_me(vec!["--server"])?)),
} }
} }
#[inline] #[inline]
fn start_server(user: Option<(String, String)>, server: &mut Option<Child>) { fn start_server(desktop: Option<&Desktop>, server: &mut Option<Child>) {
match try_start_server_(user) { match try_start_server_(desktop) {
Ok(ps) => *server = ps, Ok(ps) => *server = ps,
Err(err) => { Err(err) => {
log::error!("Failed to start server: {}", err); log::error!("Failed to start server: {}", err);
@ -257,6 +270,7 @@ fn stop_subprocess() {
fn should_start_server( fn should_start_server(
try_x11: bool, try_x11: bool,
is_display_changed: bool,
uid: &mut String, uid: &mut String,
desktop: &Desktop, desktop: &Desktop,
cm0: &mut bool, cm0: &mut bool,
@ -273,7 +287,7 @@ fn should_start_server(
*uid = "".to_owned(); *uid = "".to_owned();
should_kill = true; should_kill = true;
} }
} else if desktop.uid != *uid && !desktop.uid.is_empty() { } else if is_display_changed || desktop.uid != *uid && !desktop.uid.is_empty() {
*uid = desktop.uid.clone(); *uid = desktop.uid.clone();
if try_x11 { if try_x11 {
set_x11_env(&desktop); set_x11_env(&desktop);
@ -335,6 +349,7 @@ pub fn start_os_service() {
let running = Arc::new(AtomicBool::new(true)); let running = Arc::new(AtomicBool::new(true));
let r = running.clone(); let r = running.clone();
let (mut display, mut xauth): (String, String) = ("".to_owned(), "".to_owned());
let mut desktop = Desktop::default(); let mut desktop = Desktop::default();
let mut sid = "".to_owned(); let mut sid = "".to_owned();
let mut uid = "".to_owned(); let mut uid = "".to_owned();
@ -357,8 +372,10 @@ pub fn start_os_service() {
// try kill subprocess "--server" // try kill subprocess "--server"
stop_server(&mut user_server); stop_server(&mut user_server);
// try start subprocess "--server" // try start subprocess "--server"
// No need to check is_display_changed here.
if should_start_server( if should_start_server(
true, true,
false,
&mut uid, &mut uid,
&desktop, &desktop,
&mut cm0, &mut cm0,
@ -373,9 +390,14 @@ pub fn start_os_service() {
// try kill subprocess "--server" // try kill subprocess "--server"
stop_server(&mut server); stop_server(&mut server);
let is_display_changed = desktop.display != display || desktop.xauth != xauth;
display = desktop.display.clone();
xauth = desktop.xauth.clone();
// try start subprocess "--server" // try start subprocess "--server"
if should_start_server( if should_start_server(
false, false,
is_display_changed,
&mut uid, &mut uid,
&desktop, &desktop,
&mut cm0, &mut cm0,
@ -384,10 +406,7 @@ pub fn start_os_service() {
) { ) {
stop_subprocess(); stop_subprocess();
force_stop_server(); force_stop_server();
start_server( start_server(Some(&desktop), &mut user_server);
Some((desktop.uid.clone(), desktop.username.clone())),
&mut user_server,
);
} }
} else { } else {
force_stop_server(); force_stop_server();
@ -541,7 +560,16 @@ fn is_opensuse() -> bool {
false false
} }
pub fn run_as_user(arg: Vec<&str>, user: Option<(String, String)>) -> ResultType<Option<Child>> { pub fn run_as_user<I, K, V>(
arg: Vec<&str>,
user: Option<(String, String)>,
envs: I,
) -> ResultType<Option<Child>>
where
I: IntoIterator<Item = (K, V)>,
K: AsRef<OsStr>,
V: AsRef<OsStr>,
{
let (uid, username) = match user { let (uid, username) = match user {
Some(id_name) => id_name, Some(id_name) => id_name,
None => get_active_user_id_name(), None => get_active_user_id_name(),
@ -558,7 +586,7 @@ pub fn run_as_user(arg: Vec<&str>, user: Option<(String, String)>) -> ResultType
args.insert(0, "-E"); args.insert(0, "-E");
} }
let task = Command::new("sudo").args(args).spawn()?; let task = Command::new("sudo").envs(envs).args(args).spawn()?;
Ok(Some(task)) Ok(Some(task))
} }
@ -652,7 +680,7 @@ pub(super) fn get_env_tries(name: &str, uid: &str, process: &str, n: usize) -> S
#[inline] #[inline]
fn get_env(name: &str, uid: &str, process: &str) -> String { fn get_env(name: &str, uid: &str, process: &str) -> String {
let cmd = format!("ps -u {} -f | grep '{}' | grep -v 'grep' | tail -1 | awk '{{print $2}}' | xargs -I__ cat /proc/__/environ 2>/dev/null | tr '\\0' '\\n' | grep '^{}=' | tail -1 | sed 's/{}=//g'", uid, process, name, name); let cmd = format!("ps -u {} -f | grep -E '{}' | grep -v 'grep' | tail -1 | awk '{{print $2}}' | xargs -I__ cat /proc/__/environ 2>/dev/null | tr '\\0' '\\n' | grep '^{}=' | tail -1 | sed 's/{}=//g'", uid, process, name, name);
if let Ok(x) = run_cmds(&cmd) { if let Ok(x) = run_cmds(&cmd) {
x.trim_end().to_string() x.trim_end().to_string()
} else { } else {
@ -887,9 +915,11 @@ mod desktop {
use super::*; use super::*;
pub const XFCE4_PANEL: &str = "xfce4-panel"; pub const XFCE4_PANEL: &str = "xfce4-panel";
pub const GNOME_SESSION_BINARY: &str = "gnome-session-binary";
pub const SDDM_GREETER: &str = "sddm-greeter"; pub const SDDM_GREETER: &str = "sddm-greeter";
pub const PLASMA_X11: &str = "startplasma-x11";
const PLASMA_KDED5: &str = "kded5";
const GNOME_GOA_DAEMON: &str = "goa-daemon";
const RUSTDESK_TRAY: &str = "rustdesk +--tray";
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
pub struct Desktop { pub struct Desktop {
@ -918,10 +948,30 @@ mod desktop {
self.sid.is_empty() || self.is_rustdesk_subprocess self.sid.is_empty() || self.is_rustdesk_subprocess
} }
fn get_display(&mut self) { fn get_display_wayland(&mut self) {
let display_envs = vec![GNOME_SESSION_BINARY, XFCE4_PANEL, SDDM_GREETER, PLASMA_X11]; let display_proc = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, RUSTDESK_TRAY];
for diplay_env in display_envs { for proc in display_proc {
self.display = get_env_tries("DISPLAY", &self.uid, diplay_env, 10); self.display = get_env("DISPLAY", &self.uid, proc);
if !self.display.is_empty() {
break;
}
}
}
fn get_xauth_wayland(&mut self) {
let display_proc = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, RUSTDESK_TRAY];
for proc in display_proc {
self.xauth = get_env("XAUTHORITY", &self.uid, proc);
if !self.xauth.is_empty() {
break;
}
}
}
fn get_display_x11(&mut self) {
let display_envs = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, XFCE4_PANEL, SDDM_GREETER];
for display_env in display_envs {
self.display = get_env_tries("DISPLAY", &self.uid, display_env, 10);
if !self.display.is_empty() { if !self.display.is_empty() {
break; break;
} }
@ -980,9 +1030,9 @@ mod desktop {
} }
} }
fn get_xauth(&mut self) { fn get_xauth_x11(&mut self) {
// try by direct access to window manager process by name // try by direct access to window manager process by name
let display_envs = vec![GNOME_SESSION_BINARY, XFCE4_PANEL, SDDM_GREETER, PLASMA_X11]; let display_envs = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, XFCE4_PANEL, SDDM_GREETER];
for diplay_env in display_envs { for diplay_env in display_envs {
self.xauth = get_env_tries("XAUTHORITY", &self.uid, diplay_env, 10); self.xauth = get_env_tries("XAUTHORITY", &self.uid, diplay_env, 10);
if !self.xauth.is_empty() { if !self.xauth.is_empty() {
@ -1088,16 +1138,22 @@ mod desktop {
self.uid = seat0_values[1].clone(); self.uid = seat0_values[1].clone();
self.username = seat0_values[2].clone(); self.username = seat0_values[2].clone();
self.protocal = get_display_server_of_session(&self.sid).into(); self.protocal = get_display_server_of_session(&self.sid).into();
if self.is_wayland() { if self.is_login_wayland() {
self.display = "".to_owned(); self.display = "".to_owned();
self.xauth = "".to_owned(); self.xauth = "".to_owned();
self.is_rustdesk_subprocess = false; self.is_rustdesk_subprocess = false;
return; return;
} }
self.get_display(); if self.is_wayland() {
self.get_xauth(); self.get_display_wayland();
self.set_is_subprocess(); self.get_xauth_wayland();
self.is_rustdesk_subprocess = false;
} else {
self.get_display_x11();
self.get_xauth_x11();
self.set_is_subprocess();
}
} }
} }
} }

View File

@ -2522,7 +2522,11 @@ async fn start_ipc(
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
{ {
log::debug!("Start cm"); log::debug!("Start cm");
res = crate::platform::run_as_user(args.clone(), user.clone()); res = crate::platform::run_as_user(
args.clone(),
user.clone(),
None::<(&str, &str)>,
);
} }
if res.is_ok() { if res.is_ok() {
break; break;