2022-01-07 22:09:52 -05:00
|
|
|
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
2021-09-07 23:34:46 +08:00
|
|
|
#[cfg(not(unix))]
|
|
|
|
use deno_core::error::generic_error;
|
2021-09-07 18:45:13 -04:00
|
|
|
#[cfg(not(target_os = "windows"))]
|
2021-09-06 10:05:33 -04:00
|
|
|
use deno_core::error::type_error;
|
2020-09-14 18:48:57 +02:00
|
|
|
use deno_core::error::AnyError;
|
2022-03-14 23:14:15 +05:30
|
|
|
use deno_core::op;
|
2022-05-14 14:10:39 +02:00
|
|
|
use serde::Deserialize;
|
|
|
|
use serde::Serialize;
|
2022-03-14 23:14:15 +05:30
|
|
|
|
2021-05-03 01:22:57 +02:00
|
|
|
use deno_core::Extension;
|
2022-03-21 09:30:43 -04:00
|
|
|
#[cfg(unix)]
|
2020-09-10 09:57:45 -04:00
|
|
|
use deno_core::OpState;
|
2022-03-21 09:30:43 -04:00
|
|
|
#[cfg(unix)]
|
2020-09-10 09:57:45 -04:00
|
|
|
use std::cell::RefCell;
|
2022-03-21 09:30:43 -04:00
|
|
|
#[cfg(unix)]
|
2020-08-18 18:30:13 +02:00
|
|
|
use std::rc::Rc;
|
2020-01-24 22:15:31 +09:00
|
|
|
|
|
|
|
#[cfg(unix)]
|
2020-12-16 17:14:12 +01: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 18:40:24 +02:00
|
|
|
use deno_core::ResourceId;
|
2020-09-06 02:34:02 +02:00
|
|
|
#[cfg(unix)]
|
2020-12-16 17:14:12 +01:00
|
|
|
use std::borrow::Cow;
|
2020-01-24 22:15:31 +09:00
|
|
|
#[cfg(unix)]
|
2022-05-14 14:10:39 +02:00
|
|
|
use tokio::signal::unix::{signal, Signal as TokioSignal, SignalKind};
|
2020-01-24 22:15:31 +09:00
|
|
|
|
2021-05-03 01:22:57 +02:00
|
|
|
pub fn init() -> Extension {
|
|
|
|
Extension::builder()
|
|
|
|
.ops(vec![
|
2022-03-14 23:14:15 +05:30
|
|
|
op_signal_bind::decl(),
|
|
|
|
op_signal_unbind::decl(),
|
|
|
|
op_signal_poll::decl(),
|
2021-05-03 01:22:57 +02:00
|
|
|
])
|
|
|
|
.build()
|
2020-01-24 22:15:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
|
|
|
/// The resource for signal stream.
|
|
|
|
/// The second element is the waker of polling future.
|
2020-12-16 17:14:12 +01:00
|
|
|
struct SignalStreamResource {
|
2022-05-14 14:10:39 +02:00
|
|
|
signal: AsyncRefCell<TokioSignal>,
|
2020-12-16 17:14:12 +01:00
|
|
|
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 22:15:31 +09:00
|
|
|
|
2021-09-21 15:16:05 +02:00
|
|
|
#[cfg(target_os = "freebsd")]
|
2022-05-14 14:10:39 +02:00
|
|
|
#[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,
|
2021-09-21 15:16:05 +02:00
|
|
|
}
|
|
|
|
|
2022-01-20 07:56:33 +05:30
|
|
|
#[cfg(any(target_os = "android", target_os = "linux"))]
|
2022-05-14 14:10:39 +02:00
|
|
|
#[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,
|
2021-09-06 10:05:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(target_os = "macos")]
|
2022-05-14 14:10:39 +02:00
|
|
|
#[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,
|
2021-09-06 10:05:33 -04:00
|
|
|
}
|
|
|
|
|
2022-03-29 11:00:20 +09:00
|
|
|
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
2022-05-14 14:10:39 +02:00
|
|
|
#[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,
|
2022-03-29 11:00:20 +09:00
|
|
|
}
|
|
|
|
|
2020-01-24 22:15:31 +09:00
|
|
|
#[cfg(unix)]
|
2022-03-14 23:14:15 +05:30
|
|
|
#[op]
|
2020-01-24 22:15:31 +09:00
|
|
|
fn op_signal_bind(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: &mut OpState,
|
2022-05-14 14:10:39 +02:00
|
|
|
sig: Signal,
|
2021-04-05 18:40:24 +02:00
|
|
|
) -> Result<ResourceId, AnyError> {
|
2022-05-14 14:10:39 +02:00
|
|
|
let signo = sig as libc::c_int;
|
2022-01-04 21:55:06 +01:00
|
|
|
if signal_hook_registry::FORBIDDEN.contains(&signo) {
|
|
|
|
return Err(type_error(format!(
|
2022-05-14 14:10:39 +02:00
|
|
|
"Binding to signal '{:?}' is not allowed",
|
2022-01-04 21:55:06 +01:00
|
|
|
sig
|
|
|
|
)));
|
|
|
|
}
|
2020-12-16 17:14:12 +01:00
|
|
|
let resource = SignalStreamResource {
|
2022-01-04 21:55:06 +01:00
|
|
|
signal: AsyncRefCell::new(signal(SignalKind::from_raw(signo))?),
|
2020-12-16 17:14:12 +01:00
|
|
|
cancel: Default::default(),
|
|
|
|
};
|
|
|
|
let rid = state.resource_table.add(resource);
|
2021-04-05 18:40:24 +02:00
|
|
|
Ok(rid)
|
2020-01-24 22:15:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
2022-03-14 23:14:15 +05:30
|
|
|
#[op]
|
2020-08-28 17:08:24 +02:00
|
|
|
async fn op_signal_poll(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: Rc<RefCell<OpState>>,
|
2021-04-05 18:40:24 +02:00
|
|
|
rid: ResourceId,
|
|
|
|
) -> Result<bool, AnyError> {
|
2020-12-16 17:14:12 +01:00
|
|
|
let resource = state
|
|
|
|
.borrow_mut()
|
|
|
|
.resource_table
|
2021-08-15 13:29:19 +02:00
|
|
|
.get::<SignalStreamResource>(rid)?;
|
2020-12-16 17:14:12 +01: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 18:40:24 +02:00
|
|
|
Ok(result) => Ok(result.is_none()),
|
|
|
|
Err(_) => Ok(true),
|
2020-12-16 17:14:12 +01:00
|
|
|
}
|
2020-01-24 22:15:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(unix)]
|
2022-03-14 23:14:15 +05:30
|
|
|
#[op]
|
2020-01-24 22:15:31 +09:00
|
|
|
pub fn op_signal_unbind(
|
2020-09-10 09:57:45 -04:00
|
|
|
state: &mut OpState,
|
2021-04-05 18:40:24 +02:00
|
|
|
rid: ResourceId,
|
|
|
|
) -> Result<(), AnyError> {
|
2021-08-15 13:29:19 +02:00
|
|
|
state.resource_table.close(rid)?;
|
2021-04-05 18:40:24 +02:00
|
|
|
Ok(())
|
2020-01-24 22:15:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
2022-03-14 23:14:15 +05:30
|
|
|
#[op]
|
2022-03-16 00:33:46 +01:00
|
|
|
pub fn op_signal_bind() -> Result<(), AnyError> {
|
2021-09-07 23:34:46 +08:00
|
|
|
Err(generic_error("not implemented"))
|
2020-01-24 22:15:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
2022-03-14 23:14:15 +05:30
|
|
|
#[op]
|
2022-03-16 00:33:46 +01:00
|
|
|
fn op_signal_unbind() -> Result<(), AnyError> {
|
2021-09-07 23:34:46 +08:00
|
|
|
Err(generic_error("not implemented"))
|
2020-01-24 22:15:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
2022-03-14 23:14:15 +05:30
|
|
|
#[op]
|
2022-03-16 00:33:46 +01:00
|
|
|
async fn op_signal_poll() -> Result<(), AnyError> {
|
2021-09-07 23:34:46 +08:00
|
|
|
Err(generic_error("not implemented"))
|
2020-01-24 22:15:31 +09:00
|
|
|
}
|