Skip to content

Commit

Permalink
device: Use OwnedFd type and bump MSRV to 1.66
Browse files Browse the repository at this point in the history
The first new commit 22a2365 on `next` switches to the `RawFd` type from
the `std::os::fd` module which is only available since Rust 1.66.  This
module also provides an `OwnedFd` type which already has a `close()`
call in the `Drop` implementation, and implements the desired `AsRawFd`
(and `AsFd` and `IntoRawFd`) traits.

Note that these types were already stabilized in Rust 1.63 under
`std::os::unix::io`, which is now merely a reexport of `std::os::fd`.

This also replaces the forgotten `.fd()` calls with `.as_raw_fd()` from
from commit 17c2871.
  • Loading branch information
MarijnS95 committed Sep 6, 2023
1 parent 384e7fb commit 1f0bee8
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 48 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2018"
license = "MIT"
readme = "README.md"
repository= "https://github.com/raymanfx/libv4l-rs"
rust-version = "1.66"

[dependencies]
bitflags = "1.2.1"
Expand Down
73 changes: 44 additions & 29 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::convert::TryFrom;
use std::path::Path;
use std::{
convert::TryFrom,
io, mem,
os::fd::{AsRawFd, RawFd},
os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd},
path::Path,
sync::Arc,
};

Expand Down Expand Up @@ -72,7 +72,7 @@ impl Device {
unsafe {
let mut v4l2_caps: v4l2_capability = mem::zeroed();
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_QUERYCAP,
&mut v4l2_caps as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -91,7 +91,7 @@ impl Device {
v4l2_ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
v4l2_ctrl.id |= V4L2_CTRL_FLAG_NEXT_COMPOUND;
match v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_QUERY_EXT_CTRL,
&mut v4l2_ctrl as *mut _ as *mut std::os::raw::c_void,
) {
Expand All @@ -114,7 +114,7 @@ impl Device {
..mem::zeroed()
};
let res = v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_QUERYMENU,
&mut v4l2_menu as *mut _ as *mut std::os::raw::c_void,
);
Expand Down Expand Up @@ -169,7 +169,7 @@ impl Device {
..mem::zeroed()
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_QUERY_EXT_CTRL,
&mut queryctrl as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -188,7 +188,7 @@ impl Device {
..mem::zeroed()
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_G_EXT_CTRLS,
&mut v4l2_ctrls as *mut _ as *mut std::os::raw::c_void,
)?;
Expand Down Expand Up @@ -311,7 +311,7 @@ impl Device {
};

v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_S_EXT_CTRLS,
&mut controls as *mut _ as *mut std::os::raw::c_void,
)
Expand All @@ -323,7 +323,7 @@ impl io::Read for Device {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
unsafe {
let ret = libc::read(
self.handle().as_raw_fd(),
self.as_raw_fd(),
buf.as_mut_ptr() as *mut std::os::raw::c_void,
buf.len(),
);
Expand All @@ -339,7 +339,7 @@ impl io::Write for Device {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
unsafe {
let ret = libc::write(
self.handle().as_raw_fd(),
self.as_raw_fd(),
buf.as_ptr() as *const std::os::raw::c_void,
buf.len(),
);
Expand All @@ -358,17 +358,29 @@ impl io::Write for Device {
}
}

impl AsFd for Device {
fn as_fd(&self) -> BorrowedFd<'_> {
self.handle.as_fd()
}
}

impl AsRawFd for Device {
fn as_raw_fd(&self) -> RawFd {
self.handle.as_raw_fd()
}
}

/// Device handle for low-level access.
///
/// Acquiring a handle facilitates (possibly mutating) interactions with the device.
#[derive(Debug, Clone)]
pub struct Handle(RawFd);
#[derive(Debug)]
pub struct Handle(OwnedFd);

impl Handle {
/// Wraps an existing file descriptor
///
/// The caller must ensure that `fd` is a valid, open file descriptor for a V4L device.
pub unsafe fn new(fd: RawFd) -> Self {
pub fn new(fd: OwnedFd) -> Self {
Self(fd)
}

Expand All @@ -385,7 +397,7 @@ impl Handle {
return Err(io::Error::last_os_error());
}

Ok(Handle(fd))
Ok(Handle(unsafe { OwnedFd::from_raw_fd(fd) }))
}

/// Polls the file descriptor for I/O events
Expand All @@ -400,35 +412,38 @@ impl Handle {
pub fn poll(&self, events: i16, timeout: i32) -> io::Result<i32> {
match unsafe {
libc::poll(
[libc::pollfd {
fd: self.0,
&mut libc::pollfd {
fd: self.as_raw_fd(),
events,
revents: 0,
}]
.as_mut_ptr(),
},
1,
timeout,
)
} {
-1 => Err(io::Error::last_os_error()),
ret => {
// A return value of zero means that we timed out. A positive value signifies the
// number of fds with non-zero revents fields (aka I/O activity).
assert!(ret == 0 || ret == 1);
Ok(ret)
}
// A return value of zero means that we timed out. A positive value signifies the
// number of fds with non-zero revents fields (aka I/O activity).
ret @ 0..=1 => Ok(ret),
ret => panic!("Invalid return value {}", ret),
}
}
}

impl Drop for Handle {
fn drop(&mut self) {
let _ = v4l2::close(self.0);
impl AsFd for Handle {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}

impl AsRawFd for Handle {
fn as_raw_fd(&self) -> RawFd {
self.0
self.0.as_raw_fd()
}
}

impl IntoRawFd for Handle {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}
19 changes: 10 additions & 9 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::{
marker::PhantomData,
mem,
ops::{Index, IndexMut},
os::fd::AsRawFd,
ptr, slice,
sync::Arc,
};
Expand Down Expand Up @@ -65,7 +66,7 @@ impl<B, S> Queue<B, S> {

unsafe {
v4l2::ioctl(
self.handle.fd(),
self.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_REQBUFS,
&mut v4l2_reqbufs as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -88,7 +89,7 @@ impl<B, S> Queue<B, S> {

unsafe {
v4l2::ioctl(
self.handle.fd(),
self.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_QUERYBUF,
&mut buf as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -101,7 +102,7 @@ impl<B, S> Queue<B, S> {
fn streamon(&mut self) -> io::Result<()> {
unsafe {
v4l2::ioctl(
self.handle.fd(),
self.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_STREAMON,
&mut self.buf_type as *mut _ as *mut std::os::raw::c_void,
)
Expand All @@ -112,7 +113,7 @@ impl<B, S> Queue<B, S> {
fn streamoff(&mut self) -> io::Result<()> {
unsafe {
v4l2::ioctl(
self.handle.fd(),
self.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_STREAMOFF,
&mut self.buf_type as *mut _ as *mut std::os::raw::c_void,
)
Expand All @@ -125,7 +126,7 @@ impl<B, S> Queue<B, S> {

unsafe {
v4l2::ioctl(
self.handle.fd(),
self.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_QBUF,
buf as *mut _ as *mut std::os::raw::c_void,
)
Expand All @@ -138,7 +139,7 @@ impl<B, S> Queue<B, S> {

unsafe {
v4l2::ioctl(
self.handle.fd(),
self.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_DQBUF,
buf as *mut _ as *mut std::os::raw::c_void,
)
Expand Down Expand Up @@ -244,7 +245,7 @@ impl Queue<Mmap<'_>, queue::Idle> {

let mapping = unsafe {
v4l2::ioctl(
queue.handle.fd(),
queue.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_QUERYBUF,
&mut v4l2_buf as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -254,7 +255,7 @@ impl Queue<Mmap<'_>, queue::Idle> {
v4l2_buf.length as usize,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_SHARED,
queue.handle.fd(),
queue.handle.as_raw_fd(),
v4l2_buf.m.offset as libc::off_t,
)?;

Expand Down Expand Up @@ -322,7 +323,7 @@ impl Queue<UserPtr, queue::Idle> {
};
unsafe {
v4l2::ioctl(
queue.handle.fd(),
queue.handle.as_raw_fd(),
v4l2::vidioc::VIDIOC_G_FMT,
&mut v4l2_fmt as *mut _ as *mut std::os::raw::c_void,
)?;
Expand Down
4 changes: 2 additions & 2 deletions src/video/capture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Capture for Device {
..mem::zeroed()
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_G_PARM,
&mut v4l2_params as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -63,7 +63,7 @@ impl Capture for Device {
},
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_S_PARM,
&mut v4l2_params as *mut _ as *mut std::os::raw::c_void,
)?;
Expand Down
12 changes: 6 additions & 6 deletions src/video/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl traits::Video for Device {
loop {
let ret = unsafe {
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_ENUM_FRAMEINTERVALS,
&mut v4l2_struct as *mut _ as *mut std::os::raw::c_void,
)
Expand Down Expand Up @@ -65,7 +65,7 @@ impl traits::Video for Device {
loop {
let ret = unsafe {
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_ENUM_FRAMESIZES,
&mut v4l2_struct as *mut _ as *mut std::os::raw::c_void,
)
Expand Down Expand Up @@ -99,7 +99,7 @@ impl traits::Video for Device {

unsafe {
ret = v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_ENUM_FMT,
&mut v4l2_fmt as *mut _ as *mut std::os::raw::c_void,
);
Expand All @@ -121,7 +121,7 @@ impl traits::Video for Device {

unsafe {
ret = v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_ENUM_FMT,
&mut v4l2_fmt as *mut _ as *mut std::os::raw::c_void,
);
Expand All @@ -138,7 +138,7 @@ impl traits::Video for Device {
..mem::zeroed()
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_G_FMT,
&mut v4l2_fmt as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -154,7 +154,7 @@ impl traits::Video for Device {
fmt: v4l2_format__bindgen_ty_1 { pix: (*fmt).into() },
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_S_FMT,
&mut v4l2_fmt as *mut _ as *mut std::os::raw::c_void,
)?;
Expand Down
4 changes: 2 additions & 2 deletions src/video/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Output for Device {
..mem::zeroed()
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_G_PARM,
&mut v4l2_params as *mut _ as *mut std::os::raw::c_void,
)?;
Expand All @@ -63,7 +63,7 @@ impl Output for Device {
},
};
v4l2::ioctl(
self.handle().as_raw_fd(),
self.as_raw_fd(),
v4l2::vidioc::VIDIOC_S_PARM,
&mut v4l2_params as *mut _ as *mut std::os::raw::c_void,
)?;
Expand Down

0 comments on commit 1f0bee8

Please sign in to comment.