diff options
author | Nayeem Rahman <nayeemrmn99@gmail.com> | 2023-05-11 13:53:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-11 14:53:45 +0200 |
commit | 2ba9ccc1ab25e5c631afcbb12b53f4545ca7f750 (patch) | |
tree | 38edbbacb6682b178e0356bf38fbb1f91cc5fe93 /runtime/ops/process.rs | |
parent | 20c42286f88d861192f35d272a645d8ab6f15be8 (diff) |
fix(runtime): `ChildProcess::kill()` doesn't require additional perms (#15339)
Fixes #15217.
Diffstat (limited to 'runtime/ops/process.rs')
-rw-r--r-- | runtime/ops/process.rs | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index d991c961f..76db23d02 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -2,6 +2,7 @@ use super::check_unstable; use crate::permissions::PermissionsContainer; +use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; use deno_core::serde_json; @@ -106,6 +107,7 @@ deno_core::extension!( op_spawn_child, op_spawn_wait, op_spawn_sync, + op_spawn_kill, deprecated::op_run, deprecated::op_run_status, deprecated::op_kill, @@ -115,7 +117,9 @@ deno_core::extension!( }, ); -struct ChildResource(tokio::process::Child); +/// Second member stores the pid separately from the RefCell. It's needed for +/// `op_spawn_kill`, where the RefCell is borrowed mutably by `op_spawn_wait`. +struct ChildResource(RefCell<tokio::process::Child>, u32); impl Resource for ChildResource { fn name(&self) -> Cow<str> { @@ -302,7 +306,9 @@ fn spawn_child( .take() .map(|stderr| state.resource_table.add(ChildStderrResource::from(stderr))); - let child_rid = state.resource_table.add(ChildResource(child)); + let child_rid = state + .resource_table + .add(ChildResource(RefCell::new(child), pid)); Ok(Child { rid: child_rid, @@ -328,17 +334,18 @@ async fn op_spawn_wait( state: Rc<RefCell<OpState>>, rid: ResourceId, ) -> Result<ChildStatus, AnyError> { + #![allow(clippy::await_holding_refcell_ref)] let resource = state .borrow_mut() .resource_table - .take::<ChildResource>(rid)?; - Rc::try_unwrap(resource) - .ok() - .unwrap() - .0 - .wait() - .await? - .try_into() + .get::<ChildResource>(rid)?; + let result = resource.0.try_borrow_mut()?.wait().await?.try_into(); + state + .borrow_mut() + .resource_table + .close(rid) + .expect("shouldn't have closed until now"); + result } #[op] @@ -366,6 +373,19 @@ fn op_spawn_sync( }) } +#[op] +fn op_spawn_kill( + state: &mut OpState, + rid: ResourceId, + signal: String, +) -> Result<(), AnyError> { + if let Ok(child_resource) = state.resource_table.get::<ChildResource>(rid) { + deprecated::kill(child_resource.1 as i32, &signal)?; + return Ok(()); + } + Err(type_error("Child process has already terminated.")) +} + mod deprecated { use super::*; |