diff --git a/cli/dts/lib.deno.unstable.d.ts b/cli/dts/lib.deno.unstable.d.ts index d5797eb836..bb93eac8de 100644 --- a/cli/dts/lib.deno.unstable.d.ts +++ b/cli/dts/lib.deno.unstable.d.ts @@ -1117,7 +1117,7 @@ declare namespace Deno { | { success: false; code: number; - signal: number | null; + signal: string | null; }; export interface SpawnOutput { diff --git a/cli/tests/unit/spawn_test.ts b/cli/tests/unit/spawn_test.ts index c2c7fdbac2..40224dfb42 100644 --- a/cli/tests/unit/spawn_test.ts +++ b/cli/tests/unit/spawn_test.ts @@ -225,7 +225,7 @@ Deno.test( assertEquals(status.signal, null); } else { assertEquals(status.code, 137); - assertEquals(status.signal, 9); + assertEquals(status.signal, "SIGKILL"); } }, ); @@ -410,7 +410,7 @@ Deno.test( assertEquals(status.signal, null); } else { assertEquals(status.code, 128 + 9); - assertEquals(status.signal, 9); + assertEquals(status.signal, "SIGKILL"); } }, ); @@ -429,7 +429,7 @@ Deno.test( assertEquals(status.signal, null); } else { assertEquals(status.code, 128 + 9); - assertEquals(status.signal, 9); + assertEquals(status.signal, "SIGKILL"); } }, ); diff --git a/runtime/ops/signal.rs b/runtime/ops/signal.rs index 92b519d3c0..72e4020940 100644 --- a/runtime/ops/signal.rs +++ b/runtime/ops/signal.rs @@ -100,6 +100,46 @@ pub fn signal_str_to_int(s: &str) -> Result { } } +#[cfg(target_os = "freebsd")] +pub fn signal_int_to_str(s: libc::c_int) -> Result<&'static str, AnyError> { + match s { + 1 => Ok("SIGHUP"), + 2 => Ok("SIGINT"), + 3 => Ok("SIGQUIT"), + 4 => Ok("SIGILL"), + 5 => Ok("SIGTRAP"), + 6 => Ok("SIGABRT"), + 7 => Ok("SIGEMT"), + 8 => Ok("SIGFPE"), + 9 => Ok("SIGKILL"), + 10 => Ok("SIGBUS"), + 11 => Ok("SIGSEGV"), + 12 => Ok("SIGSYS"), + 13 => Ok("SIGPIPE"), + 14 => Ok("SIGALRM"), + 15 => Ok("SIGTERM"), + 16 => Ok("SIGURG"), + 17 => Ok("SIGSTOP"), + 18 => Ok("SIGTSTP"), + 19 => Ok("SIGCONT"), + 20 => Ok("SIGCHLD"), + 21 => Ok("SIGTTIN"), + 22 => Ok("SIGTTOU"), + 23 => Ok("SIGIO"), + 24 => Ok("SIGXCPU"), + 25 => Ok("SIGXFSZ"), + 26 => Ok("SIGVTALRM"), + 27 => Ok("SIGPROF"), + 28 => Ok("SIGWINCH"), + 29 => Ok("SIGINFO"), + 30 => Ok("SIGUSR1"), + 31 => Ok("SIGUSR2"), + 32 => Ok("SIGTHR"), + 33 => Ok("SIGLIBRT"), + _ => Err(type_error(format!("Invalid signal : {}", s))), + } +} + #[cfg(any(target_os = "android", target_os = "linux"))] pub fn signal_str_to_int(s: &str) -> Result { match s { @@ -138,6 +178,44 @@ pub fn signal_str_to_int(s: &str) -> Result { } } +#[cfg(any(target_os = "android", target_os = "linux"))] +pub fn signal_int_to_str(s: libc::c_int) -> Result<&'static str, AnyError> { + match s { + 1 => Ok("SIGHUP"), + 2 => Ok("SIGINT"), + 3 => Ok("SIGQUIT"), + 4 => Ok("SIGILL"), + 5 => Ok("SIGTRAP"), + 6 => Ok("SIGABRT"), + 7 => Ok("SIGBUS"), + 8 => Ok("SIGFPE"), + 9 => Ok("SIGKILL"), + 10 => Ok("SIGUSR1"), + 11 => Ok("SIGSEGV"), + 12 => Ok("SIGUSR2"), + 13 => Ok("SIGPIPE"), + 14 => Ok("SIGALRM"), + 15 => Ok("SIGTERM"), + 16 => Ok("SIGSTKFLT"), + 17 => Ok("SIGCHLD"), + 18 => Ok("SIGCONT"), + 19 => Ok("SIGSTOP"), + 20 => Ok("SIGTSTP"), + 21 => Ok("SIGTTIN"), + 22 => Ok("SIGTTOU"), + 23 => Ok("SIGURG"), + 24 => Ok("SIGXCPU"), + 25 => Ok("SIGXFSZ"), + 26 => Ok("SIGVTALRM"), + 27 => Ok("SIGPROF"), + 28 => Ok("SIGWINCH"), + 29 => Ok("SIGIO"), + 30 => Ok("SIGPWR"), + 31 => Ok("SIGSYS"), + _ => Err(type_error(format!("Invalid signal : {}", s))), + } +} + #[cfg(target_os = "macos")] pub fn signal_str_to_int(s: &str) -> Result { match s { @@ -176,6 +254,44 @@ pub fn signal_str_to_int(s: &str) -> Result { } } +#[cfg(target_os = "macos")] +pub fn signal_int_to_str(s: libc::c_int) -> Result<&'static str, AnyError> { + match s { + 1 => Ok("SIGHUP"), + 2 => Ok("SIGINT"), + 3 => Ok("SIGQUIT"), + 4 => Ok("SIGILL"), + 5 => Ok("SIGTRAP"), + 6 => Ok("SIGABRT"), + 7 => Ok("SIGEMT"), + 8 => Ok("SIGFPE"), + 9 => Ok("SIGKILL"), + 10 => Ok("SIGBUS"), + 11 => Ok("SIGSEGV"), + 12 => Ok("SIGSYS"), + 13 => Ok("SIGPIPE"), + 14 => Ok("SIGALRM"), + 15 => Ok("SIGTERM"), + 16 => Ok("SIGURG"), + 17 => Ok("SIGSTOP"), + 18 => Ok("SIGTSTP"), + 19 => Ok("SIGCONT"), + 20 => Ok("SIGCHLD"), + 21 => Ok("SIGTTIN"), + 22 => Ok("SIGTTOU"), + 23 => Ok("SIGIO"), + 24 => Ok("SIGXCPU"), + 25 => Ok("SIGXFSZ"), + 26 => Ok("SIGVTALRM"), + 27 => Ok("SIGPROF"), + 28 => Ok("SIGWINCH"), + 29 => Ok("SIGINFO"), + 30 => Ok("SIGUSR1"), + 31 => Ok("SIGUSR2"), + _ => Err(type_error(format!("Invalid signal: {}", s))), + } +} + #[cfg(any(target_os = "solaris", target_os = "illumos"))] pub fn signal_str_to_int(s: &str) -> Result { match s { @@ -226,6 +342,53 @@ pub fn signal_str_to_int(s: &str) -> Result { } } +#[cfg(any(target_os = "solaris", target_os = "illumos"))] +pub fn signal_int_to_str(s: libc::c_int) -> Result<&'static str, AnyError> { + match s { + 1 => Ok("SIGHUP"), + 2 => Ok("SIGINT"), + 3 => Ok("SIGQUIT"), + 4 => Ok("SIGILL"), + 5 => Ok("SIGTRAP"), + 6 => Ok("SIGABRT"), + 7 => Ok("SIGEMT"), + 8 => Ok("SIGFPE"), + 9 => Ok("SIGKILL"), + 10 => Ok("SIGBUS"), + 11 => Ok("SIGSEGV"), + 12 => Ok("SIGSYS"), + 13 => Ok("SIGPIPE"), + 14 => Ok("SIGALRM"), + 15 => Ok("SIGTERM"), + 16 => Ok("SIGUSR1"), + 17 => Ok("SIGUSR2"), + 18 => Ok("SIGCHLD"), + 19 => Ok("SIGPWR"), + 20 => Ok("SIGWINCH"), + 21 => Ok("SIGURG"), + 22 => Ok("SIGPOLL"), + 23 => Ok("SIGSTOP"), + 24 => Ok("SIGTSTP"), + 25 => Ok("SIGCONT"), + 26 => Ok("SIGTTIN"), + 27 => Ok("SIGTTOU"), + 28 => Ok("SIGVTALRM"), + 29 => Ok("SIGPROF"), + 30 => Ok("SIGXCPU"), + 31 => Ok("SIGXFSZ"), + 32 => Ok("SIGWAITING"), + 33 => Ok("SIGLWP"), + 34 => Ok("SIGFREEZE"), + 35 => Ok("SIGTHAW"), + 36 => Ok("SIGCANCEL"), + 37 => Ok("SIGLOST"), + 38 => Ok("SIGXRES"), + 39 => Ok("SIGJVM1"), + 40 => Ok("SIGJVM2"), + _ => Err(type_error(format!("Invalid signal : {}", s))), + } +} + #[cfg(unix)] #[op] fn op_signal_bind( diff --git a/runtime/ops/spawn.rs b/runtime/ops/spawn.rs index 0f329e16ee..7e7e2d05ef 100644 --- a/runtime/ops/spawn.rs +++ b/runtime/ops/spawn.rs @@ -73,22 +73,29 @@ pub struct ChildStdio { pub struct ChildStatus { success: bool, code: i32, - signal: Option, + signal: Option, } -impl From for ChildStatus { - fn from(status: ExitStatus) -> Self { +impl TryFrom for ChildStatus { + type Error = AnyError; + + fn try_from(status: ExitStatus) -> Result { let code = status.code(); #[cfg(unix)] let signal = status.signal(); #[cfg(not(unix))] - let signal = None; + let signal: Option = None; - if let Some(signal) = signal { + let status = if let Some(signal) = signal { ChildStatus { success: false, code: 128 + signal, - signal: Some(signal), + #[cfg(unix)] + signal: Some( + crate::ops::signal::signal_int_to_str(signal)?.to_string(), + ), + #[cfg(not(unix))] + signal: None, } } else { let code = code.expect("Should have either an exit code or a signal."); @@ -98,7 +105,9 @@ impl From for ChildStatus { code, signal: None, } - } + }; + + Ok(status) } } @@ -219,15 +228,13 @@ async fn op_spawn_wait( .borrow_mut() .resource_table .take::(rid)?; - Ok( - Rc::try_unwrap(resource) - .ok() - .unwrap() - .0 - .wait() - .await? - .into(), - ) + Rc::try_unwrap(resource) + .ok() + .unwrap() + .0 + .wait() + .await? + .try_into() } #[op] @@ -240,7 +247,7 @@ fn op_spawn_sync( let output = create_command(state, args)?.output()?; Ok(SpawnOutput { - status: output.status.into(), + status: output.status.try_into()?, stdout: if stdout { Some(output.stdout.into()) } else {