nix icon indicating copy to clipboard operation
nix copied to clipboard

Can't use ioctl with media_device_info, result is always ENOTTY

Open patrickelectric opened this issue 4 years ago • 3 comments
trafficstars

I have lost some time already trying to figure out how to use ioctl with nix, but until now I couldn't get it work. Is there any documentation with examples that could help ? From what I read this could is correct and should work.

use nix;
use std::os::unix::io::AsRawFd;
// https://www.kernel.org/doc/html/latest/userspace-api/media/mediactl/media-ioc-device-info.html#description
#[repr(C)]
pub struct MediaDeviceInfo {
    driver_name: [char; 16],      // ASCII
    device_name: [char; 32],      // UTF-8
    serial_number: [char; 40],    // ASCII
    bus_info: [char; 32],         // ASCII
    media_version: u32,           // Media API version, formatted with the KERNEL_VERSION() macro.
    hardware_device_version: u32, // Hardware device revision in a driver-specific format.
    driver_version: u32, //	Media device driver version, formatted with the KERNEL_VERSION() macro. Together with the driver field this identifies a particular driver.
    reserved: [u32; 31], // Reserved for future extensions. Drivers and applications must set this array to zero.
}
// https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/media.h#L372
nix::ioctl_readwrite!(media_ioc_device_info, b'|', 0x00, MediaDeviceInfo);

fn main() {
    let video_device = std::fs::File::open("/dev/video0").unwrap();
    let video_device_pointer = video_device.as_raw_fd();
    let mut media_device_info: MediaDeviceInfo = unsafe { std::mem::zeroed() };

    let result = unsafe { media_ioc_device_info(video_device_pointer, &mut media_device_info) };

    println!("device_name: {:#?}", media_device_info.device_name);
    println!("result: {:#?}", result);
}

patrickelectric avatar Feb 09 '21 20:02 patrickelectric

Have you looked at the tests in Nix's test/sys/test_ioctl.rs directory?

asomers avatar Feb 13 '21 03:02 asomers

ENOTTY usually indicates that you either got the ioctl number wrong, or you're trying to use it on the wrong kind of file descriptor. If you run your program with strace, it will attempt to decode the ioctl number. If you see MEDIA_IOC_DEVICE_INFO in strace's output then you know you defined it correctly.

asomers avatar Feb 13 '21 03:02 asomers

I don't know if is related but when implement usbapi crate I noticed that I could now use standard macros in nix and implemented ioctl_readwrite_ptr and ioctl_read_ptr. Full code here https://gitlab.com/mike7b4/usbapi-rs/-/blob/master/src/os/linux/usbfs.rs

snippets:

#[macro_export]
macro_rules! ioctl_read_ptr {
    ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
        $(#[$attr])*
        /// # Safety
        /// ioctl call need unsafe calls to C
        pub unsafe fn $name(fd: nix::libc::c_int,
                            data: *const $ty)
                            -> nix::Result<nix::libc::c_int> {
            convert_ioctl_res!(nix::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as nix::sys::ioctl::ioctl_num_type, data))
        }
    )
}

#[macro_export]
macro_rules! ioctl_readwrite_ptr {
    ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
        $(#[$attr])*
            /// # Safety
            /// ioctl call need unsafe calls to C
            pub unsafe fn $name(fd: nix::libc::c_int,
                                data: *mut $ty)
                                -> nix::Result<nix::libc::c_int> {
                                    convert_ioctl_res!(nix::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as nix::sys::ioctl::ioctl_num_type, data))
            }
    )
}

7b4software avatar Mar 30 '21 19:03 7b4software

You're opening the wrong device. Try /dev/media0.

As a side note, you shouldbe using std::ffi::c_char rather than char. The latter is a Unicode code point.

@patrickelectric did you continue working on the code? Media interface would be useful to have.

dcz-purism avatar Apr 02 '23 11:04 dcz-purism

I'm going to close the issue, on the assumption that the OP figured his problem out.

asomers avatar Apr 02 '23 13:04 asomers