diff options
author | Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> | 2024-09-12 12:24:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-12 19:24:58 +0000 |
commit | 18b89d948dcb849c4dc577478794c3d5fb23b597 (patch) | |
tree | 9945567e4b53dc50d2a61a3149b51edf97c05839 /runtime/ops | |
parent | 3f15e300625723df10c564c4e29ec276288a931b (diff) |
fix(ext/node): Implement detached option in `child_process` (#25218)
Fixes https://github.com/denoland/deno/issues/25193.
Diffstat (limited to 'runtime/ops')
-rw-r--r-- | runtime/ops/process.rs | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index d7058a053..b7242c07f 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -159,6 +159,7 @@ pub struct SpawnArgs { stdio: ChildStdio, extra_stdio: Vec<Stdio>, + detached: bool, } #[derive(Deserialize)] @@ -243,12 +244,21 @@ fn create_command( let mut command = std::process::Command::new(cmd); #[cfg(windows)] - if args.windows_raw_arguments { - for arg in args.args.iter() { - command.raw_arg(arg); + { + if args.detached { + // TODO(nathanwhit): Currently this causes the process to hang + // until the detached process exits (so never). It repros with just the + // rust std library, so it's either a bug or requires more control than we have. + // To be resolved at the same time as additional stdio support. + log::warn!("detached processes are not currently supported on Windows"); + } + if args.windows_raw_arguments { + for arg in args.args.iter() { + command.raw_arg(arg); + } + } else { + command.args(args.args); } - } else { - command.args(args.args); } #[cfg(not(windows))] @@ -336,7 +346,11 @@ fn create_command( } } + let detached = args.detached; command.pre_exec(move || { + if detached { + libc::setsid(); + } for &(src, dst) in &fds_to_dup { if src >= 0 && dst >= 0 { let _fd = libc::dup2(src, dst); @@ -402,12 +416,15 @@ fn spawn_child( command: std::process::Command, ipc_pipe_rid: Option<ResourceId>, extra_pipe_rids: Vec<Option<ResourceId>>, + detached: bool, ) -> Result<Child, AnyError> { let mut command = tokio::process::Command::from(command); // TODO(@crowlkats): allow detaching processes. // currently deno will orphan a process when exiting with an error or Deno.exit() // We want to kill child when it's closed - command.kill_on_drop(true); + if !detached { + command.kill_on_drop(true); + } let mut child = match command.spawn() { Ok(child) => child, @@ -647,9 +664,10 @@ fn op_spawn_child( #[serde] args: SpawnArgs, #[string] api_name: String, ) -> Result<Child, AnyError> { + let detached = args.detached; let (command, pipe_rid, extra_pipe_rids, handles_to_close) = create_command(state, args, &api_name)?; - let child = spawn_child(state, command, pipe_rid, extra_pipe_rids); + let child = spawn_child(state, command, pipe_rid, extra_pipe_rids, detached); for handle in handles_to_close { close_raw_handle(handle); } |