Skip to main content

ready_set/
exec.rs

1//! Hand off execution to a discovered plugin binary.
2//!
3//! On Unix the dispatcher uses `execvp`-style replacement so the plugin
4//! inherits the dispatcher's PID — cleaner signal handling, matches cargo.
5//! On Windows there is no `execvp`; we spawn the plugin as a child via
6//! `Command::status()` and propagate its exit code.
7
8use std::ffi::OsString;
9use std::process::Command;
10
11use ready_set_sdk::ExitCode;
12
13use crate::discovery::PluginEntry;
14use crate::env::{EnvContract, export_contract};
15
16/// Dispatch into `entry` with `args`, exporting the env contract.
17///
18/// Returns the plugin's exit code.
19#[cfg(unix)]
20pub fn dispatch_to_plugin(
21    entry: &PluginEntry,
22    args: &[OsString],
23    contract: &EnvContract,
24) -> ExitCode {
25    use std::os::unix::process::CommandExt;
26
27    let mut cmd = Command::new(&entry.binary_path);
28    cmd.args(args);
29    export_contract(&mut cmd, contract);
30    let err = cmd.exec();
31    // `exec` only returns on failure.
32    eprintln!(
33        "ready-set: failed to exec {}: {err}",
34        entry.binary_path.display()
35    );
36    ExitCode::SystemError
37}
38
39/// Dispatch into `entry` with `args`, exporting the env contract.
40///
41/// Returns the plugin's exit code.
42#[cfg(windows)]
43pub fn dispatch_to_plugin(
44    entry: &PluginEntry,
45    args: &[OsString],
46    contract: &EnvContract,
47) -> ExitCode {
48    let mut cmd = Command::new(&entry.binary_path);
49    cmd.args(args);
50    export_contract(&mut cmd, contract);
51    match cmd.status() {
52        Ok(status) => match status.code() {
53            Some(0) => ExitCode::Ok,
54            Some(127) => ExitCode::UnknownSubcommand,
55            Some(_) | None => ExitCode::SystemError,
56        },
57        Err(err) => {
58            eprintln!(
59                "ready-set: failed to spawn {}: {err}",
60                entry.binary_path.display()
61            );
62            ExitCode::SystemError
63        },
64    }
65}