mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 14:36:16 +01:00
Implement creating an Idevice with a file descriptor
This commit is contained in:
@@ -32,6 +32,7 @@ using IdevicePtr = std::unique_ptr<IdeviceHandle, FnDeleter<IdeviceHandle, idevi
|
|||||||
class Idevice {
|
class Idevice {
|
||||||
public:
|
public:
|
||||||
static Result<Idevice, FfiError> create(IdeviceSocketHandle* socket, const std::string& label);
|
static Result<Idevice, FfiError> create(IdeviceSocketHandle* socket, const std::string& label);
|
||||||
|
static Result<Idevice, FfiError> from_fd(int fd, const std::string& label);
|
||||||
|
|
||||||
static Result<Idevice, FfiError>
|
static Result<Idevice, FfiError>
|
||||||
create_tcp(const sockaddr* addr, socklen_t addr_len, const std::string& label);
|
create_tcp(const sockaddr* addr, socklen_t addr_len, const std::string& label);
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ Result<Idevice, FfiError> Idevice::create(IdeviceSocketHandle* socket, const std
|
|||||||
return Ok(Idevice(h));
|
return Ok(Idevice(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result<Idevice, FfiError> Idevice::from_fd(int fd, const std::string& label) {
|
||||||
|
IdeviceHandle* h = nullptr;
|
||||||
|
FfiError e(idevice_from_fd(fd, label.c_str(), &h));
|
||||||
|
if (e) {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
return Ok(Idevice(h));
|
||||||
|
}
|
||||||
|
|
||||||
Result<Idevice, FfiError>
|
Result<Idevice, FfiError>
|
||||||
Idevice::create_tcp(const sockaddr* addr, socklen_t addr_len, const std::string& label) {
|
Idevice::create_tcp(const sockaddr* addr, socklen_t addr_len, const std::string& label) {
|
||||||
IdeviceHandle* h = nullptr;
|
IdeviceHandle* h = nullptr;
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ use idevice::{Idevice, IdeviceSocket, ReadWrite};
|
|||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::{
|
use std::{
|
||||||
ffi::{CStr, CString, c_char},
|
ffi::{CStr, CString, c_char},
|
||||||
|
os::fd::FromRawFd,
|
||||||
ptr::null_mut,
|
ptr::null_mut,
|
||||||
};
|
};
|
||||||
use tokio::runtime::{self, Runtime};
|
use tokio::runtime::{self, Runtime};
|
||||||
@@ -122,6 +123,46 @@ pub unsafe extern "C" fn idevice_new(
|
|||||||
null_mut()
|
null_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an Idevice object from a socket file descriptor
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// The socket FD must be valid.
|
||||||
|
/// The pointers must be valid and non-null.
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub unsafe extern "C" fn idevice_from_fd(
|
||||||
|
fd: i32,
|
||||||
|
label: *const c_char,
|
||||||
|
idevice: *mut *mut IdeviceHandle,
|
||||||
|
) -> *mut IdeviceFfiError {
|
||||||
|
if label.is_null() || idevice.is_null() || fd == 0 {
|
||||||
|
return ffi_err!(IdeviceError::FfiInvalidArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get socket ownership
|
||||||
|
let fd = unsafe { libc::dup(fd) };
|
||||||
|
let socket = unsafe { std::net::TcpStream::from_raw_fd(fd) };
|
||||||
|
if let Err(e) = socket.set_nonblocking(true) {
|
||||||
|
return ffi_err!(e);
|
||||||
|
}
|
||||||
|
let socket = match RUNTIME.block_on(async move { tokio::net::TcpStream::from_std(socket) }) {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(e) => return ffi_err!(e),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert C string to Rust string
|
||||||
|
let c_str = match unsafe { CStr::from_ptr(label).to_str() } {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(_) => return ffi_err!(IdeviceError::FfiInvalidString),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create new Idevice instance
|
||||||
|
let dev = Idevice::new(Box::new(socket), c_str);
|
||||||
|
let boxed = Box::new(IdeviceHandle(dev));
|
||||||
|
unsafe { *idevice = Box::into_raw(boxed) };
|
||||||
|
|
||||||
|
null_mut()
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new Idevice connection
|
/// Creates a new Idevice connection
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|||||||
Reference in New Issue
Block a user