diff options
author | Kevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com> | 2019-04-21 18:26:56 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2019-04-21 21:26:56 -0400 |
commit | 1d4b92ac85d8c850270ca859f928404c72c0a49a (patch) | |
tree | 2f45ea65a3a3c5879fe7b16cacfd5624d86764cd /cli | |
parent | 9dfebbc9496138efbeedc431068f41662c780f3e (diff) |
Add Deno.kill(pid, signo) and process.kill(signo) (Unix only) (#2177)
Diffstat (limited to 'cli')
-rw-r--r-- | cli/BUILD.gn | 3 | ||||
-rw-r--r-- | cli/Cargo.toml | 3 | ||||
-rw-r--r-- | cli/errors.rs | 28 | ||||
-rw-r--r-- | cli/main.rs | 3 | ||||
-rw-r--r-- | cli/msg.fbs | 9 | ||||
-rw-r--r-- | cli/ops.rs | 17 | ||||
-rw-r--r-- | cli/signal.rs | 20 |
7 files changed, 82 insertions, 1 deletions
diff --git a/cli/BUILD.gn b/cli/BUILD.gn index a292e559f..7bf34dec3 100644 --- a/cli/BUILD.gn +++ b/cli/BUILD.gn @@ -42,6 +42,9 @@ main_extern = [ if (is_win) { main_extern += [ "$rust_build:winapi" ] } +if (is_posix) { + main_extern += [ "$rust_build:nix" ] +} ts_sources = [ "../js/assets.ts", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index a7a780618..ad921cbdd 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -50,3 +50,6 @@ url = "1.7.2" [target.'cfg(windows)'.dependencies] winapi = "0.3.7" + +[target.'cfg(unix)'.dependencies] +nix = "0.11.0" diff --git a/cli/errors.rs b/cli/errors.rs index bd3e7ba73..424091584 100644 --- a/cli/errors.rs +++ b/cli/errors.rs @@ -4,6 +4,8 @@ pub use crate::msg::ErrorKind; use crate::resolve_addr::ResolveAddrError; use deno::JSError; use hyper; +#[cfg(unix)] +use nix::{errno::Errno, Error as UnixError}; use std; use std::fmt; use std::io; @@ -168,6 +170,32 @@ impl From<ResolveAddrError> for DenoError { } } +#[cfg(unix)] +impl From<UnixError> for DenoError { + fn from(e: UnixError) -> Self { + match e { + UnixError::Sys(Errno::EPERM) => Self { + repr: Repr::Simple( + ErrorKind::PermissionDenied, + Errno::EPERM.desc().to_owned(), + ), + }, + UnixError::Sys(Errno::EINVAL) => Self { + repr: Repr::Simple( + ErrorKind::InvalidInput, + Errno::EINVAL.desc().to_owned(), + ), + }, + UnixError::Sys(err) => Self { + repr: Repr::Simple(ErrorKind::UnixError, err.desc().to_owned()), + }, + _ => Self { + repr: Repr::Simple(ErrorKind::Other, format!("{}", e)), + }, + } + } +} + pub fn bad_resource() -> DenoError { new(ErrorKind::BadResource, String::from("bad resource id")) } diff --git a/cli/main.rs b/cli/main.rs index 4d12b6c89..41b04785c 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -9,6 +9,8 @@ extern crate futures; extern crate serde_json; extern crate clap; extern crate deno; +#[cfg(unix)] +extern crate nix; mod ansi; pub mod compiler; @@ -27,6 +29,7 @@ pub mod permissions; mod repl; pub mod resolve_addr; pub mod resources; +mod signal; mod startup_data; pub mod state; mod tokio_util; diff --git a/cli/msg.fbs b/cli/msg.fbs index 4eca8dcf8..d217fc7ba 100644 --- a/cli/msg.fbs +++ b/cli/msg.fbs @@ -21,6 +21,7 @@ union Any { GlobalTimerStop, IsTTY, IsTTYRes, + Kill, Link, Listen, ListenRes, @@ -129,7 +130,8 @@ enum ErrorKind: byte { InvalidUri, InvalidSeekMode, OpNotAvaiable, - WorkerInitFailed + WorkerInitFailed, + UnixError, } table Cwd {} @@ -453,6 +455,11 @@ table Close { rid: uint32; } +table Kill { + pid: int32; + signo: int32; +} + table Shutdown { rid: uint32; how: uint; diff --git a/cli/ops.rs b/cli/ops.rs index 044e0fc20..bc06a2fb7 100644 --- a/cli/ops.rs +++ b/cli/ops.rs @@ -14,6 +14,7 @@ use crate::resolve_addr::resolve_addr; use crate::resources; use crate::resources::table_entries; use crate::resources::Resource; +use crate::signal::kill; use crate::startup_data; use crate::state::ThreadSafeState; use crate::tokio_util; @@ -171,6 +172,7 @@ pub fn op_selector_std(inner_type: msg::Any) -> Option<OpCreator> { msg::Any::GlobalTimer => Some(op_global_timer), msg::Any::GlobalTimerStop => Some(op_global_timer_stop), msg::Any::IsTTY => Some(op_is_tty), + msg::Any::Kill => Some(op_kill), msg::Any::Link => Some(op_link), msg::Any::Listen => Some(op_listen), msg::Any::MakeTempDir => Some(op_make_temp_dir), @@ -906,6 +908,21 @@ fn op_close( } } +fn op_kill( + _state: &ThreadSafeState, + base: &msg::Base<'_>, + data: deno_buf, +) -> Box<OpWithError> { + assert_eq!(data.len(), 0); + let inner = base.inner_as_kill().unwrap(); + let pid = inner.pid(); + let signo = inner.signo(); + match kill(pid, signo) { + Ok(_) => ok_future(empty_buf()), + Err(e) => odd_future(e), + } +} + fn op_shutdown( _state: &ThreadSafeState, base: &msg::Base<'_>, diff --git a/cli/signal.rs b/cli/signal.rs new file mode 100644 index 000000000..7d67ba743 --- /dev/null +++ b/cli/signal.rs @@ -0,0 +1,20 @@ +#[cfg(unix)] +use nix::sys::signal::{kill as unix_kill, Signal}; +#[cfg(unix)] +use nix::unistd::Pid; + +use crate::errors::DenoResult; + +#[cfg(unix)] +pub fn kill(pid: i32, signo: i32) -> DenoResult<()> { + use crate::errors::DenoError; + let sig = Signal::from_c_int(signo)?; + unix_kill(Pid::from_raw(pid), Option::Some(sig)).map_err(DenoError::from) +} + +#[cfg(not(unix))] +pub fn kill(_pid: i32, _signal: i32) -> DenoResult<()> { + // NOOP + // TODO: implement this for windows + Ok(()) +} |