summaryrefslogtreecommitdiff
path: root/ext/io
diff options
context:
space:
mode:
Diffstat (limited to 'ext/io')
-rw-r--r--ext/io/Cargo.toml2
-rw-r--r--ext/io/bi_pipe.rs43
-rw-r--r--ext/io/fs.rs71
-rw-r--r--ext/io/lib.rs12
4 files changed, 66 insertions, 62 deletions
diff --git a/ext/io/Cargo.toml b/ext/io/Cargo.toml
index d45834a8f..6ef049ff9 100644
--- a/ext/io/Cargo.toml
+++ b/ext/io/Cargo.toml
@@ -2,7 +2,7 @@
[package]
name = "deno_io"
-version = "0.81.0"
+version = "0.87.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
diff --git a/ext/io/bi_pipe.rs b/ext/io/bi_pipe.rs
index 402e383ac..3492e2f44 100644
--- a/ext/io/bi_pipe.rs
+++ b/ext/io/bi_pipe.rs
@@ -2,7 +2,6 @@
use std::rc::Rc;
-use deno_core::error::AnyError;
use deno_core::AsyncRefCell;
use deno_core::AsyncResult;
use deno_core::CancelHandle;
@@ -71,13 +70,16 @@ impl BiPipeResource {
pub async fn read(
self: Rc<Self>,
data: &mut [u8],
- ) -> Result<usize, AnyError> {
+ ) -> Result<usize, std::io::Error> {
let mut rd = RcRef::map(&self, |r| &r.read_half).borrow_mut().await;
let cancel_handle = RcRef::map(&self, |r| &r.cancel);
- Ok(rd.read(data).try_or_cancel(cancel_handle).await?)
+ rd.read(data).try_or_cancel(cancel_handle).await
}
- pub async fn write(self: Rc<Self>, data: &[u8]) -> Result<usize, AnyError> {
+ pub async fn write(
+ self: Rc<Self>,
+ data: &[u8],
+ ) -> Result<usize, std::io::Error> {
let mut wr = RcRef::map(self, |r| &r.write_half).borrow_mut().await;
let nwritten = wr.write(data).await?;
wr.flush().await?;
@@ -181,9 +183,10 @@ fn from_raw(
) -> Result<(BiPipeRead, BiPipeWrite), std::io::Error> {
use std::os::fd::FromRawFd;
// Safety: The fd is part of a pair of connected sockets
- let unix_stream = tokio::net::UnixStream::from_std(unsafe {
- std::os::unix::net::UnixStream::from_raw_fd(stream)
- })?;
+ let unix_stream =
+ unsafe { std::os::unix::net::UnixStream::from_raw_fd(stream) };
+ unix_stream.set_nonblocking(true)?;
+ let unix_stream = tokio::net::UnixStream::from_std(unix_stream)?;
let (read, write) = unix_stream.into_split();
Ok((BiPipeRead { inner: read }, BiPipeWrite { inner: write }))
}
@@ -270,15 +273,15 @@ impl_async_write!(for BiPipe -> self.write_end);
/// Creates both sides of a bidirectional pipe, returning the raw
/// handles to the underlying OS resources.
-pub fn bi_pipe_pair_raw() -> Result<(RawBiPipeHandle, RawBiPipeHandle), AnyError>
-{
+pub fn bi_pipe_pair_raw(
+) -> Result<(RawBiPipeHandle, RawBiPipeHandle), std::io::Error> {
#[cfg(unix)]
{
// SockFlag is broken on macOS
// https://github.com/nix-rust/nix/issues/861
let mut fds = [-1, -1];
#[cfg(not(target_os = "macos"))]
- let flags = libc::SOCK_CLOEXEC | libc::SOCK_NONBLOCK;
+ let flags = libc::SOCK_CLOEXEC;
#[cfg(target_os = "macos")]
let flags = 0;
@@ -293,19 +296,19 @@ pub fn bi_pipe_pair_raw() -> Result<(RawBiPipeHandle, RawBiPipeHandle), AnyError
)
};
if ret != 0 {
- return Err(std::io::Error::last_os_error().into());
+ return Err(std::io::Error::last_os_error());
}
if cfg!(target_os = "macos") {
let fcntl = |fd: i32, flag: libc::c_int| -> Result<(), std::io::Error> {
// SAFETY: libc call, fd is valid
- let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
+ let flags = unsafe { libc::fcntl(fd, libc::F_GETFD) };
if flags == -1 {
return Err(fail(fds));
}
// SAFETY: libc call, fd is valid
- let ret = unsafe { libc::fcntl(fd, libc::F_SETFL, flags | flag) };
+ let ret = unsafe { libc::fcntl(fd, libc::F_SETFD, flags | flag) };
if ret == -1 {
return Err(fail(fds));
}
@@ -321,13 +324,9 @@ pub fn bi_pipe_pair_raw() -> Result<(RawBiPipeHandle, RawBiPipeHandle), AnyError
std::io::Error::last_os_error()
}
- // SOCK_NONBLOCK is not supported on macOS.
- (fcntl)(fds[0], libc::O_NONBLOCK)?;
- (fcntl)(fds[1], libc::O_NONBLOCK)?;
-
// SOCK_CLOEXEC is not supported on macOS.
- (fcntl)(fds[0], libc::FD_CLOEXEC)?;
- (fcntl)(fds[1], libc::FD_CLOEXEC)?;
+ fcntl(fds[0], libc::FD_CLOEXEC)?;
+ fcntl(fds[1], libc::FD_CLOEXEC)?;
}
let fd1 = fds[0];
@@ -389,7 +388,7 @@ pub fn bi_pipe_pair_raw() -> Result<(RawBiPipeHandle, RawBiPipeHandle), AnyError
continue;
}
- return Err(err.into());
+ return Err(err);
}
break (path, hd1);
@@ -411,7 +410,7 @@ pub fn bi_pipe_pair_raw() -> Result<(RawBiPipeHandle, RawBiPipeHandle), AnyError
0,
);
if hd2 == INVALID_HANDLE_VALUE {
- return Err(io::Error::last_os_error().into());
+ return Err(io::Error::last_os_error());
}
// Will not block because we have create the pair.
@@ -419,7 +418,7 @@ pub fn bi_pipe_pair_raw() -> Result<(RawBiPipeHandle, RawBiPipeHandle), AnyError
let err = std::io::Error::last_os_error();
if err.raw_os_error() != Some(ERROR_PIPE_CONNECTED as i32) {
CloseHandle(hd2);
- return Err(err.into());
+ return Err(err);
}
}
diff --git a/ext/io/fs.rs b/ext/io/fs.rs
index 3798c1429..7ef02315b 100644
--- a/ext/io/fs.rs
+++ b/ext/io/fs.rs
@@ -1,15 +1,12 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::borrow::Cow;
+use std::fmt::Formatter;
use std::io;
use std::rc::Rc;
use std::time::SystemTime;
use std::time::UNIX_EPOCH;
-use deno_core::error::custom_error;
-use deno_core::error::not_supported;
-use deno_core::error::resource_unavailable;
-use deno_core::error::AnyError;
use deno_core::BufMutView;
use deno_core::BufView;
use deno_core::OpState;
@@ -25,6 +22,21 @@ pub enum FsError {
NotCapable(&'static str),
}
+impl std::fmt::Display for FsError {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ match self {
+ FsError::Io(err) => std::fmt::Display::fmt(err, f),
+ FsError::FileBusy => f.write_str("file busy"),
+ FsError::NotSupported => f.write_str("not supported"),
+ FsError::NotCapable(err) => {
+ f.write_str(&format!("requires {err} access"))
+ }
+ }
+ }
+}
+
+impl std::error::Error for FsError {}
+
impl FsError {
pub fn kind(&self) -> io::ErrorKind {
match self {
@@ -59,19 +71,6 @@ impl From<io::ErrorKind> for FsError {
}
}
-impl From<FsError> for AnyError {
- fn from(err: FsError) -> Self {
- match err {
- FsError::Io(err) => AnyError::from(err),
- FsError::FileBusy => resource_unavailable(),
- FsError::NotSupported => not_supported(),
- FsError::NotCapable(err) => {
- custom_error("NotCapable", format!("permission denied: {err}"))
- }
- }
- }
-}
-
impl From<JoinError> for FsError {
fn from(err: JoinError) -> Self {
if err.is_cancelled() {
@@ -95,6 +94,7 @@ pub struct FsStat {
pub mtime: Option<u64>,
pub atime: Option<u64>,
pub birthtime: Option<u64>,
+ pub ctime: Option<u64>,
pub dev: u64,
pub ino: u64,
@@ -154,6 +154,16 @@ impl FsStat {
}
}
+ #[inline(always)]
+ fn get_ctime(ctime_or_0: i64) -> Option<u64> {
+ if ctime_or_0 > 0 {
+ // ctime return seconds since epoch, but we need milliseconds
+ return Some(ctime_or_0 as u64 * 1000);
+ }
+
+ None
+ }
+
Self {
is_file: metadata.is_file(),
is_directory: metadata.is_dir(),
@@ -163,6 +173,7 @@ impl FsStat {
mtime: to_msec(metadata.modified()),
atime: to_msec(metadata.accessed()),
birthtime: to_msec(metadata.created()),
+ ctime: get_ctime(unix_or_zero!(ctime)),
dev: unix_or_zero!(dev),
ino: unix_or_zero!(ino),
@@ -266,9 +277,9 @@ impl FileResource {
state: &OpState,
rid: ResourceId,
f: F,
- ) -> Result<R, AnyError>
+ ) -> Result<R, deno_core::error::AnyError>
where
- F: FnOnce(Rc<FileResource>) -> Result<R, AnyError>,
+ F: FnOnce(Rc<FileResource>) -> Result<R, deno_core::error::AnyError>,
{
let resource = state.resource_table.get::<FileResource>(rid)?;
f(resource)
@@ -277,7 +288,7 @@ impl FileResource {
pub fn get_file(
state: &OpState,
rid: ResourceId,
- ) -> Result<Rc<dyn File>, AnyError> {
+ ) -> Result<Rc<dyn File>, deno_core::error::AnyError> {
let resource = state.resource_table.get::<FileResource>(rid)?;
Ok(resource.file())
}
@@ -286,9 +297,9 @@ impl FileResource {
state: &OpState,
rid: ResourceId,
f: F,
- ) -> Result<R, AnyError>
+ ) -> Result<R, deno_core::error::AnyError>
where
- F: FnOnce(Rc<dyn File>) -> Result<R, AnyError>,
+ F: FnOnce(Rc<dyn File>) -> Result<R, deno_core::error::AnyError>,
{
Self::with_resource(state, rid, |r| f(r.file.clone()))
}
@@ -303,10 +314,7 @@ impl deno_core::Resource for FileResource {
Cow::Borrowed(&self.name)
}
- fn read(
- self: Rc<Self>,
- limit: usize,
- ) -> deno_core::AsyncResult<deno_core::BufView> {
+ fn read(self: Rc<Self>, limit: usize) -> deno_core::AsyncResult<BufView> {
Box::pin(async move {
self
.file
@@ -319,8 +327,8 @@ impl deno_core::Resource for FileResource {
fn read_byob(
self: Rc<Self>,
- buf: deno_core::BufMutView,
- ) -> deno_core::AsyncResult<(usize, deno_core::BufMutView)> {
+ buf: BufMutView,
+ ) -> deno_core::AsyncResult<(usize, BufMutView)> {
Box::pin(async move {
self
.file
@@ -333,17 +341,14 @@ impl deno_core::Resource for FileResource {
fn write(
self: Rc<Self>,
- buf: deno_core::BufView,
+ buf: BufView,
) -> deno_core::AsyncResult<deno_core::WriteOutcome> {
Box::pin(async move {
self.file.clone().write(buf).await.map_err(|err| err.into())
})
}
- fn write_all(
- self: Rc<Self>,
- buf: deno_core::BufView,
- ) -> deno_core::AsyncResult<()> {
+ fn write_all(self: Rc<Self>, buf: BufView) -> deno_core::AsyncResult<()> {
Box::pin(async move {
self
.file
diff --git a/ext/io/lib.rs b/ext/io/lib.rs
index a07d64ae3..5d183aa46 100644
--- a/ext/io/lib.rs
+++ b/ext/io/lib.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
-use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::unsync::spawn_blocking;
use deno_core::unsync::TaskQueue;
@@ -48,6 +47,7 @@ use winapi::um::processenv::GetStdHandle;
#[cfg(windows)]
use winapi::um::winbase;
+use deno_core::futures::TryFutureExt;
#[cfg(windows)]
use parking_lot::Condvar;
#[cfg(windows)]
@@ -348,13 +348,13 @@ where
RcRef::map(self, |r| &r.stream).borrow_mut()
}
- async fn write(self: Rc<Self>, data: &[u8]) -> Result<usize, AnyError> {
+ async fn write(self: Rc<Self>, data: &[u8]) -> Result<usize, io::Error> {
let mut stream = self.borrow_mut().await;
let nwritten = stream.write(data).await?;
Ok(nwritten)
}
- async fn shutdown(self: Rc<Self>) -> Result<(), AnyError> {
+ async fn shutdown(self: Rc<Self>) -> Result<(), io::Error> {
let mut stream = self.borrow_mut().await;
stream.shutdown().await?;
Ok(())
@@ -396,7 +396,7 @@ where
self.cancel_handle.cancel()
}
- async fn read(self: Rc<Self>, data: &mut [u8]) -> Result<usize, AnyError> {
+ async fn read(self: Rc<Self>, data: &mut [u8]) -> Result<usize, io::Error> {
let mut rd = self.borrow_mut().await;
let nread = rd.read(data).try_or_cancel(self.cancel_handle()).await?;
Ok(nread)
@@ -417,7 +417,7 @@ impl Resource for ChildStdinResource {
deno_core::impl_writable!();
fn shutdown(self: Rc<Self>) -> AsyncResult<()> {
- Box::pin(self.shutdown())
+ Box::pin(self.shutdown().map_err(|e| e.into()))
}
}
@@ -1010,7 +1010,7 @@ pub fn op_print(
state: &mut OpState,
#[string] msg: &str,
is_err: bool,
-) -> Result<(), AnyError> {
+) -> Result<(), deno_core::error::AnyError> {
let rid = if is_err { 2 } else { 1 };
FileResource::with_file(state, rid, move |file| {
Ok(file.write_all_sync(msg.as_bytes())?)