summaryrefslogtreecommitdiff
path: root/runtime/ops
diff options
context:
space:
mode:
authorNathan Whitaker <17734409+nathanwhit@users.noreply.github.com>2024-09-12 12:24:58 -0700
committerGitHub <noreply@github.com>2024-09-12 19:24:58 +0000
commit18b89d948dcb849c4dc577478794c3d5fb23b597 (patch)
tree9945567e4b53dc50d2a61a3149b51edf97c05839 /runtime/ops
parent3f15e300625723df10c564c4e29ec276288a931b (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.rs32
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);
}