summaryrefslogtreecommitdiff
path: root/cli/ops/process.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-12-13 19:45:53 +0100
committerGitHub <noreply@github.com>2020-12-13 19:45:53 +0100
commit2e74f164b6dcf0ecbf8dd38fba9fae550d784bd0 (patch)
tree61abe8e09d5331ace5d9de529f0e2737a8e05dbb /cli/ops/process.rs
parent84ef9bd21fb48fb6b5fbc8dafc3de9f361bade3b (diff)
refactor: deno_runtime crate (#8640)
This commit moves Deno JS runtime, ops, permissions and inspector implementation to new "deno_runtime" crate located in "runtime/" directory. Details in "runtime/README.md". Co-authored-by: Ryan Dahl <ry@tinyclouds.org>
Diffstat (limited to 'cli/ops/process.rs')
-rw-r--r--cli/ops/process.rs236
1 files changed, 0 insertions, 236 deletions
diff --git a/cli/ops/process.rs b/cli/ops/process.rs
deleted file mode 100644
index 60a6d5095..000000000
--- a/cli/ops/process.rs
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-
-use super::io::{std_file_resource, StreamResource, StreamResourceHolder};
-use crate::permissions::Permissions;
-use crate::signal::kill;
-use deno_core::error::bad_resource_id;
-use deno_core::error::type_error;
-use deno_core::error::AnyError;
-use deno_core::futures::future::poll_fn;
-use deno_core::futures::future::FutureExt;
-use deno_core::serde_json;
-use deno_core::serde_json::json;
-use deno_core::serde_json::Value;
-use deno_core::BufVec;
-use deno_core::OpState;
-use deno_core::ZeroCopyBuf;
-use serde::Deserialize;
-use std::cell::RefCell;
-use std::rc::Rc;
-use tokio::process::Command;
-
-#[cfg(unix)]
-use std::os::unix::process::ExitStatusExt;
-
-pub fn init(rt: &mut deno_core::JsRuntime) {
- super::reg_json_sync(rt, "op_run", op_run);
- super::reg_json_async(rt, "op_run_status", op_run_status);
- super::reg_json_sync(rt, "op_kill", op_kill);
-}
-
-fn clone_file(
- state: &mut OpState,
- rid: u32,
-) -> Result<std::fs::File, AnyError> {
- std_file_resource(state, rid, move |r| match r {
- Ok(std_file) => std_file.try_clone().map_err(AnyError::from),
- Err(_) => Err(bad_resource_id()),
- })
-}
-
-fn subprocess_stdio_map(s: &str) -> Result<std::process::Stdio, AnyError> {
- match s {
- "inherit" => Ok(std::process::Stdio::inherit()),
- "piped" => Ok(std::process::Stdio::piped()),
- "null" => Ok(std::process::Stdio::null()),
- _ => Err(type_error("Invalid resource for stdio")),
- }
-}
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct RunArgs {
- cmd: Vec<String>,
- cwd: Option<String>,
- env: Vec<(String, String)>,
- stdin: String,
- stdout: String,
- stderr: String,
- stdin_rid: u32,
- stdout_rid: u32,
- stderr_rid: u32,
-}
-
-struct ChildResource {
- child: tokio::process::Child,
-}
-
-fn op_run(
- state: &mut OpState,
- args: Value,
- _zero_copy: &mut [ZeroCopyBuf],
-) -> Result<Value, AnyError> {
- let run_args: RunArgs = serde_json::from_value(args)?;
- state.borrow::<Permissions>().check_run()?;
-
- let args = run_args.cmd;
- let env = run_args.env;
- let cwd = run_args.cwd;
-
- let mut c = Command::new(args.get(0).unwrap());
- (1..args.len()).for_each(|i| {
- let arg = args.get(i).unwrap();
- c.arg(arg);
- });
- cwd.map(|d| c.current_dir(d));
- for (key, value) in &env {
- c.env(key, value);
- }
-
- // TODO: make this work with other resources, eg. sockets
- if !run_args.stdin.is_empty() {
- c.stdin(subprocess_stdio_map(run_args.stdin.as_ref())?);
- } else {
- let file = clone_file(state, run_args.stdin_rid)?;
- c.stdin(file);
- }
-
- if !run_args.stdout.is_empty() {
- c.stdout(subprocess_stdio_map(run_args.stdout.as_ref())?);
- } else {
- let file = clone_file(state, run_args.stdout_rid)?;
- c.stdout(file);
- }
-
- if !run_args.stderr.is_empty() {
- c.stderr(subprocess_stdio_map(run_args.stderr.as_ref())?);
- } else {
- let file = clone_file(state, run_args.stderr_rid)?;
- c.stderr(file);
- }
-
- // We want to kill child when it's closed
- c.kill_on_drop(true);
-
- // Spawn the command.
- let mut child = c.spawn()?;
- let pid = child.id();
-
- let stdin_rid = match child.stdin.take() {
- Some(child_stdin) => {
- let rid = state.resource_table.add(
- "childStdin",
- Box::new(StreamResourceHolder::new(StreamResource::ChildStdin(
- child_stdin,
- ))),
- );
- Some(rid)
- }
- None => None,
- };
-
- let stdout_rid = match child.stdout.take() {
- Some(child_stdout) => {
- let rid = state.resource_table.add(
- "childStdout",
- Box::new(StreamResourceHolder::new(StreamResource::ChildStdout(
- child_stdout,
- ))),
- );
- Some(rid)
- }
- None => None,
- };
-
- let stderr_rid = match child.stderr.take() {
- Some(child_stderr) => {
- let rid = state.resource_table.add(
- "childStderr",
- Box::new(StreamResourceHolder::new(StreamResource::ChildStderr(
- child_stderr,
- ))),
- );
- Some(rid)
- }
- None => None,
- };
-
- let child_resource = ChildResource { child };
- let child_rid = state.resource_table.add("child", Box::new(child_resource));
-
- Ok(json!({
- "rid": child_rid,
- "pid": pid,
- "stdinRid": stdin_rid,
- "stdoutRid": stdout_rid,
- "stderrRid": stderr_rid,
- }))
-}
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct RunStatusArgs {
- rid: i32,
-}
-
-async fn op_run_status(
- state: Rc<RefCell<OpState>>,
- args: Value,
- _zero_copy: BufVec,
-) -> Result<Value, AnyError> {
- let args: RunStatusArgs = serde_json::from_value(args)?;
- let rid = args.rid as u32;
-
- {
- let s = state.borrow();
- s.borrow::<Permissions>().check_run()?;
- }
-
- let run_status = poll_fn(|cx| {
- let mut state = state.borrow_mut();
- let child_resource = state
- .resource_table
- .get_mut::<ChildResource>(rid)
- .ok_or_else(bad_resource_id)?;
- let child = &mut child_resource.child;
- child.poll_unpin(cx).map_err(AnyError::from)
- })
- .await?;
-
- let code = run_status.code();
-
- #[cfg(unix)]
- let signal = run_status.signal();
- #[cfg(not(unix))]
- let signal = None;
-
- code
- .or(signal)
- .expect("Should have either an exit code or a signal.");
- let got_signal = signal.is_some();
-
- Ok(json!({
- "gotSignal": got_signal,
- "exitCode": code.unwrap_or(-1),
- "exitSignal": signal.unwrap_or(-1),
- }))
-}
-
-#[derive(Deserialize)]
-struct KillArgs {
- pid: i32,
- signo: i32,
-}
-
-fn op_kill(
- state: &mut OpState,
- args: Value,
- _zero_copy: &mut [ZeroCopyBuf],
-) -> Result<Value, AnyError> {
- super::check_unstable(state, "Deno.kill");
- state.borrow::<Permissions>().check_run()?;
-
- let args: KillArgs = serde_json::from_value(args)?;
- kill(args.pid, args.signo)?;
- Ok(json!({}))
-}