vx_shim/
executor.rs

1//! Cross-platform process execution with signal handling
2
3use anyhow::Result;
4use std::process::{Command, Stdio};
5
6use crate::config::ShimConfig;
7use crate::platform::PlatformExecutor;
8
9/// Cross-platform process executor
10pub struct Executor {
11    config: ShimConfig,
12    platform: PlatformExecutor,
13}
14
15impl Executor {
16    /// Create a new executor with the given configuration
17    pub fn new(config: ShimConfig) -> Self {
18        Self {
19            config,
20            platform: PlatformExecutor::new(),
21        }
22    }
23
24    /// Execute the target program with the given arguments
25    pub fn execute(&self, args: &[String]) -> Result<i32> {
26        let target_path = self.config.resolved_path();
27        let mut cmd_args = self.config.resolved_args();
28        cmd_args.extend_from_slice(args);
29
30        // Create the command
31        let mut command = Command::new(&target_path);
32        command.args(&cmd_args);
33
34        // Set working directory if specified
35        if let Some(working_dir) = self.config.resolved_working_dir() {
36            command.current_dir(working_dir);
37        }
38
39        // Set environment variables
40        for (key, value) in self.config.resolved_env() {
41            command.env(key, value);
42        }
43
44        // Configure stdio
45        command
46            .stdin(Stdio::inherit())
47            .stdout(Stdio::inherit())
48            .stderr(Stdio::inherit());
49
50        // Platform-specific execution
51        self.platform.execute(command, &self.config)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58    use crate::config::ShimConfig;
59    use std::collections::HashMap;
60
61    #[test]
62    fn test_executor_creation() {
63        let config = ShimConfig {
64            path: "/bin/echo".to_string(),
65            args: Some(vec!["hello".to_string()]),
66            working_dir: None,
67            env: None,
68            hide_console: None,
69            run_as_admin: None,
70            signal_handling: None,
71        };
72
73        let executor = Executor::new(config);
74        assert_eq!(executor.config.path, "/bin/echo");
75    }
76
77    #[test]
78    fn test_executor_with_env() {
79        let mut env = HashMap::new();
80        env.insert("TEST_VAR".to_string(), "test_value".to_string());
81
82        let config = ShimConfig {
83            path: "/bin/echo".to_string(),
84            args: None,
85            working_dir: None,
86            env: Some(env),
87            hide_console: None,
88            run_as_admin: None,
89            signal_handling: None,
90        };
91
92        let executor = Executor::new(config);
93        let resolved_env = executor.config.resolved_env();
94        assert_eq!(
95            resolved_env.get("TEST_VAR"),
96            Some(&"test_value".to_string())
97        );
98    }
99}