⎇ 36dac00c8dd8d39d0306a4804c5432b9ef0c5935
crates/shared/ente-incarnate/src/plain.rs
Historia
Quién tocó qué
crudo
feat(shipote): data plane + DAG fan-in/out + stats + lifecycle (fases F-I)
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}