mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
refactor(runtime): use new fd methods from resource table (#20010)
Prereq for fast streams work. No longer need `#[cfg]` around `backing_fd`.
This commit is contained in:
parent
ab2627a014
commit
45572e329a
4 changed files with 93 additions and 150 deletions
|
@ -17,6 +17,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::BufMutView;
|
||||
use deno_core::BufView;
|
||||
use deno_core::ResourceHandleFd;
|
||||
use deno_runtime::deno_fs::FsDirEntry;
|
||||
use deno_runtime::deno_io;
|
||||
use deno_runtime::deno_io::fs::FsError;
|
||||
|
@ -697,12 +698,7 @@ impl deno_io::fs::File for FileBackedVfsFile {
|
|||
fn as_stdio(self: Rc<Self>) -> FsResult<std::process::Stdio> {
|
||||
Err(FsError::NotSupported)
|
||||
}
|
||||
#[cfg(unix)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::unix::prelude::RawFd> {
|
||||
None
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::windows::io::RawHandle> {
|
||||
fn backing_fd(self: Rc<Self>) -> Option<ResourceHandleFd> {
|
||||
None
|
||||
}
|
||||
fn try_clone_inner(self: Rc<Self>) -> FsResult<Rc<dyn deno_io::fs::File>> {
|
||||
|
|
16
ext/io/fs.rs
16
ext/io/fs.rs
|
@ -12,6 +12,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::BufMutView;
|
||||
use deno_core::BufView;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ResourceHandleFd;
|
||||
use deno_core::ResourceId;
|
||||
use tokio::task::JoinError;
|
||||
|
||||
|
@ -236,10 +237,7 @@ pub trait File {
|
|||
|
||||
// lower level functionality
|
||||
fn as_stdio(self: Rc<Self>) -> FsResult<std::process::Stdio>;
|
||||
#[cfg(unix)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::unix::prelude::RawFd>;
|
||||
#[cfg(windows)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::windows::io::RawHandle>;
|
||||
fn backing_fd(self: Rc<Self>) -> Option<ResourceHandleFd>;
|
||||
fn try_clone_inner(self: Rc<Self>) -> FsResult<Rc<dyn File>>;
|
||||
}
|
||||
|
||||
|
@ -253,7 +251,7 @@ impl FileResource {
|
|||
Self { name, file }
|
||||
}
|
||||
|
||||
pub fn with_resource<F, R>(
|
||||
fn with_resource<F, R>(
|
||||
state: &OpState,
|
||||
rid: ResourceId,
|
||||
f: F,
|
||||
|
@ -359,13 +357,7 @@ impl deno_core::Resource for FileResource {
|
|||
self.file.clone().write_sync(data).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::unix::prelude::RawFd> {
|
||||
self.file.clone().backing_fd()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::windows::io::RawHandle> {
|
||||
fn backing_fd(self: Rc<Self>) -> Option<ResourceHandleFd> {
|
||||
self.file.clone().backing_fd()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ use deno_core::Op;
|
|||
use deno_core::OpState;
|
||||
use deno_core::RcRef;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceHandle;
|
||||
use deno_core::ResourceHandleFd;
|
||||
use deno_core::TaskQueue;
|
||||
use fs::FileResource;
|
||||
use fs::FsError;
|
||||
|
@ -308,6 +310,7 @@ pub struct StdFileResourceInner {
|
|||
// Used to keep async actions in order and only allow one
|
||||
// to occur at a time
|
||||
cell_async_task_queue: TaskQueue,
|
||||
handle: ResourceHandleFd,
|
||||
}
|
||||
|
||||
impl StdFileResourceInner {
|
||||
|
@ -316,8 +319,11 @@ impl StdFileResourceInner {
|
|||
}
|
||||
|
||||
fn new(kind: StdFileResourceKind, fs_file: StdFile) -> Self {
|
||||
// We know this will be an fd
|
||||
let handle = ResourceHandle::from_fd_like(&fs_file).as_fd_like().unwrap();
|
||||
StdFileResourceInner {
|
||||
kind,
|
||||
handle,
|
||||
cell: RefCell::new(Some(fs_file)),
|
||||
cell_async_task_queue: Default::default(),
|
||||
}
|
||||
|
@ -705,6 +711,7 @@ impl crate::fs::File for StdFileResourceInner {
|
|||
kind: self.kind,
|
||||
cell: RefCell::new(Some(inner.try_clone()?)),
|
||||
cell_async_task_queue: Default::default(),
|
||||
handle: self.handle,
|
||||
})),
|
||||
None => Err(FsError::FileBusy),
|
||||
}
|
||||
|
@ -720,16 +727,8 @@ impl crate::fs::File for StdFileResourceInner {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::unix::prelude::RawFd> {
|
||||
use std::os::unix::io::AsRawFd;
|
||||
self.with_sync(|file| Ok(file.as_raw_fd())).ok()
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn backing_fd(self: Rc<Self>) -> Option<std::os::windows::io::RawHandle> {
|
||||
use std::os::windows::prelude::AsRawHandle;
|
||||
self.with_sync(|file| Ok(file.as_raw_handle())).ok()
|
||||
fn backing_fd(self: Rc<Self>) -> Option<ResourceHandleFd> {
|
||||
Some(self.handle)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,9 @@
|
|||
use std::io::Error;
|
||||
use std::rc::Rc;
|
||||
|
||||
use deno_core::error::resource_unavailable;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_io::fs::FileResource;
|
||||
|
||||
#[cfg(unix)]
|
||||
use deno_core::ResourceId;
|
||||
|
@ -45,35 +42,6 @@ use winapi::shared::minwindef::DWORD;
|
|||
#[cfg(windows)]
|
||||
use winapi::um::wincon;
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_fd_from_resource(
|
||||
resource: Rc<FileResource>,
|
||||
) -> Result<std::os::windows::io::RawHandle, AnyError> {
|
||||
use winapi::um::handleapi;
|
||||
|
||||
#[allow(deprecated)]
|
||||
let Some(handle) = resource.backing_fd() else {
|
||||
return Err(resource_unavailable());
|
||||
};
|
||||
if handle == handleapi::INVALID_HANDLE_VALUE {
|
||||
return Err(Error::last_os_error().into());
|
||||
} else if handle.is_null() {
|
||||
return Err(custom_error("ReferenceError", "null handle"));
|
||||
}
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn get_fd_from_resource(
|
||||
resource: Rc<FileResource>,
|
||||
) -> Result<std::os::unix::prelude::RawFd, AnyError> {
|
||||
#[allow(deprecated)]
|
||||
match resource.backing_fd() {
|
||||
Some(fd) => Ok(fd),
|
||||
None => Err(resource_unavailable()),
|
||||
}
|
||||
}
|
||||
|
||||
deno_core::extension!(
|
||||
deno_tty,
|
||||
ops = [op_stdin_set_raw, op_isatty, op_console_size],
|
||||
|
@ -110,6 +78,7 @@ fn op_stdin_set_raw(
|
|||
cbreak: bool,
|
||||
) -> Result<(), AnyError> {
|
||||
let rid = 0; // stdin is always rid=0
|
||||
let handle_or_fd = state.resource_table.get_fd(rid)?;
|
||||
|
||||
// From https://github.com/kkawakam/rustyline/blob/master/src/tty/windows.rs
|
||||
// and https://github.com/kkawakam/rustyline/blob/master/src/tty/unix.rs
|
||||
|
@ -121,79 +90,76 @@ fn op_stdin_set_raw(
|
|||
use winapi::shared::minwindef::FALSE;
|
||||
use winapi::um::consoleapi;
|
||||
|
||||
let handle = handle_or_fd;
|
||||
|
||||
if cbreak {
|
||||
return Err(deno_core::error::not_supported());
|
||||
}
|
||||
|
||||
FileResource::with_resource(state, rid, move |resource| {
|
||||
let handle = get_fd_from_resource(resource)?;
|
||||
let mut original_mode: DWORD = 0;
|
||||
// SAFETY: winapi call
|
||||
if unsafe { consoleapi::GetConsoleMode(handle, &mut original_mode) }
|
||||
== FALSE
|
||||
{
|
||||
return Err(Error::last_os_error().into());
|
||||
}
|
||||
let mut original_mode: DWORD = 0;
|
||||
// SAFETY: winapi call
|
||||
if unsafe { consoleapi::GetConsoleMode(handle, &mut original_mode) }
|
||||
== FALSE
|
||||
{
|
||||
return Err(Error::last_os_error().into());
|
||||
}
|
||||
|
||||
let new_mode = if is_raw {
|
||||
mode_raw_input_on(original_mode)
|
||||
} else {
|
||||
mode_raw_input_off(original_mode)
|
||||
};
|
||||
let new_mode = if is_raw {
|
||||
mode_raw_input_on(original_mode)
|
||||
} else {
|
||||
mode_raw_input_off(original_mode)
|
||||
};
|
||||
|
||||
// SAFETY: winapi call
|
||||
if unsafe { consoleapi::SetConsoleMode(handle, new_mode) } == FALSE {
|
||||
return Err(Error::last_os_error().into());
|
||||
}
|
||||
// SAFETY: winapi call
|
||||
if unsafe { consoleapi::SetConsoleMode(handle, new_mode) } == FALSE {
|
||||
return Err(Error::last_os_error().into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let tty_mode_store = state.borrow::<TtyModeStore>().clone();
|
||||
let previous_mode = tty_mode_store.get(rid);
|
||||
|
||||
FileResource::with_resource(state, rid, move |resource| {
|
||||
let raw_fd = get_fd_from_resource(resource)?;
|
||||
let raw_fd = handle_or_fd;
|
||||
|
||||
if is_raw {
|
||||
let mut raw = match previous_mode {
|
||||
Some(mode) => mode,
|
||||
None => {
|
||||
// Save original mode.
|
||||
let original_mode = termios::tcgetattr(raw_fd)?;
|
||||
tty_mode_store.set(rid, original_mode.clone());
|
||||
original_mode
|
||||
}
|
||||
};
|
||||
|
||||
raw.input_flags &= !(termios::InputFlags::BRKINT
|
||||
| termios::InputFlags::ICRNL
|
||||
| termios::InputFlags::INPCK
|
||||
| termios::InputFlags::ISTRIP
|
||||
| termios::InputFlags::IXON);
|
||||
|
||||
raw.control_flags |= termios::ControlFlags::CS8;
|
||||
|
||||
raw.local_flags &= !(termios::LocalFlags::ECHO
|
||||
| termios::LocalFlags::ICANON
|
||||
| termios::LocalFlags::IEXTEN);
|
||||
if !cbreak {
|
||||
raw.local_flags &= !(termios::LocalFlags::ISIG);
|
||||
}
|
||||
raw.control_chars[termios::SpecialCharacterIndices::VMIN as usize] = 1;
|
||||
raw.control_chars[termios::SpecialCharacterIndices::VTIME as usize] = 0;
|
||||
termios::tcsetattr(raw_fd, termios::SetArg::TCSADRAIN, &raw)?;
|
||||
} else {
|
||||
// Try restore saved mode.
|
||||
if let Some(mode) = tty_mode_store.take(rid) {
|
||||
termios::tcsetattr(raw_fd, termios::SetArg::TCSADRAIN, &mode)?;
|
||||
if is_raw {
|
||||
let mut raw = match previous_mode {
|
||||
Some(mode) => mode,
|
||||
None => {
|
||||
// Save original mode.
|
||||
let original_mode = termios::tcgetattr(raw_fd)?;
|
||||
tty_mode_store.set(rid, original_mode.clone());
|
||||
original_mode
|
||||
}
|
||||
};
|
||||
|
||||
raw.input_flags &= !(termios::InputFlags::BRKINT
|
||||
| termios::InputFlags::ICRNL
|
||||
| termios::InputFlags::INPCK
|
||||
| termios::InputFlags::ISTRIP
|
||||
| termios::InputFlags::IXON);
|
||||
|
||||
raw.control_flags |= termios::ControlFlags::CS8;
|
||||
|
||||
raw.local_flags &= !(termios::LocalFlags::ECHO
|
||||
| termios::LocalFlags::ICANON
|
||||
| termios::LocalFlags::IEXTEN);
|
||||
if !cbreak {
|
||||
raw.local_flags &= !(termios::LocalFlags::ISIG);
|
||||
}
|
||||
raw.control_chars[termios::SpecialCharacterIndices::VMIN as usize] = 1;
|
||||
raw.control_chars[termios::SpecialCharacterIndices::VTIME as usize] = 0;
|
||||
termios::tcsetattr(raw_fd, termios::SetArg::TCSADRAIN, &raw)?;
|
||||
} else {
|
||||
// Try restore saved mode.
|
||||
if let Some(mode) = tty_mode_store.take(rid) {
|
||||
termios::tcsetattr(raw_fd, termios::SetArg::TCSADRAIN, &mode)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,34 +169,26 @@ fn op_isatty(
|
|||
rid: u32,
|
||||
out: &mut [u8],
|
||||
) -> Result<(), AnyError> {
|
||||
FileResource::with_resource(state, rid, move |resource| {
|
||||
let raw_fd = get_fd_from_resource(resource)?;
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use winapi::shared::minwindef::FALSE;
|
||||
use winapi::um::consoleapi;
|
||||
let raw_fd = state.resource_table.get_fd(rid)?;
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use winapi::shared::minwindef::FALSE;
|
||||
use winapi::um::consoleapi;
|
||||
|
||||
let handle = raw_fd;
|
||||
let mut test_mode: DWORD = 0;
|
||||
// If I cannot get mode out of console, it is not a console.
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
{
|
||||
out[0] = unsafe {
|
||||
consoleapi::GetConsoleMode(handle, &mut test_mode) != FALSE
|
||||
} as u8;
|
||||
}
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
{
|
||||
out[0] = unsafe { libc::isatty(raw_fd as libc::c_int) == 1 } as u8;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
let handle = raw_fd;
|
||||
let mut test_mode: DWORD = 0;
|
||||
// If I cannot get mode out of console, it is not a console.
|
||||
out[0] =
|
||||
// SAFETY: Windows API
|
||||
unsafe { consoleapi::GetConsoleMode(handle, &mut test_mode) != FALSE }
|
||||
as u8;
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
// SAFETY: Posix API
|
||||
out[0] = unsafe { libc::isatty(raw_fd as libc::c_int) == 1 } as u8;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[op(fast)]
|
||||
|
@ -243,13 +201,11 @@ fn op_console_size(
|
|||
result: &mut [u32],
|
||||
rid: u32,
|
||||
) -> Result<(), AnyError> {
|
||||
FileResource::with_resource(state, rid, move |resource| {
|
||||
let fd = get_fd_from_resource(resource)?;
|
||||
let size = console_size_from_fd(fd)?;
|
||||
result[0] = size.cols;
|
||||
result[1] = size.rows;
|
||||
Ok(())
|
||||
})
|
||||
let fd = state.resource_table.get_fd(rid)?;
|
||||
let size = console_size_from_fd(fd)?;
|
||||
result[0] = size.cols;
|
||||
result[1] = size.rows;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let mut last_result = Ok(());
|
||||
|
|
Loading…
Add table
Reference in a new issue