From abff2fd7feb8eb7f5f97714b8413d99547aca309 Mon Sep 17 00:00:00 2001 From: Vladislav Yaroslavlev Date: Mon, 13 Apr 2026 00:21:19 +0300 Subject: [PATCH] fix(maestro): restore Windows build (missing run_inner) The full runtime entry was gated with #[cfg(unix)] while run() still called run_inner() on non-Unix targets, causing E0425 on Windows (issue #690). Extract shared pipeline into run_telemt_core with a post-bind hook for Unix privilege dropping; provide cfg-split run_inner wrappers. Fixes https://github.com/telemt/telemt/issues/690 Made-with: Cursor --- src/maestro/mod.rs | 73 ++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/src/maestro/mod.rs b/src/maestro/mod.rs index 00b3b2d..5f3cb69 100644 --- a/src/maestro/mod.rs +++ b/src/maestro/mod.rs @@ -81,23 +81,9 @@ pub async fn run() -> std::result::Result<(), Box> { } } -#[cfg(unix)] -async fn run_inner( - daemon_opts: DaemonOptions, -) -> std::result::Result<(), Box> { - // Acquire PID file if daemonizing or if explicitly requested - // Keep it alive until shutdown (underscore prefix = intentionally kept for RAII cleanup) - let _pid_file = if daemon_opts.daemonize || daemon_opts.pid_file.is_some() { - let mut pf = PidFile::new(daemon_opts.pid_file_path()); - if let Err(e) = pf.acquire() { - eprintln!("[telemt] {}", e); - std::process::exit(1); - } - Some(pf) - } else { - None - }; - +// Shared maestro startup and main loop. `drop_after_bind` runs on Unix after listeners are bound +// (for privilege drop); it is a no-op on other platforms. +async fn run_telemt_core(drop_after_bind: impl FnOnce()) -> std::result::Result<(), Box> { let process_started_at = Instant::now(); let process_started_at_epoch_secs = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -761,17 +747,8 @@ async fn run_inner( std::process::exit(1); } - // Drop privileges after binding sockets (which may require root for port < 1024) - if daemon_opts.user.is_some() || daemon_opts.group.is_some() { - if let Err(e) = drop_privileges( - daemon_opts.user.as_deref(), - daemon_opts.group.as_deref(), - _pid_file.as_ref(), - ) { - error!(error = %e, "Failed to drop privileges"); - std::process::exit(1); - } - } + // On Unix, caller supplies privilege drop after bind (may require root for port < 1024). + drop_after_bind(); runtime_tasks::apply_runtime_log_filter( has_rust_log, @@ -819,3 +796,43 @@ async fn run_inner( Ok(()) } + +#[cfg(unix)] +async fn run_inner( + daemon_opts: DaemonOptions, +) -> std::result::Result<(), Box> { + // Acquire PID file if daemonizing or if explicitly requested + // Keep it alive until shutdown (underscore prefix = intentionally kept for RAII cleanup) + let _pid_file = if daemon_opts.daemonize || daemon_opts.pid_file.is_some() { + let mut pf = PidFile::new(daemon_opts.pid_file_path()); + if let Err(e) = pf.acquire() { + eprintln!("[telemt] {}", e); + std::process::exit(1); + } + Some(pf) + } else { + None + }; + + let user = daemon_opts.user.clone(); + let group = daemon_opts.group.clone(); + + run_telemt_core(|| { + if user.is_some() || group.is_some() { + if let Err(e) = drop_privileges( + user.as_deref(), + group.as_deref(), + _pid_file.as_ref(), + ) { + error!(error = %e, "Failed to drop privileges"); + std::process::exit(1); + } + } + }) + .await +} + +#[cfg(not(unix))] +async fn run_inner() -> std::result::Result<(), Box> { + run_telemt_core(|| {}).await +}