feat: use privileged sockets
This commit is contained in:
parent
6d0826f319
commit
fd2dc23fac
6 changed files with 186 additions and 42 deletions
47
Cargo.lock
generated
47
Cargo.lock
generated
|
|
@ -61,7 +61,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"parking",
|
"parking",
|
||||||
"polling",
|
"polling",
|
||||||
"rustix",
|
"rustix 0.37.23",
|
||||||
"slab",
|
"slab",
|
||||||
"socket2",
|
"socket2",
|
||||||
"waker-fn",
|
"waker-fn",
|
||||||
|
|
@ -89,7 +89,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"event-listener",
|
"event-listener",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"rustix",
|
"rustix 0.37.23",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
@ -166,6 +166,12 @@ version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
|
|
@ -276,7 +282,7 @@ dependencies = [
|
||||||
"launch-pad",
|
"launch-pad",
|
||||||
"libc",
|
"libc",
|
||||||
"log-panics",
|
"log-panics",
|
||||||
"nix 0.26.2",
|
"rustix 0.38.13",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
"sendfd",
|
"sendfd",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -566,7 +572,7 @@ checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "launch-pad"
|
name = "launch-pad"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pop-os/launch-pad#702bb0531bcd0aca6c17b85e1b516e46f31ddaa1"
|
source = "git+https://github.com/pop-os/launch-pad#4707088eb1111946fc5ea91e9b02ff2737552462"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nix 0.26.2",
|
"nix 0.26.2",
|
||||||
|
|
@ -595,6 +601,12 @@ version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.10"
|
version = "0.4.10"
|
||||||
|
|
@ -680,7 +692,7 @@ version = "0.23.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
|
checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -693,7 +705,7 @@ version = "0.26.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"memoffset 0.7.1",
|
"memoffset 0.7.1",
|
||||||
|
|
@ -796,7 +808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"concurrent-queue",
|
"concurrent-queue",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -875,7 +887,7 @@ version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -934,11 +946,24 @@ version = "0.37.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
|
checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
"errno",
|
"errno",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys 0.3.8",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.4.1",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys 0.4.11",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1117,7 +1142,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"rustix",
|
"rustix 0.37.23",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ futures-util = "0.3"
|
||||||
launch-pad = { git = "https://github.com/pop-os/launch-pad" }
|
launch-pad = { git = "https://github.com/pop-os/launch-pad" }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log-panics = { version = "2", features = ["with-backtrace"] }
|
log-panics = { version = "2", features = ["with-backtrace"] }
|
||||||
nix = { version = "0.26", features = ["fs"], default-features = false }
|
rustix = "0.38"
|
||||||
scopeguard = "1"
|
scopeguard = "1"
|
||||||
sendfd = { version = "0.4", features = ["tokio"] }
|
sendfd = { version = "0.4", features = ["tokio"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
|
||||||
32
src/comp.rs
32
src/comp.rs
|
|
@ -101,6 +101,31 @@ async fn receive_ipc(state: &mut IpcState, rx: &mut OwnedReadHalf) -> Result<()>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_privileged_socket(
|
||||||
|
sockets: &mut Vec<UnixStream>,
|
||||||
|
env_vars: &[(String, String)],
|
||||||
|
) -> Result<(Vec<(String, String)>, OwnedFd)> {
|
||||||
|
// Create a new pair of unnamed Unix sockets
|
||||||
|
let (comp_socket, client_socket) =
|
||||||
|
UnixStream::pair().wrap_err("failed to create socket pair")?;
|
||||||
|
// Push one socket to the list of sockets we were passed
|
||||||
|
sockets.push(comp_socket);
|
||||||
|
// Turn the other socket into a non-blocking fd, which we can pass to the child
|
||||||
|
// process
|
||||||
|
let client_fd = {
|
||||||
|
let std_stream = client_socket
|
||||||
|
.into_std()
|
||||||
|
.wrap_err("failed to convert client socket to std socket")?;
|
||||||
|
std_stream
|
||||||
|
.set_nonblocking(true)
|
||||||
|
.wrap_err("failed to mark client socket as non-blocking")?;
|
||||||
|
OwnedFd::from(std_stream)
|
||||||
|
};
|
||||||
|
let mut env_vars = env_vars.to_vec();
|
||||||
|
env_vars.push(("WAYLAND_SOCKET".into(), client_fd.as_raw_fd().to_string()));
|
||||||
|
Ok((env_vars, client_fd))
|
||||||
|
}
|
||||||
|
|
||||||
async fn send_fd(session_tx: &mut OwnedWriteHalf, stream: Vec<UnixStream>) -> Result<()> {
|
async fn send_fd(session_tx: &mut OwnedWriteHalf, stream: Vec<UnixStream>) -> Result<()> {
|
||||||
// Turn our list of Unix streams into non-blocking file descriptors.
|
// Turn our list of Unix streams into non-blocking file descriptors.
|
||||||
let fds = stream
|
let fds = stream
|
||||||
|
|
@ -134,12 +159,15 @@ async fn send_fd(session_tx: &mut OwnedWriteHalf, stream: Vec<UnixStream>) -> Re
|
||||||
tokio::time::sleep(std::time::Duration::from_micros(100)).await;
|
tokio::time::sleep(std::time::Duration::from_micros(100)).await;
|
||||||
// Send our file descriptors.
|
// Send our file descriptors.
|
||||||
let fd: &UnixStream = session_tx.as_ref();
|
let fd: &UnixStream = session_tx.as_ref();
|
||||||
|
info!("sending {} fds", fds.len());
|
||||||
|
|
||||||
fd.send_with_fd(
|
fd.send_with_fd(
|
||||||
&[0],
|
&[0],
|
||||||
&fds.iter().map(|fd| fd.as_raw_fd()).collect::<Vec<_>>(),
|
&fds.into_iter()
|
||||||
|
.map(|fd| fd.into_raw_fd())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
)
|
)
|
||||||
.wrap_err("failed to send fd")?;
|
.wrap_err("failed to send fd")?;
|
||||||
info!("sent {} fds", fds.len());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
81
src/main.rs
81
src/main.rs
|
|
@ -9,17 +9,19 @@ mod service;
|
||||||
mod systemd;
|
mod systemd;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
os::fd::AsRawFd,
|
os::fd::{AsRawFd, IntoRawFd},
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_signals::Signals;
|
use async_signals::Signals;
|
||||||
use color_eyre::{eyre::WrapErr, Result};
|
use color_eyre::{eyre::WrapErr, Result};
|
||||||
|
use comp::create_privileged_socket;
|
||||||
use cosmic_notifications_util::{DAEMON_NOTIFICATIONS_FD, PANEL_NOTIFICATIONS_FD};
|
use cosmic_notifications_util::{DAEMON_NOTIFICATIONS_FD, PANEL_NOTIFICATIONS_FD};
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
use launch_pad::{process::Process, ProcessManager};
|
use launch_pad::{process::Process, ProcessManager};
|
||||||
use service::SessionRequest;
|
use service::SessionRequest;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
|
net::UnixStream,
|
||||||
sync::{
|
sync::{
|
||||||
mpsc::{self, Receiver, Sender},
|
mpsc::{self, Receiver, Sender},
|
||||||
oneshot,
|
oneshot,
|
||||||
|
|
@ -99,7 +101,7 @@ async fn start(
|
||||||
))
|
))
|
||||||
.await;
|
.await;
|
||||||
let token = CancellationToken::new();
|
let token = CancellationToken::new();
|
||||||
let (_, socket_rx) = mpsc::unbounded_channel();
|
let (socket_tx, socket_rx) = mpsc::unbounded_channel();
|
||||||
let (env_tx, env_rx) = oneshot::channel();
|
let (env_tx, env_rx) = oneshot::channel();
|
||||||
let compositor_handle = comp::run_compositor(
|
let compositor_handle = comp::run_compositor(
|
||||||
&process_manager,
|
&process_manager,
|
||||||
|
|
@ -160,6 +162,7 @@ async fn start(
|
||||||
panel_key.clone(),
|
panel_key.clone(),
|
||||||
panel_env_vars.clone(),
|
panel_env_vars.clone(),
|
||||||
panel_notifications_fd.as_raw_fd(),
|
panel_notifications_fd.as_raw_fd(),
|
||||||
|
socket_tx.clone(),
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.expect("failed to start notifications daemon"),
|
.expect("failed to start notifications daemon"),
|
||||||
|
|
@ -180,6 +183,7 @@ async fn start(
|
||||||
notif_key,
|
notif_key,
|
||||||
daemon_env_vars,
|
daemon_env_vars,
|
||||||
daemon_notifications_fd.as_raw_fd(),
|
daemon_notifications_fd.as_raw_fd(),
|
||||||
|
socket_tx.clone(),
|
||||||
))
|
))
|
||||||
.await
|
.await
|
||||||
.expect("failed to start panel"),
|
.expect("failed to start panel"),
|
||||||
|
|
@ -187,19 +191,40 @@ async fn start(
|
||||||
drop(guard);
|
drop(guard);
|
||||||
|
|
||||||
let span = info_span!(parent: None, "cosmic-app-library");
|
let span = info_span!(parent: None, "cosmic-app-library");
|
||||||
start_component("cosmic-app-library", span, &process_manager, &env_vars).await;
|
start_component(
|
||||||
|
"cosmic-app-library",
|
||||||
|
span,
|
||||||
|
&process_manager,
|
||||||
|
&env_vars,
|
||||||
|
&socket_tx,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let span = info_span!(parent: None, "cosmic-launcher");
|
let span = info_span!(parent: None, "cosmic-launcher");
|
||||||
start_component("cosmic-launcher", span, &process_manager, &env_vars).await;
|
start_component(
|
||||||
|
"cosmic-launcher",
|
||||||
|
span,
|
||||||
|
&process_manager,
|
||||||
|
&env_vars,
|
||||||
|
&socket_tx,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let span = info_span!(parent: None, "cosmic-workspaces");
|
let span = info_span!(parent: None, "cosmic-workspaces");
|
||||||
start_component("cosmic-workspaces", span, &process_manager, &env_vars).await;
|
start_component(
|
||||||
|
"cosmic-workspaces",
|
||||||
|
span,
|
||||||
|
&process_manager,
|
||||||
|
&env_vars,
|
||||||
|
&socket_tx,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let span = info_span!(parent: None, "cosmic-osd");
|
let span = info_span!(parent: None, "cosmic-osd");
|
||||||
start_component("cosmic-osd", span, &process_manager, &env_vars).await;
|
start_component("cosmic-osd", span, &process_manager, &env_vars, &socket_tx).await;
|
||||||
|
|
||||||
let span = info_span!(parent: None, "cosmic-bg");
|
let span = info_span!(parent: None, "cosmic-bg");
|
||||||
start_component("cosmic-bg", span, &process_manager, &env_vars).await;
|
start_component("cosmic-bg", span, &process_manager, &env_vars, &socket_tx).await;
|
||||||
|
|
||||||
let span = info_span!(parent: None, "xdg-desktop-portal-cosmic");
|
let span = info_span!(parent: None, "xdg-desktop-portal-cosmic");
|
||||||
start_component(
|
start_component(
|
||||||
|
|
@ -207,6 +232,7 @@ async fn start(
|
||||||
span,
|
span,
|
||||||
&process_manager,
|
&process_manager,
|
||||||
&env_vars,
|
&env_vars,
|
||||||
|
&socket_tx,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|
@ -258,9 +284,18 @@ async fn start_component(
|
||||||
span: tracing::Span,
|
span: tracing::Span,
|
||||||
process_manager: &ProcessManager,
|
process_manager: &ProcessManager,
|
||||||
env_vars: &[(String, String)],
|
env_vars: &[(String, String)],
|
||||||
|
socket_tx: &mpsc::UnboundedSender<Vec<UnixStream>>,
|
||||||
) {
|
) {
|
||||||
|
let mut sockets = Vec::with_capacity(1);
|
||||||
|
let (env_vars, fd) = create_privileged_socket(&mut sockets, env_vars).unwrap();
|
||||||
|
let fd = fd.into_raw_fd();
|
||||||
|
if let Err(why) = socket_tx.send(sockets) {
|
||||||
|
error!(?why, "Failed to send the privileged socket");
|
||||||
|
}
|
||||||
|
let socket_tx_clone = socket_tx.clone();
|
||||||
let stdout_span = span.clone();
|
let stdout_span = span.clone();
|
||||||
let stderr_span = span.clone();
|
let stderr_span = span.clone();
|
||||||
|
let cmd_clone = cmd.to_string();
|
||||||
process_manager
|
process_manager
|
||||||
.start(
|
.start(
|
||||||
Process::new()
|
Process::new()
|
||||||
|
|
@ -279,7 +314,37 @@ async fn start_component(
|
||||||
warn!("{}", line);
|
warn!("{}", line);
|
||||||
}
|
}
|
||||||
.instrument(stderr_span)
|
.instrument(stderr_span)
|
||||||
}),
|
})
|
||||||
|
.with_on_exit(move |mut pman, key, err_code, will_restart| {
|
||||||
|
if let Some(err) = err_code {
|
||||||
|
error!("{cmd_clone} exited with error {}", err.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let socket_tx_clone = socket_tx_clone.clone();
|
||||||
|
async move {
|
||||||
|
if !will_restart {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut sockets = Vec::with_capacity(1);
|
||||||
|
let env_vars = Vec::with_capacity(1);
|
||||||
|
let (env_vars, new_fd) =
|
||||||
|
create_privileged_socket(&mut sockets, &env_vars).unwrap();
|
||||||
|
|
||||||
|
let new_fd = new_fd.into_raw_fd();
|
||||||
|
|
||||||
|
if let Err(why) = socket_tx_clone.send(sockets) {
|
||||||
|
error!(?why, "Failed to send the privileged socket");
|
||||||
|
}
|
||||||
|
if let Err(why) = pman.update_process_env(&key, env_vars).await {
|
||||||
|
error!(?why, "Failed to update environment variables");
|
||||||
|
}
|
||||||
|
if let Err(why) = pman.update_process_fds(&key, move || vec![new_fd]).await
|
||||||
|
{
|
||||||
|
error!(?why, "Failed to update fds");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.with_fds(move || vec![fd]),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.expect(&format!("failed to start {}", cmd));
|
.expect(&format!("failed to start {}", cmd));
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,14 @@ use color_eyre::eyre::Context;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use launch_pad::process::Process;
|
use launch_pad::process::Process;
|
||||||
use launch_pad::ProcessKey;
|
use launch_pad::ProcessKey;
|
||||||
use std::os::fd::{OwnedFd, RawFd};
|
use std::os::fd::{IntoRawFd, OwnedFd, RawFd};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use tokio::sync::mpsc;
|
||||||
use tracing::Instrument;
|
use tracing::Instrument;
|
||||||
|
|
||||||
|
use crate::comp::create_privileged_socket;
|
||||||
|
|
||||||
pub fn create_socket() -> Result<(OwnedFd, OwnedFd)> {
|
pub fn create_socket() -> Result<(OwnedFd, OwnedFd)> {
|
||||||
// Create a new pair of unnamed Unix sockets
|
// Create a new pair of unnamed Unix sockets
|
||||||
let (sock_1, sock_2) = UnixStream::pair().wrap_err("failed to create socket pair")?;
|
let (sock_1, sock_2) = UnixStream::pair().wrap_err("failed to create socket pair")?;
|
||||||
|
|
@ -28,20 +31,28 @@ pub fn notifications_process(
|
||||||
span: tracing::Span,
|
span: tracing::Span,
|
||||||
cmd: &'static str,
|
cmd: &'static str,
|
||||||
key: Arc<Mutex<Option<ProcessKey>>>,
|
key: Arc<Mutex<Option<ProcessKey>>>,
|
||||||
env_vars: Vec<(String, String)>,
|
mut env_vars: Vec<(String, String)>,
|
||||||
fd: RawFd,
|
fd: RawFd,
|
||||||
restart_span: tracing::Span,
|
restart_span: tracing::Span,
|
||||||
restart_cmd: &'static str,
|
restart_cmd: &'static str,
|
||||||
restart_key: Arc<Mutex<Option<ProcessKey>>>,
|
restart_key: Arc<Mutex<Option<ProcessKey>>>,
|
||||||
restart_env_vars: Vec<(String, String)>,
|
restart_env_vars: Vec<(String, String)>,
|
||||||
restart_fd: RawFd,
|
restart_fd: RawFd,
|
||||||
|
socket_tx: mpsc::UnboundedSender<Vec<tokio::net::UnixStream>>,
|
||||||
) -> Process {
|
) -> Process {
|
||||||
|
env_vars.retain(|v| &v.0 != "WAYLAND_SOCKET");
|
||||||
|
|
||||||
let stdout_span = span.clone();
|
let stdout_span = span.clone();
|
||||||
let stderr_span = span.clone();
|
let stderr_span = span.clone();
|
||||||
|
let mut sockets = Vec::with_capacity(1);
|
||||||
|
let (env_vars, privileged_fd) = create_privileged_socket(&mut sockets, &env_vars).unwrap();
|
||||||
|
_ = socket_tx.send(sockets);
|
||||||
let env_clone = env_vars.clone();
|
let env_clone = env_vars.clone();
|
||||||
|
let socket_tx_clone = socket_tx.clone();
|
||||||
|
let privileged_fd = privileged_fd.into_raw_fd();
|
||||||
Process::new()
|
Process::new()
|
||||||
.with_executable(cmd)
|
.with_executable(cmd)
|
||||||
.with_fds(move || vec![fd])
|
.with_fds(move || vec![privileged_fd, fd])
|
||||||
.with_on_stdout(move |_, _, line| {
|
.with_on_stdout(move |_, _, line| {
|
||||||
let stdout_span = stdout_span.clone();
|
let stdout_span = stdout_span.clone();
|
||||||
async move {
|
async move {
|
||||||
|
|
@ -56,7 +67,7 @@ pub fn notifications_process(
|
||||||
}
|
}
|
||||||
.instrument(stderr_span)
|
.instrument(stderr_span)
|
||||||
})
|
})
|
||||||
.with_on_exit(move |pman, _, _, will_restart| {
|
.with_on_exit(move |pman, my_key, _, will_restart| {
|
||||||
// force restart of notifications / panel when the other exits
|
// force restart of notifications / panel when the other exits
|
||||||
let new_process = notifications_process(
|
let new_process = notifications_process(
|
||||||
restart_span.clone(),
|
restart_span.clone(),
|
||||||
|
|
@ -69,13 +80,37 @@ pub fn notifications_process(
|
||||||
key.clone(),
|
key.clone(),
|
||||||
env_clone.clone(),
|
env_clone.clone(),
|
||||||
fd,
|
fd,
|
||||||
|
socket_tx_clone.clone(),
|
||||||
);
|
);
|
||||||
let restart_key = restart_key.clone();
|
let restart_key = restart_key.clone();
|
||||||
|
let socket_tx_clone = socket_tx_clone.clone();
|
||||||
|
|
||||||
|
let env_clone = env_clone.clone();
|
||||||
|
let mut pman_clone = pman.clone();
|
||||||
async move {
|
async move {
|
||||||
if will_restart {
|
if will_restart {
|
||||||
|
let mut sockets = Vec::with_capacity(1);
|
||||||
|
let (env_vars, new_fd) =
|
||||||
|
create_privileged_socket(&mut sockets, &env_clone).unwrap();
|
||||||
|
|
||||||
|
let new_fd = new_fd.into_raw_fd();
|
||||||
|
|
||||||
|
if let Err(why) = socket_tx_clone.send(sockets) {
|
||||||
|
error!(?why, "Failed to send the privileged socket");
|
||||||
|
}
|
||||||
|
if let Err(why) = pman_clone.update_process_env(&my_key, env_vars).await {
|
||||||
|
error!(?why, "Failed to update environment variables");
|
||||||
|
}
|
||||||
|
if let Err(why) = pman_clone
|
||||||
|
.update_process_fds(&my_key, move || vec![new_fd, fd])
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
error!(?why, "Failed to update fds");
|
||||||
|
}
|
||||||
|
|
||||||
let Some(old) = restart_key.lock().unwrap().clone() else {
|
let Some(old) = restart_key.lock().unwrap().clone() else {
|
||||||
error!("Couldn't stop previous invocation of {}", cmd);
|
error!("Couldn't stop previous invocation of {}", cmd);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
_ = pman.stop_process(old).await;
|
_ = pman.stop_process(old).await;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,10 @@
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
use color_eyre::eyre::{ContextCompat, Result, WrapErr};
|
use color_eyre::eyre::{Result, WrapErr};
|
||||||
use nix::fcntl;
|
use rustix::io::FdFlags;
|
||||||
use std::os::unix::prelude::*;
|
use std::os::unix::prelude::*;
|
||||||
|
|
||||||
pub(crate) fn mark_as_not_cloexec(file: &impl AsFd) -> Result<()> {
|
pub(crate) fn mark_as_not_cloexec(file: &impl AsFd) -> Result<()> {
|
||||||
let raw_fd = file.as_fd().as_raw_fd();
|
let flags = rustix::io::fcntl_getfd(file).wrap_err("failed to get GETFD value of stream")?;
|
||||||
let fd_flags = fcntl::FdFlag::from_bits(
|
rustix::io::fcntl_setfd(file, flags.difference(FdFlags::CLOEXEC))
|
||||||
fcntl::fcntl(raw_fd, fcntl::FcntlArg::F_GETFD)
|
.wrap_err("failed to unset CLOEXEC on file")
|
||||||
.wrap_err("failed to get GETFD value of stream")?,
|
|
||||||
)
|
|
||||||
.wrap_err("failed to get fd flags from file")?;
|
|
||||||
fcntl::fcntl(
|
|
||||||
raw_fd,
|
|
||||||
fcntl::FcntlArg::F_SETFD(fd_flags.difference(fcntl::FdFlag::FD_CLOEXEC)),
|
|
||||||
)
|
|
||||||
.wrap_err("failed to set CLOEXEC on file")?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue