2021-01-10 21:59:07 -05:00
|
|
|
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
2021-09-06 10:05:33 -04:00
|
|
|
use deno_core::error::type_error;
|
2020-09-14 12:48:57 -04:00
|
|
|
use deno_core::error::AnyError;
|
2021-06-25 00:15:35 -04:00
|
|
|
use deno_core::op_async_unref;
|
2021-05-02 19:22:57 -04:00
|
|
|
use deno_core::op_sync;
|
|
|
|
use deno_core::Extension;
|
2020-09-10 09:57:45 -04:00
|
|
|
use deno_core::OpState;
|
|
|
|
use std::cell::RefCell;
|
2020-08-18 12:30:13 -04:00
|
|
|
use std::rc::Rc;
|
2020-01-24 08:15:31 -05:00
|
|
|
|
|
|
|
#[cfg(unix)]
|
2020-12-16 11:14:12 -05:00
|
|
|
use deno_core::AsyncRefCell;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::CancelFuture;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::CancelHandle;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::RcRef;
|
|
|
|
#[cfg(unix)]
|
|
|
|
use deno_core::Resource;
|
|
|
|
#[cfg(unix)]
|
2021-04-05 12:40:24 -04:00
|
|
|
use deno_core::ResourceId;
|
2020-09-05 20:34:02 -04:00
|
|
|
#[cfg(unix)]
|
2020-12-16 11:14:12 -05:00
|
|
|
use std::borrow::Cow;
|
2020-01-24 08:15:31 -05:00
|
|
|
#[cfg(unix)]
|
|
|
|
use tokio::signal::unix::{signal, Signal, SignalKind};
|
|
|
|
|
2021-05-02 19:22:57 -04:00
|
|
|
pub fn init() -> Extension {
|
|
|
|
Extension::builder()
|
|
|
|
.ops(vec![
|
|
|
|
("op_signal_bind", op_sync(op_signal_bind)),
|
|
|
|
("op_signal_unbind", op_sync(op_signal_unbind)),
|
2021-06-25 00:15:35 -04:00
|
|
|
("op_signal_poll", op_async_unref(op_signal_poll)),
|
2021-05-02 19:22:57 -04:00
|
|
|
])
|
|
|
|
.build()
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
/// The resource for signal stream.
|
|
|
|
/// The second element is the waker of polling future.
|
2020-12-16 11:14:12 -05:00
|
|
|
struct SignalStreamResource {
|
|
|
|
signal: AsyncRefCell<Signal>,
|
|
|
|
cancel: CancelHandle,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
impl Resource for SignalStreamResource {
|
|
|
|
fn name(&self) -> Cow<str> {
|
|
|
|
"signal".into()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn close(self: Rc<Self>) {
|
|
|
|
self.cancel.cancel();
|
|
|
|
}
|
|
|
|
}
|
2020-01-24 08:15:31 -05:00
|
|
|
|
2021-09-06 10:05:33 -04:00
|
|
|
#[cfg(target_os = "linux")]
|
|
|
|
fn signal_str_to_int(s: &str) -> Option<libc::c_int> {
|
|
|
|
match s {
|
|
|
|
"SIGHUP" => Some(1),
|
|
|
|
"SIGINT" => Some(2),
|
|
|
|
"SIGQUIT" => Some(3),
|
|
|
|
"SIGILL" => Some(4),
|
|
|
|
"SIGTRAP" => Some(5),
|
|
|
|
"SIGABRT" => Some(6),
|
|
|
|
"SIGBUS" => Some(7),
|
|
|
|
"SIGFPE" => Some(8),
|
|
|
|
"SIGKILL" => Some(9),
|
|
|
|
"SIGUSR1" => Some(10),
|
|
|
|
"SIGSEGV" => Some(11),
|
|
|
|
"SIGUSR2" => Some(12),
|
|
|
|
"SIGPIPE" => Some(13),
|
|
|
|
"SIGALRM" => Some(14),
|
|
|
|
"SIGTERM" => Some(15),
|
|
|
|
"SIGSTKFLT" => Some(16),
|
|
|
|
"SIGCHLD" => Some(17),
|
|
|
|
"SIGCONT" => Some(18),
|
|
|
|
"SIGSTOP" => Some(19),
|
|
|
|
"SIGTSTP" => Some(20),
|
|
|
|
"SIGTTIN" => Some(21),
|
|
|
|
"SIGTTOU" => Some(22),
|
|
|
|
"SIGURG" => Some(23),
|
|
|
|
"SIGXCPU" => Some(24),
|
|
|
|
"SIGXFSZ" => Some(25),
|
|
|
|
"SIGVTALRM" => Some(26),
|
|
|
|
"SIGPROF" => Some(27),
|
|
|
|
"SIGWINCH" => Some(28),
|
|
|
|
"SIGIO" => Some(29),
|
|
|
|
"SIGPWR" => Some(30),
|
|
|
|
"SIGSYS" => Some(31),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
fn signal_str_to_int(s: &str) -> Option<libc::c_int> {
|
|
|
|
match s {
|
|
|
|
"SIGHUP" => Some(1),
|
|
|
|
"SIGINT" => Some(2),
|
|
|
|
"SIGQUIT" => Some(3),
|
|
|
|
"SIGILL" => Some(4),
|
|
|
|
"SIGTRAP" => Some(5),
|
|
|
|
"SIGABRT" => Some(6),
|
|
|
|
"SIGEMT" => Some(7),
|
|
|
|
"SIGFPE" => Some(8),
|
|
|
|
"SIGKILL" => Some(9),
|
|
|
|
"SIGBUS" => Some(10),
|
|
|
|
"SIGSEGV" => Some(11),
|
|
|
|
"SIGSYS" => Some(12),
|
|
|
|
"SIGPIPE" => Some(13),
|
|
|
|
"SIGALRM" => Some(14),
|
|
|
|
"SIGTERM" => Some(15),
|
|
|
|
"SIGURG" => Some(16),
|
|
|
|
"SIGSTOP" => Some(17),
|
|
|
|
"SIGTSTP" => Some(18),
|
|
|
|
"SIGCONT" => Some(19),
|
|
|
|
"SIGCHLD" => Some(20),
|
|
|
|
"SIGTTIN" => Some(21),
|
|
|
|
"SIGTTOU" => Some(22),
|
|
|
|
"SIGIO" => Some(23),
|
|
|
|
"SIGXCPU" => Some(24),
|
|
|
|
"SIGXFSZ" => Some(25),
|
|
|
|
"SIGVTALRM" => Some(26),
|
|
|
|
"SIGPROF" => Some(27),
|
|
|
|
"SIGWINCH" => Some(28),
|
|
|
|
"SIGINFO" => Some(29),
|
|
|
|
"SIGUSR1" => Some(30),
|
|
|
|
"SIGUSR2" => Some(31),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_os = "windows")]
|
2021-09-07 10:39:32 -04:00
|
|
|
fn signal_str_to_int(_s: &str) -> Option<libc::c_int> {
|
2021-09-06 10:05:33 -04:00
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn signal_str_to_int_unwrap(s: &str) -> Result<libc::c_int, AnyError> {
|
|
|
|
signal_str_to_int(s)
|
|
|
|
.ok_or_else(|| type_error(format!("Invalid signal : {}", s)))
|
|
|
|
}
|
|
|
|
|
2020-01-24 08:15:31 -05:00
|
|
|
#[cfg(unix)]
|
|
|
|
fn op_signal_bind(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: &mut OpState,
|
2021-09-06 10:05:33 -04:00
|
|
|
sig: String,
|
2021-05-08 08:37:42 -04:00
|
|
|
_: (),
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<ResourceId, AnyError> {
|
2020-09-26 14:26:51 -04:00
|
|
|
super::check_unstable(state, "Deno.signal");
|
2021-09-06 10:05:33 -04:00
|
|
|
let signo = signal_str_to_int_unwrap(&sig)?;
|
2020-12-16 11:14:12 -05:00
|
|
|
let resource = SignalStreamResource {
|
2021-09-06 10:05:33 -04:00
|
|
|
signal: AsyncRefCell::new(signal(SignalKind::from_raw(signo)).unwrap()),
|
2020-12-16 11:14:12 -05:00
|
|
|
cancel: Default::default(),
|
|
|
|
};
|
|
|
|
let rid = state.resource_table.add(resource);
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(rid)
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
2020-08-28 11:08:24 -04:00
|
|
|
async fn op_signal_poll(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: Rc<RefCell<OpState>>,
|
2021-04-05 12:40:24 -04:00
|
|
|
rid: ResourceId,
|
2021-05-08 08:37:42 -04:00
|
|
|
_: (),
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<bool, AnyError> {
|
2020-09-26 14:26:51 -04:00
|
|
|
super::check_unstable2(&state, "Deno.signal");
|
2020-01-24 08:15:31 -05:00
|
|
|
|
2020-12-16 11:14:12 -05:00
|
|
|
let resource = state
|
|
|
|
.borrow_mut()
|
|
|
|
.resource_table
|
2021-08-15 07:29:19 -04:00
|
|
|
.get::<SignalStreamResource>(rid)?;
|
2020-12-16 11:14:12 -05:00
|
|
|
let cancel = RcRef::map(&resource, |r| &r.cancel);
|
|
|
|
let mut signal = RcRef::map(&resource, |r| &r.signal).borrow_mut().await;
|
|
|
|
|
|
|
|
match signal.recv().or_cancel(cancel).await {
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(result) => Ok(result.is_none()),
|
|
|
|
Err(_) => Ok(true),
|
2020-12-16 11:14:12 -05:00
|
|
|
}
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
pub fn op_signal_unbind(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: &mut OpState,
|
2021-04-05 12:40:24 -04:00
|
|
|
rid: ResourceId,
|
2021-05-08 08:37:42 -04:00
|
|
|
_: (),
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-09-26 14:26:51 -04:00
|
|
|
super::check_unstable(state, "Deno.signal");
|
2021-08-15 07:29:19 -04:00
|
|
|
state.resource_table.close(rid)?;
|
2021-04-05 12:40:24 -04:00
|
|
|
Ok(())
|
2020-01-24 08:15:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
pub fn op_signal_bind(
|
2020-09-10 09:57:45 -04:00
|
|
|
_state: &mut OpState,
|
2021-04-05 12:40:24 -04:00
|
|
|
_args: (),
|
2021-05-08 08:37:42 -04:00
|
|
|
_: (),
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-01-24 08:15:31 -05:00
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
fn op_signal_unbind(
|
2020-09-10 09:57:45 -04:00
|
|
|
_state: &mut OpState,
|
2021-04-05 12:40:24 -04:00
|
|
|
_args: (),
|
2021-05-08 08:37:42 -04:00
|
|
|
_: (),
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-01-24 08:15:31 -05:00
|
|
|
unimplemented!();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
2020-08-28 11:08:24 -04:00
|
|
|
async fn op_signal_poll(
|
2020-09-10 09:57:45 -04:00
|
|
|
_state: Rc<RefCell<OpState>>,
|
2021-04-05 12:40:24 -04:00
|
|
|
_args: (),
|
2021-05-08 08:37:42 -04:00
|
|
|
_: (),
|
2021-04-05 12:40:24 -04:00
|
|
|
) -> Result<(), AnyError> {
|
2020-01-24 08:15:31 -05:00
|
|
|
unimplemented!();
|
|
|
|
}
|