ai_session/core/
process.rs1use anyhow::Result;
4use std::process::Stdio;
5use tokio::process::{Child, Command};
6
7pub struct ProcessHandle {
9 child: Child,
11 pid: u32,
13}
14
15impl ProcessHandle {
16 pub async fn spawn(
18 command: &str,
19 args: &[String],
20 working_dir: &std::path::Path,
21 env: &[(String, String)],
22 ) -> Result<Self> {
23 let mut cmd = Command::new(command);
24
25 cmd.args(args)
26 .current_dir(working_dir)
27 .stdin(Stdio::piped())
28 .stdout(Stdio::piped())
29 .stderr(Stdio::piped());
30
31 for (key, value) in env {
32 cmd.env(key, value);
33 }
34
35 let child = cmd.spawn()?;
36 let pid = child
37 .id()
38 .ok_or_else(|| anyhow::anyhow!("Failed to get process ID"))?;
39
40 Ok(Self { child, pid })
41 }
42
43 pub fn pid(&self) -> u32 {
45 self.pid
46 }
47
48 pub async fn is_running(&mut self) -> bool {
50 matches!(self.child.try_wait(), Ok(None))
51 }
52
53 pub async fn kill(&mut self) -> Result<()> {
55 self.child.kill().await?;
56 Ok(())
57 }
58
59 pub async fn wait(&mut self) -> Result<std::process::ExitStatus> {
61 Ok(self.child.wait().await?)
62 }
63}