From 5f1e03911f0819ceacd366f76f961be407bec2b6 Mon Sep 17 00:00:00 2001 From: Abdullah Al-Banna Date: Sun, 30 Nov 2025 08:43:28 -0800 Subject: [PATCH] get and create a FileDescriptor from the fd (#43) --- idevice/src/services/afc/file.rs | 23 ++++++++++++++++++++--- idevice/src/services/afc/inner_file.rs | 11 ----------- idevice/src/services/afc/mod.rs | 6 +++--- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/idevice/src/services/afc/file.rs b/idevice/src/services/afc/file.rs index 855b78c..e31b3b4 100644 --- a/idevice/src/services/afc/file.rs +++ b/idevice/src/services/afc/file.rs @@ -1,6 +1,6 @@ // Jackson Coxson -use std::{io::SeekFrom, pin::Pin}; +use std::{io::SeekFrom, marker::PhantomPinned, pin::Pin}; use tokio::io::{AsyncRead, AsyncSeek, AsyncWrite}; @@ -13,8 +13,25 @@ pub struct FileDescriptor<'a> { } impl<'a> FileDescriptor<'a> { - pub(crate) fn new(inner: Pin>>) -> Self { - Self { inner } + /// create a new FileDescriptor from a raw fd + /// + /// # Safety + /// make sure the fd is an opened file, and that you got it from a previous + /// FileDescriptor via `as_raw_fd()` method + pub unsafe fn new(client: &'a mut super::AfcClient, fd: u64, path: String) -> Self { + Self { + inner: Box::pin(InnerFileDescriptor { + client, + fd, + path, + pending_fut: None, + _m: PhantomPinned, + }), + } + } + + pub fn as_raw_fd(&self) -> u64 { + self.inner.fd } } impl FileDescriptor<'_> { diff --git a/idevice/src/services/afc/inner_file.rs b/idevice/src/services/afc/inner_file.rs index bfd144e..270b140 100644 --- a/idevice/src/services/afc/inner_file.rs +++ b/idevice/src/services/afc/inner_file.rs @@ -44,17 +44,6 @@ pub(crate) struct InnerFileDescriptor<'a> { pub(crate) _m: std::marker::PhantomPinned, } -impl<'a> InnerFileDescriptor<'a> { - pub(crate) fn new(client: &'a mut super::AfcClient, fd: u64, path: String) -> Pin> { - Box::pin(Self { - client, - fd, - path, - pending_fut: None, - _m: std::marker::PhantomPinned, - }) - } -} impl InnerFileDescriptor<'_> { /// Generic helper to send an AFC packet and read the response pub async fn send_packet( diff --git a/idevice/src/services/afc/mod.rs b/idevice/src/services/afc/mod.rs index d767bb6..90927d1 100644 --- a/idevice/src/services/afc/mod.rs +++ b/idevice/src/services/afc/mod.rs @@ -410,9 +410,9 @@ impl AfcClient { return Err(IdeviceError::UnexpectedResponse); } let fd = u64::from_le_bytes(res.header_payload[..8].try_into().unwrap()); - Ok(FileDescriptor::new(inner_file::InnerFileDescriptor::new( - self, fd, path, - ))) + + // we know it's a valid fd + Ok(unsafe { FileDescriptor::new(self, fd, path) }) } /// Creates a hard or symbolic link