diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/io/bi_pipe.rs | 6 | ||||
-rw-r--r-- | ext/io/lib.rs | 107 | ||||
-rw-r--r-- | ext/io/pipe.rs | 2 | ||||
-rw-r--r-- | ext/node/lib.rs | 29 | ||||
-rw-r--r-- | ext/node/polyfills/child_process.ts | 7 | ||||
-rw-r--r-- | ext/node/polyfills/internal/child_process.ts | 9 |
6 files changed, 121 insertions, 39 deletions
diff --git a/ext/io/bi_pipe.rs b/ext/io/bi_pipe.rs index 04fff7b00..402e383ac 100644 --- a/ext/io/bi_pipe.rs +++ b/ext/io/bi_pipe.rs @@ -11,11 +11,7 @@ use deno_core::RcRef; use tokio::io::AsyncReadExt; use tokio::io::AsyncWriteExt; -#[cfg(unix)] -pub type RawBiPipeHandle = std::os::fd::RawFd; - -#[cfg(windows)] -pub type RawBiPipeHandle = std::os::windows::io::RawHandle; +pub type RawBiPipeHandle = super::RawIoHandle; /// One end of a bidirectional pipe. This implements the /// `Resource` trait. diff --git a/ext/io/lib.rs b/ext/io/lib.rs index 47921bcee..a07d64ae3 100644 --- a/ext/io/lib.rs +++ b/ext/io/lib.rs @@ -67,6 +67,7 @@ pub use pipe::AsyncPipeRead; pub use pipe::AsyncPipeWrite; pub use pipe::PipeRead; pub use pipe::PipeWrite; +pub use pipe::RawPipeHandle; pub use bi_pipe::bi_pipe_pair_raw; pub use bi_pipe::BiPipe; @@ -75,6 +76,112 @@ pub use bi_pipe::BiPipeResource; pub use bi_pipe::BiPipeWrite; pub use bi_pipe::RawBiPipeHandle; +/// Abstraction over `AsRawFd` (unix) and `AsRawHandle` (windows) +pub trait AsRawIoHandle { + fn as_raw_io_handle(&self) -> RawIoHandle; +} + +#[cfg(unix)] +impl<T> AsRawIoHandle for T +where + T: std::os::unix::io::AsRawFd, +{ + fn as_raw_io_handle(&self) -> RawIoHandle { + self.as_raw_fd() + } +} + +#[cfg(windows)] +impl<T> AsRawIoHandle for T +where + T: std::os::windows::io::AsRawHandle, +{ + fn as_raw_io_handle(&self) -> RawIoHandle { + self.as_raw_handle() + } +} + +/// Abstraction over `IntoRawFd` (unix) and `IntoRawHandle` (windows) +pub trait IntoRawIoHandle { + fn into_raw_io_handle(self) -> RawIoHandle; +} + +#[cfg(unix)] +impl<T> IntoRawIoHandle for T +where + T: std::os::unix::io::IntoRawFd, +{ + fn into_raw_io_handle(self) -> RawIoHandle { + self.into_raw_fd() + } +} + +#[cfg(windows)] +impl<T> IntoRawIoHandle for T +where + T: std::os::windows::io::IntoRawHandle, +{ + fn into_raw_io_handle(self) -> RawIoHandle { + self.into_raw_handle() + } +} + +/// Abstraction over `FromRawFd` (unix) and `FromRawHandle` (windows) +pub trait FromRawIoHandle: Sized { + /// Constructs a type from a raw io handle (fd/HANDLE). + /// + /// # Safety + /// + /// Refer to the standard library docs ([unix](https://doc.rust-lang.org/stable/std/os/windows/io/trait.FromRawHandle.html#tymethod.from_raw_handle)) ([windows](https://doc.rust-lang.org/stable/std/os/fd/trait.FromRawFd.html#tymethod.from_raw_fd)) + /// + unsafe fn from_raw_io_handle(handle: RawIoHandle) -> Self; +} + +#[cfg(unix)] +impl<T> FromRawIoHandle for T +where + T: std::os::unix::io::FromRawFd, +{ + unsafe fn from_raw_io_handle(fd: RawIoHandle) -> T { + // SAFETY: upheld by caller + unsafe { T::from_raw_fd(fd) } + } +} + +#[cfg(windows)] +impl<T> FromRawIoHandle for T +where + T: std::os::windows::io::FromRawHandle, +{ + unsafe fn from_raw_io_handle(fd: RawIoHandle) -> T { + // SAFETY: upheld by caller + unsafe { T::from_raw_handle(fd) } + } +} + +#[cfg(unix)] +pub type RawIoHandle = std::os::fd::RawFd; + +#[cfg(windows)] +pub type RawIoHandle = std::os::windows::io::RawHandle; + +pub fn close_raw_handle(handle: RawIoHandle) { + #[cfg(unix)] + { + // SAFETY: libc call + unsafe { + libc::close(handle); + } + } + #[cfg(windows)] + { + // SAFETY: win32 call + unsafe { + windows_sys::Win32::Foundation::CloseHandle(handle as _); + } + } +} + // Store the stdio fd/handles in global statics in order to keep them // alive for the duration of the application since the last handle/fd // being dropped will close the corresponding pipe. diff --git a/ext/io/pipe.rs b/ext/io/pipe.rs index 70788f752..e0e019e27 100644 --- a/ext/io/pipe.rs +++ b/ext/io/pipe.rs @@ -3,6 +3,8 @@ use std::io; use std::pin::Pin; use std::process::Stdio; +pub type RawPipeHandle = super::RawIoHandle; + // The synchronous read end of a unidirectional pipe. pub struct PipeRead { file: std::fs::File, diff --git a/ext/node/lib.rs b/ext/node/lib.rs index af14e3e85..0c821ecf8 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -16,7 +16,6 @@ use deno_core::url::Url; use deno_core::v8; use deno_core::v8::ExternalReference; use deno_core::JsRuntime; -use deno_core::OpState; use deno_fs::sync::MaybeSend; use deno_fs::sync::MaybeSync; use node_resolver::NpmResolverRc; @@ -121,24 +120,6 @@ impl NodePermissions for deno_permissions::PermissionsContainer { } #[allow(clippy::disallowed_types)] -pub type NpmProcessStateProviderRc = - deno_fs::sync::MaybeArc<dyn NpmProcessStateProvider>; - -pub trait NpmProcessStateProvider: - std::fmt::Debug + MaybeSend + MaybeSync -{ - /// Gets a string containing the serialized npm state of the process. - /// - /// This will be set on the `DENO_DONT_USE_INTERNAL_NODE_COMPAT_STATE` environment - /// variable when doing a `child_process.fork`. The implementor can then check this environment - /// variable on startup to repopulate the internal npm state. - fn get_npm_process_state(&self) -> String { - // This method is only used in the CLI. - String::new() - } -} - -#[allow(clippy::disallowed_types)] pub type NodeRequireResolverRc = deno_fs::sync::MaybeArc<dyn NodeRequireResolver>; @@ -165,17 +146,9 @@ fn op_node_build_os() -> String { env!("TARGET").split('-').nth(2).unwrap().to_string() } -#[op2] -#[string] -fn op_npm_process_state(state: &mut OpState) -> Result<String, AnyError> { - let npm_resolver = state.borrow_mut::<NpmProcessStateProviderRc>(); - Ok(npm_resolver.get_npm_process_state()) -} - pub struct NodeExtInitServices { pub node_require_resolver: NodeRequireResolverRc, pub node_resolver: NodeResolverRc, - pub npm_process_state_provider: NpmProcessStateProviderRc, pub npm_resolver: NpmResolverRc, } @@ -374,7 +347,6 @@ deno_core::extension!(deno_node, ops::os::op_cpus<P>, ops::os::op_homedir<P>, op_node_build_os, - op_npm_process_state, ops::require::op_require_can_parse_as_esm, ops::require::op_require_init_paths, ops::require::op_require_node_module_paths<P>, @@ -662,7 +634,6 @@ deno_core::extension!(deno_node, state.put(init.node_require_resolver.clone()); state.put(init.node_resolver.clone()); state.put(init.npm_resolver.clone()); - state.put(init.npm_process_state_provider.clone()); } }, global_template_middleware = global_template_middleware, diff --git a/ext/node/polyfills/child_process.ts b/ext/node/polyfills/child_process.ts index f77a430c2..c37dfc410 100644 --- a/ext/node/polyfills/child_process.ts +++ b/ext/node/polyfills/child_process.ts @@ -10,7 +10,6 @@ import { internals } from "ext:core/mod.js"; import { op_bootstrap_unstable_args, op_node_child_ipc_pipe, - op_npm_process_state, } from "ext:core/ops"; import { @@ -54,6 +53,7 @@ import { convertToValidSignal, kEmptyObject, } from "ext:deno_node/internal/util.mjs"; +import { kNeedsNpmProcessState } from "ext:runtime/40_process.js"; const MAX_BUFFER = 1024 * 1024; @@ -168,9 +168,8 @@ export function fork( options.execPath = options.execPath || Deno.execPath(); options.shell = false; - Object.assign(options.env ??= {}, { - DENO_DONT_USE_INTERNAL_NODE_COMPAT_STATE: op_npm_process_state(), - }); + // deno-lint-ignore no-explicit-any + (options as any)[kNeedsNpmProcessState] = true; return spawn(options.execPath, args, options); } diff --git a/ext/node/polyfills/internal/child_process.ts b/ext/node/polyfills/internal/child_process.ts index 56fc21f35..6f209b719 100644 --- a/ext/node/polyfills/internal/child_process.ts +++ b/ext/node/polyfills/internal/child_process.ts @@ -56,7 +56,12 @@ import { StringPrototypeSlice } from "ext:deno_node/internal/primordials.mjs"; import { StreamBase } from "ext:deno_node/internal_binding/stream_wrap.ts"; import { Pipe, socketType } from "ext:deno_node/internal_binding/pipe_wrap.ts"; import { Socket } from "node:net"; -import { kDetached, kExtraStdio, kIpc } from "ext:runtime/40_process.js"; +import { + kDetached, + kExtraStdio, + kIpc, + kNeedsNpmProcessState, +} from "ext:runtime/40_process.js"; export function mapValues<T, O>( record: Readonly<Record<string, T>>, @@ -281,6 +286,8 @@ export class ChildProcess extends EventEmitter { [kIpc]: ipc, // internal [kExtraStdio]: extraStdioNormalized, [kDetached]: detached, + // deno-lint-ignore no-explicit-any + [kNeedsNpmProcessState]: (options ?? {} as any)[kNeedsNpmProcessState], }).spawn(); this.pid = this.#process.pid; |