diff --git a/usb_util/src/bindings.rs b/usb_util/src/bindings.rs index d24bf03e86..d64ebed254 100644 --- a/usb_util/src/bindings.rs +++ b/usb_util/src/bindings.rs @@ -4184,6 +4184,13 @@ extern "C" { dev_handle: *mut *mut libusb_device_handle, ) -> ::std::os::raw::c_int; } +extern "C" { + pub fn libusb_open_fd( + dev: *mut libusb_device, + fd: ::std::os::raw::c_int, + handle: *mut *mut libusb_device_handle, + ) -> ::std::os::raw::c_int; +} extern "C" { pub fn libusb_close(dev_handle: *mut libusb_device_handle); } diff --git a/usb_util/src/libusb_device.rs b/usb_util/src/libusb_device.rs index fa248df2ca..4ee80d2b06 100644 --- a/usb_util/src/libusb_device.rs +++ b/usb_util/src/libusb_device.rs @@ -9,6 +9,7 @@ use config_descriptor::ConfigDescriptor; use device_handle::DeviceHandle; use error::{Error, Result}; use libusb_context::LibUsbContextInner; +use std::os::unix::io::RawFd; use std::sync::Arc; use types::Speed; @@ -101,9 +102,19 @@ impl LibUsbDevice { /// Get device handle of this device. pub fn open(&self) -> Result { let mut handle: *mut bindings::libusb_device_handle = std::ptr::null_mut(); - // Safe because 'self.device' is valid and handle is on stack. + // Safe because 'self.device' is constructed from libusb device list and handle is on stack. try_libusb!(unsafe { bindings::libusb_open(self.device, &mut handle) }); // Safe because handle points to valid memory. Ok(unsafe { DeviceHandle::new(self._context.clone(), handle) }) } + + /// Get device handle of this device. Take an external fd. This function is only safe when fd + /// is an fd of this usb device. + pub unsafe fn open_fd(&self, fd: RawFd) -> Result { + let mut handle: *mut bindings::libusb_device_handle = std::ptr::null_mut(); + // Safe because 'self.device' is constructed from libusb device list and handle is on stack. + try_libusb!(unsafe { bindings::libusb_open_fd(self.device, fd, &mut handle) }); + // Safe because handle is successfully initialized with libusb_open_fd. + Ok(unsafe { DeviceHandle::new(self._context.clone(), handle) }) + } }