From 4828346f8b563aaf9188be17ca8ce90d925d3da4 Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Sun, 5 Mar 2023 00:20:18 -0600 Subject: [PATCH] Implement and use `Read` and `Write` traits for `AutoCloseFd` This lets us use any std::io functions that build on top of these, such as `write_all()` in place of our own `write_loop()`. --- fish-rust/src/fds.rs | 28 ++++++++++++++++++++++++++++ fish-rust/src/tests/fd_monitor.rs | 4 ++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/fish-rust/src/fds.rs b/fish-rust/src/fds.rs index ab1c7bdd6..efd266a24 100644 --- a/fish-rust/src/fds.rs +++ b/fish-rust/src/fds.rs @@ -1,5 +1,6 @@ use crate::ffi; use nix::unistd; +use std::io::{Read, Write}; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; /// A helper type for managing and automatically closing a file descriptor @@ -11,6 +12,33 @@ pub struct AutoCloseFd { fd_: RawFd, } +impl Read for AutoCloseFd { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + unsafe { + match libc::read(self.as_raw_fd(), buf.as_mut_ptr() as *mut _, buf.len()) { + -1 => Err(std::io::Error::from_raw_os_error(errno::errno().0)), + bytes => Ok(bytes as usize), + } + } + } +} + +impl Write for AutoCloseFd { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + unsafe { + match libc::write(self.as_raw_fd(), buf.as_ptr() as *const _, buf.len()) { + -1 => Err(std::io::Error::from_raw_os_error(errno::errno().0)), + bytes => Ok(bytes as usize), + } + } + } + + fn flush(&mut self) -> std::io::Result<()> { + // We don't buffer anything so this is a no-op. + Ok(()) + } +} + #[cxx::bridge] mod autoclose_fd_t { extern "Rust" { diff --git a/fish-rust/src/tests/fd_monitor.rs b/fish-rust/src/tests/fd_monitor.rs index 6593e2f9b..ff0e34086 100644 --- a/fish-rust/src/tests/fd_monitor.rs +++ b/fish-rust/src/tests/fd_monitor.rs @@ -1,9 +1,9 @@ +use std::io::Write; use std::os::fd::AsRawFd; use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Duration; -use crate::common::write_loop; use crate::fd_monitor::{FdMonitor, FdMonitorItem, FdMonitorItemId, ItemWakeReason}; use crate::fds::{make_autoclose_pipes, AutoCloseFd}; use crate::ffi_tests::add_test; @@ -96,7 +96,7 @@ fn callback(&self, fd: &mut AutoCloseFd, reason: ItemWakeReason) { fn write42(&self) { let buf = [0u8; 42]; let mut writer = self.writer.lock().expect("Mutex poisoned!"); - write_loop(&mut *writer, &buf).expect("Error writing 42 bytes to pipe!"); + writer.write_all(&buf).expect("Error writing 42 bytes to pipe!"); } }