diff --git a/cli/tests/unit/process_test.ts b/cli/tests/unit/process_test.ts index 5acb922268..9abe149f9c 100644 --- a/cli/tests/unit/process_test.ts +++ b/cli/tests/unit/process_test.ts @@ -473,10 +473,10 @@ Deno.test( Deno.test({ permissions: { run: false } }, function killPermissions() { assertThrows(() => { // Unlike the other test cases, we don't have permission to spawn a - // subprocess we can safely kill. Instead we send SIGCONT to the current + // subprocess we can safely kill. Instead we send SIGTERM to the current // process - assuming that Deno does not have a special handler set for it // and will just continue even if a signal is erroneously sent. - Deno.kill(Deno.pid, "SIGCONT"); + Deno.kill(Deno.pid, "SIGTERM"); }, Deno.errors.PermissionDenied); }); diff --git a/runtime/ops/process.rs b/runtime/ops/process.rs index ab303e2104..d91ad2bab0 100644 --- a/runtime/ops/process.rs +++ b/runtime/ops/process.rs @@ -288,16 +288,15 @@ async fn op_run_status( } #[cfg(unix)] -pub fn kill(pid: i32, signal: &str) -> Result<(), AnyError> { - let signo = super::signal::signal_str_to_int(signal)?; +pub fn kill(pid: i32, signal: super::signal::Signal) -> Result<(), AnyError> { use nix::sys::signal::{kill as unix_kill, Signal}; use nix::unistd::Pid; - let sig = Signal::try_from(signo)?; + let sig = Signal::try_from(signal as libc::c_int)?; unix_kill(Pid::from_raw(pid), Option::Some(sig)).map_err(AnyError::from) } #[cfg(not(unix))] -pub fn kill(pid: i32, signal: &str) -> Result<(), AnyError> { +pub fn kill(pid: i32, _signal: super::signal::Signal) -> Result<(), AnyError> { use deno_core::error::type_error; use std::io::Error; use std::io::ErrorKind::NotFound; @@ -311,9 +310,7 @@ pub fn kill(pid: i32, signal: &str) -> Result<(), AnyError> { use winapi::um::processthreadsapi::TerminateProcess; use winapi::um::winnt::PROCESS_TERMINATE; - if !matches!(signal, "SIGKILL" | "SIGTERM") { - Err(type_error(format!("Invalid signal: {}", signal))) - } else if pid <= 0 { + if pid <= 0 { Err(type_error("Invalid pid")) } else { let handle = unsafe { OpenProcess(PROCESS_TERMINATE, FALSE, pid as DWORD) }; @@ -339,9 +336,9 @@ pub fn kill(pid: i32, signal: &str) -> Result<(), AnyError> { fn op_kill( state: &mut OpState, pid: i32, - signal: String, + signal: super::signal::Signal, ) -> Result<(), AnyError> { state.borrow_mut::().run.check_all()?; - kill(pid, &signal)?; + kill(pid, signal)?; Ok(()) } diff --git a/runtime/ops/signal.rs b/runtime/ops/signal.rs index 92b519d3c0..50790f0747 100644 --- a/runtime/ops/signal.rs +++ b/runtime/ops/signal.rs @@ -5,6 +5,8 @@ use deno_core::error::generic_error; use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::op; +use serde::Deserialize; +use serde::Serialize; use deno_core::Extension; #[cfg(unix)] @@ -29,7 +31,7 @@ use deno_core::ResourceId; #[cfg(unix)] use std::borrow::Cow; #[cfg(unix)] -use tokio::signal::unix::{signal, Signal, SignalKind}; +use tokio::signal::unix::{signal, Signal as TokioSignal, SignalKind}; pub fn init() -> Extension { Extension::builder() @@ -45,7 +47,7 @@ pub fn init() -> Extension { /// The resource for signal stream. /// The second element is the waker of polling future. struct SignalStreamResource { - signal: AsyncRefCell, + signal: AsyncRefCell, cancel: CancelHandle, } @@ -61,181 +63,178 @@ impl Resource for SignalStreamResource { } #[cfg(target_os = "freebsd")] -pub fn signal_str_to_int(s: &str) -> Result { - match s { - "SIGHUP" => Ok(1), - "SIGINT" => Ok(2), - "SIGQUIT" => Ok(3), - "SIGILL" => Ok(4), - "SIGTRAP" => Ok(5), - "SIGABRT" => Ok(6), - "SIGEMT" => Ok(7), - "SIGFPE" => Ok(8), - "SIGKILL" => Ok(9), - "SIGBUS" => Ok(10), - "SIGSEGV" => Ok(11), - "SIGSYS" => Ok(12), - "SIGPIPE" => Ok(13), - "SIGALRM" => Ok(14), - "SIGTERM" => Ok(15), - "SIGURG" => Ok(16), - "SIGSTOP" => Ok(17), - "SIGTSTP" => Ok(18), - "SIGCONT" => Ok(19), - "SIGCHLD" => Ok(20), - "SIGTTIN" => Ok(21), - "SIGTTOU" => Ok(22), - "SIGIO" => Ok(23), - "SIGXCPU" => Ok(24), - "SIGXFSZ" => Ok(25), - "SIGVTALRM" => Ok(26), - "SIGPROF" => Ok(27), - "SIGWINCH" => Ok(28), - "SIGINFO" => Ok(29), - "SIGUSR1" => Ok(30), - "SIGUSR2" => Ok(31), - "SIGTHR" => Ok(32), - "SIGLIBRT" => Ok(33), - _ => Err(type_error(format!("Invalid signal : {}", s))), - } +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +pub enum Signal { + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGABRT = 6, + SIGEMT = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGBUS = 10, + SIGSEGV = 11, + SIGSYS = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGURG = 16, + SIGSTOP = 17, + SIGTSTP = 18, + SIGCONT = 19, + SIGCHLD = 20, + SIGTTIN = 21, + SIGTTOU = 22, + SIGIO = 23, + SIGXCPU = 24, + SIGXFSZ = 25, + SIGVTALRM = 26, + SIGPROF = 27, + SIGWINCH = 28, + SIGINFO = 29, + SIGUSR1 = 30, + SIGUSR2 = 31, + SIGTHR = 32, + SIGLIBRT = 33, } #[cfg(any(target_os = "android", target_os = "linux"))] -pub fn signal_str_to_int(s: &str) -> Result { - match s { - "SIGHUP" => Ok(1), - "SIGINT" => Ok(2), - "SIGQUIT" => Ok(3), - "SIGILL" => Ok(4), - "SIGTRAP" => Ok(5), - "SIGABRT" => Ok(6), - "SIGBUS" => Ok(7), - "SIGFPE" => Ok(8), - "SIGKILL" => Ok(9), - "SIGUSR1" => Ok(10), - "SIGSEGV" => Ok(11), - "SIGUSR2" => Ok(12), - "SIGPIPE" => Ok(13), - "SIGALRM" => Ok(14), - "SIGTERM" => Ok(15), - "SIGSTKFLT" => Ok(16), - "SIGCHLD" => Ok(17), - "SIGCONT" => Ok(18), - "SIGSTOP" => Ok(19), - "SIGTSTP" => Ok(20), - "SIGTTIN" => Ok(21), - "SIGTTOU" => Ok(22), - "SIGURG" => Ok(23), - "SIGXCPU" => Ok(24), - "SIGXFSZ" => Ok(25), - "SIGVTALRM" => Ok(26), - "SIGPROF" => Ok(27), - "SIGWINCH" => Ok(28), - "SIGIO" => Ok(29), - "SIGPWR" => Ok(30), - "SIGSYS" => Ok(31), - _ => Err(type_error(format!("Invalid signal : {}", s))), - } +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +pub enum Signal { + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGABRT = 6, + SIGBUS = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGUSR1 = 10, + SIGSEGV = 11, + SIGUSR2 = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGSTKFLT = 16, + SIGCHLD = 17, + SIGCONT = 18, + SIGSTOP = 19, + SIGTSTP = 20, + SIGTTIN = 21, + SIGTTOU = 22, + SIGURG = 23, + SIGXCPU = 24, + SIGXFSZ = 25, + SIGVTALRM = 26, + SIGPROF = 27, + SIGWINCH = 28, + SIGIO = 29, + SIGPWR = 30, + SIGSYS = 31, } #[cfg(target_os = "macos")] -pub fn signal_str_to_int(s: &str) -> Result { - match s { - "SIGHUP" => Ok(1), - "SIGINT" => Ok(2), - "SIGQUIT" => Ok(3), - "SIGILL" => Ok(4), - "SIGTRAP" => Ok(5), - "SIGABRT" => Ok(6), - "SIGEMT" => Ok(7), - "SIGFPE" => Ok(8), - "SIGKILL" => Ok(9), - "SIGBUS" => Ok(10), - "SIGSEGV" => Ok(11), - "SIGSYS" => Ok(12), - "SIGPIPE" => Ok(13), - "SIGALRM" => Ok(14), - "SIGTERM" => Ok(15), - "SIGURG" => Ok(16), - "SIGSTOP" => Ok(17), - "SIGTSTP" => Ok(18), - "SIGCONT" => Ok(19), - "SIGCHLD" => Ok(20), - "SIGTTIN" => Ok(21), - "SIGTTOU" => Ok(22), - "SIGIO" => Ok(23), - "SIGXCPU" => Ok(24), - "SIGXFSZ" => Ok(25), - "SIGVTALRM" => Ok(26), - "SIGPROF" => Ok(27), - "SIGWINCH" => Ok(28), - "SIGINFO" => Ok(29), - "SIGUSR1" => Ok(30), - "SIGUSR2" => Ok(31), - _ => Err(type_error(format!("Invalid signal: {}", s))), - } +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +pub enum Signal { + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGABRT = 6, + SIGEMT = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGBUS = 10, + SIGSEGV = 11, + SIGSYS = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGURG = 16, + SIGSTOP = 17, + SIGTSTP = 18, + SIGCONT = 19, + SIGCHLD = 20, + SIGTTIN = 21, + SIGTTOU = 22, + SIGIO = 23, + SIGXCPU = 24, + SIGXFSZ = 25, + SIGVTALRM = 26, + SIGPROF = 27, + SIGWINCH = 28, + SIGINFO = 29, + SIGUSR1 = 30, + SIGUSR2 = 31, } #[cfg(any(target_os = "solaris", target_os = "illumos"))] -pub fn signal_str_to_int(s: &str) -> Result { - match s { - "SIGHUP" => Ok(1), - "SIGINT" => Ok(2), - "SIGQUIT" => Ok(3), - "SIGILL" => Ok(4), - "SIGTRAP" => Ok(5), - "SIGIOT" => Ok(6), - "SIGABRT" => Ok(6), - "SIGEMT" => Ok(7), - "SIGFPE" => Ok(8), - "SIGKILL" => Ok(9), - "SIGBUS" => Ok(10), - "SIGSEGV" => Ok(11), - "SIGSYS" => Ok(12), - "SIGPIPE" => Ok(13), - "SIGALRM" => Ok(14), - "SIGTERM" => Ok(15), - "SIGUSR1" => Ok(16), - "SIGUSR2" => Ok(17), - "SIGCLD" => Ok(18), - "SIGCHLD" => Ok(18), - "SIGPWR" => Ok(19), - "SIGWINCH" => Ok(20), - "SIGURG" => Ok(21), - "SIGPOLL" => Ok(22), - "SIGIO" => Ok(22), - "SIGSTOP" => Ok(23), - "SIGTSTP" => Ok(24), - "SIGCONT" => Ok(25), - "SIGTTIN" => Ok(26), - "SIGTTOU" => Ok(27), - "SIGVTALRM" => Ok(28), - "SIGPROF" => Ok(29), - "SIGXCPU" => Ok(30), - "SIGXFSZ" => Ok(31), - "SIGWAITING" => Ok(32), - "SIGLWP" => Ok(33), - "SIGFREEZE" => Ok(34), - "SIGTHAW" => Ok(35), - "SIGCANCEL" => Ok(36), - "SIGLOST" => Ok(37), - "SIGXRES" => Ok(38), - "SIGJVM1" => Ok(39), - "SIGJVM2" => Ok(40), - _ => Err(type_error(format!("Invalid signal : {}", s))), - } +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +pub enum Signal { + SIGHUP = 1, + SIGINT = 2, + SIGQUIT = 3, + SIGILL = 4, + SIGTRAP = 5, + SIGIOT = 6, + SIGABRT = 6, + SIGEMT = 7, + SIGFPE = 8, + SIGKILL = 9, + SIGBUS = 10, + SIGSEGV = 11, + SIGSYS = 12, + SIGPIPE = 13, + SIGALRM = 14, + SIGTERM = 15, + SIGUSR1 = 16, + SIGUSR2 = 17, + SIGCHLD = 18, + SIGPWR = 19, + SIGWINCH = 20, + SIGURG = 21, + SIGPOLL = 22, + SIGSTOP = 23, + SIGTSTP = 24, + SIGCONT = 25, + SIGTTIN = 26, + SIGTTOU = 27, + SIGVTALRM = 28, + SIGPROF = 29, + SIGXCPU = 30, + SIGXFSZ = 31, + SIGWAITING = 32, + SIGLWP = 33, + SIGFREEZE = 34, + SIGTHAW = 35, + SIGCANCEL = 36, + SIGLOST = 37, + SIGXRES = 38, + SIGJVM1 = 39, + SIGJVM2 = 40, +} + +#[cfg(target_os = "windows")] +#[derive(Debug, Serialize, Deserialize, Clone, Copy)] +pub enum Signal { + SIGKILL, + SIGTERM, } #[cfg(unix)] #[op] fn op_signal_bind( state: &mut OpState, - sig: String, + sig: Signal, ) -> Result { - let signo = signal_str_to_int(&sig)?; + let signo = sig as libc::c_int; if signal_hook_registry::FORBIDDEN.contains(&signo) { return Err(type_error(format!( - "Binding to signal '{}' is not allowed", + "Binding to signal '{:?}' is not allowed", sig ))); }