diff --git a/cli/src/commands/args.rs b/cli/src/commands/args.rs index cd07bbc5198..f672fc5fc13 100644 --- a/cli/src/commands/args.rs +++ b/cli/src/commands/args.rs @@ -547,15 +547,13 @@ pub struct TunnelServeArgs { #[clap(long)] pub random_name: bool, - /// Sets the machine name for port forwarding service #[clap(long)] pub name: Option, /// Optional parent process id. If provided, the server will be stopped when the process of the given pid no longer exists #[clap(long, hide = true)] - pub parent_process_id: Option, - + pub parent_process_id: Option, } #[derive(Args, Debug, Clone)] diff --git a/cli/src/commands/tunnels.rs b/cli/src/commands/tunnels.rs index eee1c27dc32..3e332685a64 100644 --- a/cli/src/commands/tunnels.rs +++ b/cli/src/commands/tunnels.rs @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ use async_trait::async_trait; +use std::str::FromStr; use std::fmt; use sysinfo::{Pid, SystemExt}; use tokio::sync::mpsc; @@ -94,6 +95,7 @@ impl ServiceContainer for TunnelServiceContainer { pub enum ShutdownSignal { CtrlC, ParentProcessKilled, + ServiceStopped, } impl fmt::Display for ShutdownSignal { @@ -101,6 +103,7 @@ impl fmt::Display for ShutdownSignal { match self { ShutdownSignal::CtrlC => write!(f, "Ctrl-C received"), ShutdownSignal::ParentProcessKilled => write!(f, "Parent process no longer exists"), + ShutdownSignal::ServiceStopped => write!(f, "Service stopped"), } } } @@ -241,7 +244,8 @@ async fn serve_with_csa( let tunnel = if let Some(d) = gateway_args.tunnel.clone().into() { dt.start_existing_tunnel(d).await } else { - dt.start_new_launcher_tunnel(gateway_args.name, gateway_args.random_name).await + dt.start_new_launcher_tunnel(gateway_args.name, gateway_args.random_name) + .await }?; let shutdown_tx = if let Some(tx) = shutdown_rx { @@ -249,19 +253,22 @@ async fn serve_with_csa( } else { let (tx, rx) = mpsc::channel::(2); if let Some(process_id) = gateway_args.parent_process_id { - let tx = tx.clone(); - info!(log, "checking for parent process {}", process_id); - tokio::spawn(async move { - let mut s = sysinfo::System::new(); - #[cfg(windows)] - let pid = Pid::from(process_id as usize); - #[cfg(unix)] - let pid = Pid::from(process_id); - while s.refresh_process(pid) { - sleep(Duration::from_millis(2000)).await; + match Pid::from_str(&process_id) { + Ok(pid) => { + let tx = tx.clone(); + info!(log, "checking for parent process {}", process_id); + tokio::spawn(async move { + let mut s = sysinfo::System::new(); + while s.refresh_process(pid) { + sleep(Duration::from_millis(2000)).await; + } + tx.send(ShutdownSignal::ParentProcessKilled).await.ok(); + }); } - tx.send(ShutdownSignal::ParentProcessKilled).await.ok(); - }); + Err(_) => { + info!(log, "invalid parent process id: {}", process_id); + } + } } tokio::spawn(async move { tokio::signal::ctrl_c().await.ok(); diff --git a/cli/src/tunnels/service_windows.rs b/cli/src/tunnels/service_windows.rs index 4c2b1c8d950..3d011dfa22b 100644 --- a/cli/src/tunnels/service_windows.rs +++ b/cli/src/tunnels/service_windows.rs @@ -18,7 +18,10 @@ use windows_service::{ service_manager::{ServiceManager, ServiceManagerAccess}, }; -use crate::{util::errors::{wrap, AnyError, WindowsNeedsElevation}, commands::tunnels::ShutdownSignal}; +use crate::{ + commands::tunnels::ShutdownSignal, + util::errors::{wrap, AnyError, WindowsNeedsElevation}, +}; use crate::{ log::{self, FileLogSink}, state::LauncherPaths, @@ -203,7 +206,7 @@ fn service_main(_arguments: Vec) -> Result<(), AnyError> { let mut service = SERVICE_IMPL.lock().unwrap().take().unwrap(); // Create a channel to be able to poll a stop event from the service worker loop. - let (shutdown_tx, shutdown_rx) = mpsc::channel(1); + let (shutdown_tx, shutdown_rx) = mpsc::channel::(5); let mut shutdown_tx = Some(shutdown_tx); // Define system service event handler that will be receiving service events. @@ -211,10 +214,9 @@ fn service_main(_arguments: Vec) -> Result<(), AnyError> { match control_event { ServiceControl::Interrogate => ServiceControlHandlerResult::NoError, ServiceControl::Stop => { - shutdown_tx.take().and_then(|tx| tx.blocking_send(ShutdownSignal::CtrlC).ok()); + shutdown_tx.take().and_then(|tx| tx.blocking_send(ShutdownSignal::ServiceStopped).ok()); ServiceControlHandlerResult::NoError } - _ => ServiceControlHandlerResult::NotImplemented, } };