tawasuyu

tawasuyu/brahman

Rust 506TOML 198Markdown 56JSON 197212 Definiciones

⎇ 36dac00c8dd8d39d0306a4804c5432b9ef0c5935 crates/shared/ente-incarnate/src/plain.rs Rust · 60 líneas · 2.0 KB Historia Quién tocó qué crudo

feat(shipote): data plane + DAG fan-in/out + stats + lifecycle (fases F-I) 36dac00c8 · sergio ·

1//! Path simple: spawn directo, sin namespacing.
2
3use crate::env::{build_env, EnvSpec};
4use crate::error::IncarnateError;
5use crate::pre_exec::{apply_unchecked, ChildSetup};
6use crate::ChildStdio;
7use brahman_card::{Card, Payload};
8use nix::unistd::Pid;
9use std::os::fd::FromRawFd;
10use std::os::unix::process::CommandExt;
11use std::process::{Command, Stdio};
12
13pub fn incarnate_plain(
14    card: &Card,
15    env_spec: &EnvSpec,
16    stdio: &ChildStdio,
17    setup: &ChildSetup,
18) -> Result<Pid, IncarnateError> {
19    let (exec, argv, base_envp) = match &card.payload {
20        Payload::Native { exec, argv, envp } => (exec.clone(), argv.clone(), envp.clone()),
21        Payload::Legacy { exec, argv, .. } => (exec.clone(), argv.clone(), Vec::new()),
22        _ => return Err(IncarnateError::NonExecutablePayload),
23    };
24    let env = build_env(card, &base_envp, env_spec);
25    let mut cmd = Command::new(&exec);
26    cmd.args(&argv);
27    cmd.env_clear();
28    for (k, v) in &env {
29        cmd.env(k, v);
30    }
31    if let Some(fd) = stdio.stdin_fd {
32        // SAFETY: el caller garantiza que `fd` está abierto y le
33        // transfiere ownership al child. `Command` lo cierra tras spawn.
34        cmd.stdin(unsafe { Stdio::from_raw_fd(fd) });
35    }
36    if let Some(fd) = stdio.stdout_fd {
37        cmd.stdout(unsafe { Stdio::from_raw_fd(fd) });
38    }
39    if let Some(fd) = stdio.stderr_fd {
40        cmd.stderr(unsafe { Stdio::from_raw_fd(fd) });
41    }
42    if !setup.is_empty() {
43        // Clone para que la closure sea 'static (Command::pre_exec lo exige).
44        let ops = setup.ops.clone();
45        // SAFETY: pre_exec corre post-fork pre-exec. apply_unchecked sólo
46        // hace syscalls async-signal-safe.
47        unsafe {
48            cmd.pre_exec(move || {
49                let r = apply_unchecked(&ops);
50                if r != 0 {
51                    Err(std::io::Error::from_raw_os_error(libc::EINVAL))
52                } else {
53                    Ok(())
54                }
55            });
56        }
57    }
58    let child = cmd.spawn()?;
59    Ok(Pid::from_raw(child.id() as i32))
60}