From 3ac4e47654935985d2010b3816c807a9585b3785 Mon Sep 17 00:00:00 2001 From: intellild Date: Tue, 12 May 2026 11:46:29 +0000 Subject: [PATCH 1/2] update rustix dependency --- Cargo.toml | 2 +- src/fs/file_io_ext.rs | 11 ++++++- src/io/is_read_write.rs | 64 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4df0e13..c91d9fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ ssh2 = { version = "0.9.1", optional = true } #socket2 = { version = "0.4.0", optional = true } [target.'cfg(not(windows))'.dependencies] -rustix = { version = "0.38.0", features = ["fs", "net"] } +rustix = { version = "1.1.4", features = ["fs", "net"] } [target.'cfg(windows)'.dependencies] cap-std = "3.0.0" diff --git a/src/fs/file_io_ext.rs b/src/fs/file_io_ext.rs index 36f4622..d37b345 100644 --- a/src/fs/file_io_ext.rs +++ b/src/fs/file_io_ext.rs @@ -23,6 +23,15 @@ use rustix::fs::{fallocate, FallocateFlags}; #[cfg(not(any(windows, target_os = "ios", target_os = "macos", target_os = "redox")))] use rustix::io::{preadv, pwritev}; use std::io::{self, IoSlice, IoSliceMut, Seek, SeekFrom}; +#[cfg(not(any( + windows, + target_os = "ios", + target_os = "macos", + target_os = "netbsd", + target_os = "openbsd", + target_os = "redox", +)))] +use std::num::NonZeroU64; use std::slice; #[cfg(windows)] use {cap_fs_ext::Reopen, std::fs, std::os::windows::fs::FileExt}; @@ -420,7 +429,7 @@ impl FileIoExt for T { Advice::Random => rustix::fs::Advice::Random, Advice::DontNeed => rustix::fs::Advice::DontNeed, }; - Ok(fadvise(self, offset, len, advice)?) + Ok(fadvise(self, offset, NonZeroU64::new(len), advice)?) } #[cfg(any(target_os = "ios", target_os = "macos"))] diff --git a/src/io/is_read_write.rs b/src/io/is_read_write.rs index 5cbc258..efe5fc4 100644 --- a/src/io/is_read_write.rs +++ b/src/io/is_read_write.rs @@ -1,6 +1,13 @@ use std::io; #[cfg(not(windows))] -use {io_lifetimes::AsFilelike, rustix::io::is_read_write}; +use { + io_lifetimes::AsFilelike, + rustix::{ + fs::{fcntl_getfl, OFlags}, + io::Errno, + net::{recv, send, RecvFlags, SendFlags}, + }, +}; #[cfg(windows)] use { std::{ @@ -22,7 +29,60 @@ pub trait IsReadWrite { impl IsReadWrite for T { #[inline] fn is_read_write(&self) -> io::Result<(bool, bool)> { - Ok(is_read_write(self)?) + is_read_write(self) + } +} + +#[cfg(not(windows))] +#[inline] +fn is_read_write(fd: Fd) -> io::Result<(bool, bool)> { + let (mut read, mut write) = is_file_read_write(&fd)?; + let mut not_socket = false; + + if read { + let mut buf = [0_u8; 1]; + match recv(&fd, &mut buf, RecvFlags::PEEK | RecvFlags::DONTWAIT) { + Ok((0, _)) => read = false, + Ok(_) => (), + Err(err) if err == Errno::AGAIN || err == Errno::WOULDBLOCK => (), + Err(Errno::NOTSOCK) => not_socket = true, + Err(err) => return Err(err.into()), + } + } + + if write && !not_socket { + match send(&fd, &[], SendFlags::DONTWAIT) { + Ok(_) => (), + Err(err) + if err == Errno::AGAIN || err == Errno::WOULDBLOCK || err == Errno::NOTSOCK => {} + Err(Errno::PIPE) => write = false, + Err(err) => return Err(err.into()), + } + } + + Ok((read, write)) +} + +#[cfg(not(windows))] +#[inline] +fn is_file_read_write(fd: Fd) -> io::Result<(bool, bool)> { + let mode = fcntl_getfl(fd)?; + + #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "linux" + ))] + if mode.contains(OFlags::PATH) { + return Ok((false, false)); + } + + match mode & OFlags::RWMODE { + OFlags::RDONLY => Ok((true, false)), + OFlags::RDWR => Ok((true, true)), + OFlags::WRONLY => Ok((false, true)), + _ => unreachable!(), } } From ec07f4951fe8e8b2fd5889977e8a53f94a42a5da Mon Sep 17 00:00:00 2001 From: intellild Date: Fri, 15 May 2026 02:11:26 +0000 Subject: [PATCH 2/2] Fix Android rustix append fallback --- src/fs/file_io_ext.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fs/file_io_ext.rs b/src/fs/file_io_ext.rs index d37b345..a7917ac 100644 --- a/src/fs/file_io_ext.rs +++ b/src/fs/file_io_ext.rs @@ -538,7 +538,7 @@ impl FileIoExt for T { use rustix::io::write; // On Linux, use `pwritev2`. - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(target_os = "linux")] { use rustix::io::{pwritev2, Errno, ReadWriteFlags}; @@ -571,7 +571,7 @@ impl FileIoExt for T { use rustix::io::writev; // On Linux, use `pwritev2`. - #[cfg(any(target_os = "android", target_os = "linux"))] + #[cfg(target_os = "linux")] { use rustix::io::{pwritev2, Errno, ReadWriteFlags};