use std::ffi::CString;
use std::os::unix::ffi::OsStrExt;
use std::{io, path::Path};
use crate::v4l2::vidioc;
#[cfg(feature = "v4l-sys")]
mod detail {
use crate::v4l2::vidioc;
use crate::v4l_sys::*;
use std::convert::TryInto;
pub unsafe fn open(path: *const std::os::raw::c_char, flags: i32) -> std::os::raw::c_int {
v4l2_open(path, flags)
}
pub unsafe fn close(fd: std::os::raw::c_int) -> std::os::raw::c_int {
v4l2_close(fd)
}
pub unsafe fn ioctl(
fd: std::os::raw::c_int,
request: vidioc::_IOC_TYPE,
argp: *mut std::os::raw::c_void,
) -> std::os::raw::c_int {
#![allow(clippy::useless_conversion)]
v4l2_ioctl(
fd,
request.try_into().expect("vidioc::_IOC_TYPE -> u64 failed"),
argp,
)
}
pub unsafe fn mmap(
start: *mut std::os::raw::c_void,
length: usize,
prot: std::os::raw::c_int,
flags: std::os::raw::c_int,
fd: std::os::raw::c_int,
offset: libc::off_t,
) -> *mut std::os::raw::c_void {
#![allow(clippy::useless_conversion)]
v4l2_mmap(
start,
length.try_into().expect("usize -> c size_t failed"),
prot,
flags,
fd,
offset as i64,
)
}
pub unsafe fn munmap(start: *mut std::os::raw::c_void, length: usize) -> std::os::raw::c_int {
v4l2_munmap(start, length.try_into().expect("usize -> c size_t failed"))
}
}
#[cfg(feature = "v4l2-sys")]
mod detail {
use crate::v4l2::vidioc;
pub unsafe fn open(path: *const std::os::raw::c_char, flags: i32) -> std::os::raw::c_int {
libc::open(path, flags)
}
pub unsafe fn close(fd: std::os::raw::c_int) -> std::os::raw::c_int {
libc::close(fd)
}
pub unsafe fn ioctl(
fd: std::os::raw::c_int,
request: vidioc::_IOC_TYPE,
argp: *mut std::os::raw::c_void,
) -> std::os::raw::c_int {
libc::syscall(libc::SYS_ioctl, fd, request, argp) as std::os::raw::c_int
}
pub unsafe fn mmap(
start: *mut std::os::raw::c_void,
length: usize,
prot: std::os::raw::c_int,
flags: std::os::raw::c_int,
fd: std::os::raw::c_int,
offset: libc::off_t,
) -> *mut std::os::raw::c_void {
libc::mmap(start, length, prot, flags, fd, offset)
}
pub unsafe fn munmap(start: *mut std::os::raw::c_void, length: usize) -> std::os::raw::c_int {
libc::munmap(start, length)
}
}
pub fn open<P: AsRef<Path>>(path: P, flags: i32) -> io::Result<std::os::raw::c_int> {
let fd: std::os::raw::c_int;
let c_path = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
unsafe {
fd = detail::open(c_path.as_ptr(), flags);
}
if fd == -1 {
Err(io::Error::last_os_error())
} else {
Ok(fd)
}
}
pub fn close(fd: std::os::raw::c_int) -> io::Result<()> {
let ret: std::os::raw::c_int;
unsafe {
ret = detail::close(fd);
}
if ret == -1 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}
pub unsafe fn ioctl(
fd: std::os::raw::c_int,
request: vidioc::_IOC_TYPE,
argp: *mut std::os::raw::c_void,
) -> io::Result<()> {
let ret = detail::ioctl(fd, request, argp);
if ret == -1 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}
pub unsafe fn mmap(
start: *mut std::os::raw::c_void,
length: usize,
prot: std::os::raw::c_int,
flags: std::os::raw::c_int,
fd: std::os::raw::c_int,
offset: libc::off_t,
) -> io::Result<*mut std::os::raw::c_void> {
let ret = detail::mmap(start, length, prot, flags, fd, offset);
if ret as usize == std::usize::MAX {
Err(io::Error::last_os_error())
} else {
Ok(ret)
}
}
pub unsafe fn munmap(start: *mut std::os::raw::c_void, length: usize) -> io::Result<()> {
let ret = detail::munmap(start, length);
if ret == -1 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}