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::{
cell::RefCell,
ffi::OsStr,
io::Write,
path::{Path, PathBuf},
process::{Child, Command},
@ -195,17 +196,29 @@ fn start_uinput_service() {
}
#[inline]
fn try_start_server_(user: Option<(String, String)>) -> ResultType<Option<Child>> {
if user.is_some() {
run_as_user(vec!["--server"], user)
} else {
Ok(Some(crate::run_me(vec!["--server"])?))
fn try_start_server_(desktop: Option<&Desktop>) -> ResultType<Option<Child>> {
match desktop {
Some(desktop) => {
let mut envs = vec![];
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]
fn start_server(user: Option<(String, String)>, server: &mut Option<Child>) {
match try_start_server_(user) {
fn start_server(desktop: Option<&Desktop>, server: &mut Option<Child>) {
match try_start_server_(desktop) {
Ok(ps) => *server = ps,
Err(err) => {
log::error!("Failed to start server: {}", err);
@ -257,6 +270,7 @@ fn stop_subprocess() {
fn should_start_server(
try_x11: bool,
is_display_changed: bool,
uid: &mut String,
desktop: &Desktop,
cm0: &mut bool,
@ -273,7 +287,7 @@ fn should_start_server(
*uid = "".to_owned();
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();
if try_x11 {
set_x11_env(&desktop);
@ -335,6 +349,7 @@ pub fn start_os_service() {
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();
let (mut display, mut xauth): (String, String) = ("".to_owned(), "".to_owned());
let mut desktop = Desktop::default();
let mut sid = "".to_owned();
let mut uid = "".to_owned();
@ -357,8 +372,10 @@ pub fn start_os_service() {
// try kill subprocess "--server"
stop_server(&mut user_server);
// try start subprocess "--server"
// No need to check is_display_changed here.
if should_start_server(
true,
false,
&mut uid,
&desktop,
&mut cm0,
@ -373,9 +390,14 @@ pub fn start_os_service() {
// try kill subprocess "--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"
if should_start_server(
false,
is_display_changed,
&mut uid,
&desktop,
&mut cm0,
@ -384,10 +406,7 @@ pub fn start_os_service() {
) {
stop_subprocess();
force_stop_server();
start_server(
Some((desktop.uid.clone(), desktop.username.clone())),
&mut user_server,
);
start_server(Some(&desktop), &mut user_server);
}
} else {
force_stop_server();
@ -541,7 +560,16 @@ fn is_opensuse() -> bool {
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 {
Some(id_name) => 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");
}
let task = Command::new("sudo").args(args).spawn()?;
let task = Command::new("sudo").envs(envs).args(args).spawn()?;
Ok(Some(task))
}
@ -652,7 +680,7 @@ pub(super) fn get_env_tries(name: &str, uid: &str, process: &str, n: usize) -> S
#[inline]
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) {
x.trim_end().to_string()
} else {
@ -887,9 +915,11 @@ mod desktop {
use super::*;
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 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)]
pub struct Desktop {
@ -918,10 +948,30 @@ mod desktop {
self.sid.is_empty() || self.is_rustdesk_subprocess
}
fn get_display(&mut self) {
let display_envs = vec![GNOME_SESSION_BINARY, XFCE4_PANEL, SDDM_GREETER, PLASMA_X11];
for diplay_env in display_envs {
self.display = get_env_tries("DISPLAY", &self.uid, diplay_env, 10);
fn get_display_wayland(&mut self) {
let display_proc = vec![PLASMA_KDED5, GNOME_GOA_DAEMON, RUSTDESK_TRAY];
for proc in display_proc {
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() {
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
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 {
self.xauth = get_env_tries("XAUTHORITY", &self.uid, diplay_env, 10);
if !self.xauth.is_empty() {
@ -1088,16 +1138,22 @@ mod desktop {
self.uid = seat0_values[1].clone();
self.username = seat0_values[2].clone();
self.protocal = get_display_server_of_session(&self.sid).into();
if self.is_wayland() {
if self.is_login_wayland() {
self.display = "".to_owned();
self.xauth = "".to_owned();
self.is_rustdesk_subprocess = false;
return;
}
self.get_display();
self.get_xauth();
self.set_is_subprocess();
if self.is_wayland() {
self.get_display_wayland();
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")]
{
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() {
break;