wip: better handling of cloexec with reused fds for panel and notifications daemon
This commit is contained in:
parent
183fc329c1
commit
8bff06e9a7
4 changed files with 122 additions and 30 deletions
89
src/main.rs
89
src/main.rs
|
|
@ -8,7 +8,11 @@ mod process;
|
|||
mod service;
|
||||
mod systemd;
|
||||
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::{
|
||||
ops::Deref,
|
||||
os::fd::AsRawFd,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use async_signals::Signals;
|
||||
use color_eyre::{eyre::WrapErr, Result};
|
||||
|
|
@ -24,6 +28,8 @@ use tracing::{metadata::LevelFilter, Instrument};
|
|||
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
||||
use zbus::ConnectionBuilder;
|
||||
|
||||
use crate::process::{mark_as_cloexec, mark_as_not_cloexec};
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() -> Result<()> {
|
||||
color_eyre::install().wrap_err("failed to install color_eyre error handler")?;
|
||||
|
|
@ -75,10 +81,43 @@ async fn main() -> Result<()> {
|
|||
panel_notifications_fd.as_raw_fd().to_string(),
|
||||
));
|
||||
|
||||
let panel_notifications_fd_pre = Arc::new(Mutex::new(panel_notifications_fd));
|
||||
let panel_notifications_fd_post = panel_notifications_fd_pre.clone();
|
||||
let span = info_span!(parent: None, "cosmic-panel");
|
||||
let stdout_span = span.clone();
|
||||
let stderr_span = span;
|
||||
process_manager
|
||||
.start(
|
||||
Process::new()
|
||||
.with_executable("cosmic-panel")
|
||||
.with_pre_start(move |_, _, _| {
|
||||
let panel_notifications_fd = panel_notifications_fd_pre.clone();
|
||||
let fd = panel_notifications_fd.lock().unwrap();
|
||||
let fd = fd.deref();
|
||||
mark_as_not_cloexec(&fd)
|
||||
.expect("Failed to mark panel notifications socket as not CLOEXEC");
|
||||
})
|
||||
.with_post_start(move |_, _, _| {
|
||||
let panel_notifications_fd = panel_notifications_fd_post.clone();
|
||||
let fd = panel_notifications_fd.lock().unwrap();
|
||||
let fd = fd.deref();
|
||||
mark_as_cloexec(&fd)
|
||||
.expect("Failed to mark panel notifications socket as CLOEXEC");
|
||||
})
|
||||
.with_on_stdout(move |_, _, line| {
|
||||
let stdout_span = stdout_span.clone();
|
||||
async move {
|
||||
info!("{}", line);
|
||||
}
|
||||
.instrument(stdout_span)
|
||||
})
|
||||
.with_on_stderr(move |_, _, line| {
|
||||
let stderr_span = stderr_span.clone();
|
||||
async move {
|
||||
warn!("{}", line);
|
||||
}
|
||||
.instrument(stderr_span)
|
||||
})
|
||||
.with_env(panel_env_vars.clone()),
|
||||
)
|
||||
.await
|
||||
|
|
@ -90,7 +129,53 @@ async fn main() -> Result<()> {
|
|||
daemon_notifications_fd.as_raw_fd().to_string(),
|
||||
));
|
||||
let span = info_span!(parent: None, "cosmic-notifications");
|
||||
start_component("cosmic-notifications", span, &process_manager, &env_vars).await;
|
||||
let stdout_span = span.clone();
|
||||
let stderr_span = span;
|
||||
let daemon_notifications_fd_pre = Arc::new(Mutex::new(daemon_notifications_fd));
|
||||
let daemon_notifications_fd_post = daemon_notifications_fd_pre.clone();
|
||||
|
||||
process_manager
|
||||
.start(
|
||||
Process::new()
|
||||
.with_executable("cosmic-notifications")
|
||||
.with_pre_start(move |_, _, _| {
|
||||
let daemon_notifications_fd = daemon_notifications_fd_pre.clone();
|
||||
let fd = daemon_notifications_fd.lock().unwrap();
|
||||
let fd = fd.deref();
|
||||
mark_as_not_cloexec(&fd)
|
||||
.expect("Failed to mark daemon notifications socket as not CLOEXEC");
|
||||
})
|
||||
.with_post_start(move |_, _, _| {
|
||||
let daemon_notifications_fd = daemon_notifications_fd_post.clone();
|
||||
let fd = daemon_notifications_fd.lock().unwrap();
|
||||
let fd = fd.deref();
|
||||
mark_as_cloexec(&fd)
|
||||
.expect("Failed to mark daemon notifications socket as CLOEXEC");
|
||||
})
|
||||
.with_on_stdout(move |_, _, line| {
|
||||
let stdout_span = stdout_span.clone();
|
||||
async move {
|
||||
info!("{}", line);
|
||||
}
|
||||
.instrument(stdout_span)
|
||||
})
|
||||
.with_on_stderr(move |_, _, line| {
|
||||
let stderr_span = stderr_span.clone();
|
||||
async move {
|
||||
warn!("{}", line);
|
||||
}
|
||||
.instrument(stderr_span)
|
||||
})
|
||||
.with_env(daemon_env_vars.clone()),
|
||||
)
|
||||
.await
|
||||
.expect("failed to start notifications daemon");
|
||||
|
||||
// mark_as_cloexec(&daemon_notifications_fd)
|
||||
// .expect("Failed to mark daemon notifications socket as CLOEXEC");
|
||||
// start_component("cosmic-notifications", span, &process_manager, &env_vars).await;
|
||||
// mark_as_not_cloexec(&daemon_notifications_fd)
|
||||
// .expect("Failed to mark daemon notifications socket as not CLOEXEC");
|
||||
|
||||
let span = info_span!(parent: None, "cosmic-app-library");
|
||||
start_component("cosmic-app-library", span, &process_manager, &env_vars).await;
|
||||
|
|
|
|||
|
|
@ -17,3 +17,18 @@ pub(crate) fn mark_as_not_cloexec(file: &impl AsFd) -> Result<()> {
|
|||
.wrap_err("failed to set CLOEXEC on file")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn mark_as_cloexec(file: &impl AsFd) -> Result<()> {
|
||||
let raw_fd = file.as_fd().as_raw_fd();
|
||||
let fd_flags = fcntl::FdFlag::from_bits(
|
||||
fcntl::fcntl(raw_fd, fcntl::FcntlArg::F_GETFD)
|
||||
.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.union(fcntl::FdFlag::FD_CLOEXEC)),
|
||||
)
|
||||
.wrap_err("failed to set CLOEXEC on file")?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue