diff --git a/eden/fs/cli_rs/src/main.rs b/eden/fs/cli_rs/src/main.rs index 0bc9d9bad8..060c2232c2 100644 --- a/eden/fs/cli_rs/src/main.rs +++ b/eden/fs/cli_rs/src/main.rs @@ -19,18 +19,35 @@ use crate::opt::Opt; fn process_opt(_opt: Opt) -> Result<()> { Ok(()) } -fn fallback() -> Result<()> { - let binary = std::env::current_exe().context("unable to locate Python binary")?; - let python_binary = binary - .parent() - .ok_or_else(|| anyhow!("unable to locate Python binary"))? - .join("edenfsctl.real"); - let mut cmd = Command::new(python_binary); +fn python_fallback() -> Result { + if let Ok(args) = std::env::var("EDENFSCTL_REAL") { + // We might get a command starting with python.exe here instead of a simple path. + let mut parts = args.split_ascii_whitespace(); + let binary = parts + .next() + .ok_or_else(|| anyhow!("invalid fallback environment variable: {:?}", args))?; + let mut cmd = Command::new(binary); + cmd.args(parts); + Ok(cmd) + } else { + let binary = std::env::current_exe().context("unable to locate Python binary")?; + let python_binary = binary + .parent() + .ok_or_else(|| anyhow!("unable to locate Python binary"))? + .join("edenfsctl.real"); + Ok(Command::new(python_binary)) + } +} + +fn fallback() -> Result<()> { + let mut cmd = python_fallback()?; + // skip arg0 cmd.args(std::env::args().skip(1)); #[cfg(windows)] { + // Windows doesn't have exec, so we have to open a subprocess cmd.status() .with_context(|| format!("failed to execute: {:?}", cmd))?; Ok(()) @@ -38,6 +55,8 @@ fn fallback() -> Result<()> { #[cfg(unix)] { + // `.exec()` should take over the process, if we ever get to return this Err, then it means + // exec has failed, hence an error. Err(cmd.exec()).with_context(|| format!("failed to execute {:?}", cmd)) } }