From bed1c7f07c6041ae4694e2e854f249114089cd24 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 6 Nov 2023 17:21:54 -0800 Subject: [PATCH] WIP Use Rustix Updates `drm-ffi` to use Rustix. Not *too* hard to update by defining macros like Nix had, though it's probably not ideal. The generic ioctl API for Rustix seems a bit awkward when dealing with APIs like drm that involve very large numbers of ioctls. Instead of generating functions with a macro like this, it's possible to define types aliases with `ReadWriteOpcode`, etc. But it's still necessary to deal with `Getter`/`Setter`, etc... --- drm-ffi/Cargo.toml | 6 +-- drm-ffi/src/gem.rs | 10 ++--- drm-ffi/src/ioctl.rs | 67 +++++++++++++++++++++++++++++- drm-ffi/src/lib.rs | 35 ++++++++-------- drm-ffi/src/mode.rs | 92 +++++++++++++++++++++--------------------- drm-ffi/src/syncobj.rs | 24 +++++------ 6 files changed, 146 insertions(+), 88 deletions(-) diff --git a/drm-ffi/Cargo.toml b/drm-ffi/Cargo.toml index d57c2378..ea8f75ab 100644 --- a/drm-ffi/Cargo.toml +++ b/drm-ffi/Cargo.toml @@ -10,11 +10,7 @@ edition = "2021" [dependencies] drm-sys = { path = "drm-sys", version = "0.5.0" } - -[dependencies.nix] -version = "0.27" -default-features = false -features = ["ioctl"] +rustix = { version = "0.38.21" } [features] use_bindgen = ["drm-sys/use_bindgen"] diff --git a/drm-ffi/src/gem.rs b/drm-ffi/src/gem.rs index 4d330d6d..1cc66421 100644 --- a/drm-ffi/src/gem.rs +++ b/drm-ffi/src/gem.rs @@ -7,7 +7,7 @@ use drm_sys::*; use std::{ io, - os::unix::io::{AsRawFd, BorrowedFd}, + os::unix::io::{AsFd, AsRawFd, BorrowedFd}, }; /// Open a GEM object given it's 32-bit name, returning the handle. @@ -18,7 +18,7 @@ pub fn open(fd: BorrowedFd<'_>, name: u32) -> io::Result { }; unsafe { - ioctl::gem::open(fd.as_raw_fd(), &mut gem)?; + ioctl::gem::open(fd.as_fd(), &mut gem)?; } Ok(gem) @@ -32,7 +32,7 @@ pub fn close(fd: BorrowedFd<'_>, handle: u32) -> io::Result { }; unsafe { - ioctl::gem::close(fd.as_raw_fd(), &gem)?; + ioctl::gem::close(fd.as_fd(), &gem)?; } Ok(gem) @@ -47,7 +47,7 @@ pub fn handle_to_fd(fd: BorrowedFd<'_>, handle: u32, flags: u32) -> io::Result, primefd: BorrowedFd<'_>) -> io::Result(&'a mut T, PhantomData); + +unsafe impl<'a, Opcode: CompileTimeOpcode, T> Ioctl for GetterSetter<'a, Opcode, T> { + type Output = std::ffi::c_int; + const IS_MUTATING: bool = true; + const OPCODE: rustix::ioctl::Opcode = Opcode::OPCODE; + + fn as_ptr(&mut self) -> *mut c_void { + self.0 as *mut T as *mut c_void + } + + unsafe fn output_from_ptr( + output: IoctlOutput, + _ptr: *mut c_void, + ) -> rustix::io::Result { + Ok(output) + } +} + +macro_rules! ioctl_readwrite { + ($name:ident, $ioty:expr, $nr:expr, $ty:ty) => { + pub unsafe fn $name(fd: std::os::fd::BorrowedFd, data: &mut $ty) -> std::io::Result<()> { + type Opcode = rustix::ioctl::ReadWriteOpcode<$ioty, $nr, $ty>; + rustix::ioctl::ioctl( + fd, + crate::ioctl::GetterSetter::(data, std::marker::PhantomData), + )?; + Ok(()) + } + }; +} + +macro_rules! ioctl_read { + ($name:ident, $ioty:expr, $nr:expr, $ty:ty) => { + pub unsafe fn $name(fd: std::os::fd::BorrowedFd, data: &mut $ty) -> std::io::Result<()> { + type Opcode = rustix::ioctl::ReadOpcode<$ioty, $nr, $ty>; + *data = rustix::ioctl::ioctl(fd, rustix::ioctl::Getter::::new())?; + Ok(()) + } + }; +} + +macro_rules! ioctl_write_ptr { + ($name:ident, $ioty:expr, $nr:expr, $ty:ty) => { + pub unsafe fn $name(fd: std::os::fd::BorrowedFd, data: &$ty) -> std::io::Result<()> { + type Opcode = rustix::ioctl::WriteOpcode<$ioty, $nr, $ty>; + rustix::ioctl::ioctl(fd, rustix::ioctl::Setter::::new(*data))?; + Ok(()) + } + }; +} + +macro_rules! ioctl_none { + ($name:ident, $ioty:expr, $nr:expr) => { + pub unsafe fn $name(fd: std::os::fd::BorrowedFd) -> std::io::Result<()> { + type Opcode = rustix::ioctl::NoneOpcode<$ioty, $nr, ()>; + rustix::ioctl::ioctl(fd, rustix::ioctl::NoArg::::new())?; + Ok(()) + } + }; +} + /// Gets the bus ID of the device /// /// # Locks DRM mutex: Yes @@ -95,7 +160,7 @@ ioctl_readwrite!(wait_vblank, DRM_IOCTL_BASE, 0x3a, drm_wait_vblank); pub(crate) mod mode { use drm_sys::*; - use nix::libc::c_uint; + use std::ffi::c_uint; /// Modesetting resources ioctl_readwrite!(get_resources, DRM_IOCTL_BASE, 0xA0, drm_mode_card_res); diff --git a/drm-ffi/src/lib.rs b/drm-ffi/src/lib.rs index c63c9558..9c9a7dc4 100644 --- a/drm-ffi/src/lib.rs +++ b/drm-ffi/src/lib.rs @@ -7,9 +7,6 @@ pub use drm_sys::{self, *}; -#[macro_use] -extern crate nix; - #[macro_use] pub(crate) mod utils; @@ -18,10 +15,10 @@ mod ioctl; pub mod mode; pub mod syncobj; -use nix::libc::{c_int, c_ulong}; use std::{ + ffi::{c_int, c_ulong}, io, - os::unix::io::{AsRawFd, BorrowedFd}, + os::unix::io::{AsFd, BorrowedFd}, }; /// @@ -33,7 +30,7 @@ pub mod auth { use std::{ io, - os::unix::io::{AsRawFd, BorrowedFd}, + os::unix::io::{AsFd, BorrowedFd}, }; /// Get the 'Magic Authentication Token' for this file descriptor. @@ -41,7 +38,7 @@ pub mod auth { let mut auth = drm_auth::default(); unsafe { - ioctl::get_token(fd.as_raw_fd(), &mut auth)?; + ioctl::get_token(fd.as_fd(), &mut auth)?; } Ok(auth) @@ -52,7 +49,7 @@ pub mod auth { let token = drm_auth { magic: auth }; unsafe { - ioctl::auth_token(fd.as_raw_fd(), &token)?; + ioctl::auth_token(fd.as_fd(), &token)?; } Ok(token) @@ -61,7 +58,7 @@ pub mod auth { /// Acquire the 'Master DRM Lock' for this file descriptor. pub fn acquire_master(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { - ioctl::acquire_master(fd.as_raw_fd())?; + ioctl::acquire_master(fd.as_fd())?; } Ok(()) @@ -70,7 +67,7 @@ pub mod auth { /// Release the 'Master DRM Lock' for this file descriptor. pub fn release_master(fd: BorrowedFd<'_>) -> io::Result<()> { unsafe { - ioctl::release_master(fd.as_raw_fd())?; + ioctl::release_master(fd.as_fd())?; } Ok(()) @@ -81,7 +78,7 @@ pub mod auth { pub fn get_bus_id(fd: BorrowedFd<'_>, mut buf: Option<&mut Vec>) -> io::Result { let mut sizes = drm_unique::default(); unsafe { - ioctl::get_bus_id(fd.as_raw_fd(), &mut sizes)?; + ioctl::get_bus_id(fd.as_fd(), &mut sizes)?; } if buf.is_none() { @@ -96,7 +93,7 @@ pub fn get_bus_id(fd: BorrowedFd<'_>, mut buf: Option<&mut Vec>) -> io::Resu }; unsafe { - ioctl::get_bus_id(fd.as_raw_fd(), &mut busid)?; + ioctl::get_bus_id(fd.as_fd(), &mut busid)?; } map_set!(buf, busid.unique_len as usize); @@ -119,7 +116,7 @@ pub fn get_interrupt_from_bus_id( }; unsafe { - ioctl::get_irq_from_bus_id(fd.as_raw_fd(), &mut irq)?; + ioctl::get_irq_from_bus_id(fd.as_fd(), &mut irq)?; } Ok(irq) @@ -133,7 +130,7 @@ pub fn get_client(fd: BorrowedFd<'_>, idx: c_int) -> io::Result { }; unsafe { - ioctl::get_client(fd.as_raw_fd(), &mut client)?; + ioctl::get_client(fd.as_fd(), &mut client)?; } Ok(client) @@ -147,7 +144,7 @@ pub fn get_capability(fd: BorrowedFd<'_>, cty: u64) -> io::Result { }; unsafe { - ioctl::get_cap(fd.as_raw_fd(), &mut cap)?; + ioctl::get_cap(fd.as_fd(), &mut cap)?; } Ok(cap) @@ -161,7 +158,7 @@ pub fn set_capability(fd: BorrowedFd<'_>, cty: u64, val: bool) -> io::Result io::Result { let mut sizes = drm_version::default(); unsafe { - ioctl::get_version(fd.as_raw_fd(), &mut sizes)?; + ioctl::get_version(fd.as_fd(), &mut sizes)?; } map_reserve!(name_buf, sizes.name_len as usize); @@ -194,7 +191,7 @@ pub fn get_version( }; unsafe { - ioctl::get_version(fd.as_raw_fd(), &mut version)?; + ioctl::get_version(fd.as_fd(), &mut version)?; } map_set!(name_buf, version.name_len as usize); @@ -223,7 +220,7 @@ pub fn wait_vblank( }; unsafe { - ioctl::wait_vblank(fd.as_raw_fd(), &mut wait_vblank)?; + ioctl::wait_vblank(fd.as_fd(), &mut wait_vblank)?; }; Ok(unsafe { wait_vblank.reply }) diff --git a/drm-ffi/src/mode.rs b/drm-ffi/src/mode.rs index 49c2d5a2..e4af220d 100644 --- a/drm-ffi/src/mode.rs +++ b/drm-ffi/src/mode.rs @@ -9,7 +9,7 @@ use drm_sys::*; use std::{ io, - os::unix::io::{AsRawFd, BorrowedFd}, + os::unix::io::{AsFd, BorrowedFd}, }; /// Enumerate most card resources. @@ -22,7 +22,7 @@ pub fn get_resources( ) -> io::Result { let mut sizes = drm_mode_card_res::default(); unsafe { - ioctl::mode::get_resources(fd.as_raw_fd(), &mut sizes)?; + ioctl::mode::get_resources(fd.as_fd(), &mut sizes)?; } map_reserve!(fbs, sizes.count_fbs as usize); @@ -43,7 +43,7 @@ pub fn get_resources( }; unsafe { - ioctl::mode::get_resources(fd.as_raw_fd(), &mut res)?; + ioctl::mode::get_resources(fd.as_fd(), &mut res)?; } map_set!(fbs, res.count_fbs as usize); @@ -61,7 +61,7 @@ pub fn get_plane_resources( ) -> io::Result { let mut sizes = drm_mode_get_plane_res::default(); unsafe { - ioctl::mode::get_plane_resources(fd.as_raw_fd(), &mut sizes)?; + ioctl::mode::get_plane_resources(fd.as_fd(), &mut sizes)?; } if planes.is_none() { @@ -76,7 +76,7 @@ pub fn get_plane_resources( }; unsafe { - ioctl::mode::get_plane_resources(fd.as_raw_fd(), &mut res)?; + ioctl::mode::get_plane_resources(fd.as_fd(), &mut res)?; } map_set!(planes, res.count_planes as usize); @@ -92,7 +92,7 @@ pub fn get_framebuffer(fd: BorrowedFd<'_>, fb_id: u32) -> io::Result, fb_id: u32) -> io::Result, mut id: u32) -> io::Result<()> { unsafe { - ioctl::mode::rm_fb(fd.as_raw_fd(), &mut id)?; + ioctl::mode::rm_fb(fd.as_fd(), &mut id)?; } Ok(()) @@ -193,7 +193,7 @@ pub fn dirty_fb( }; unsafe { - ioctl::mode::dirty_fb(fd.as_raw_fd(), &mut dirty)?; + ioctl::mode::dirty_fb(fd.as_fd(), &mut dirty)?; } Ok(dirty) @@ -207,7 +207,7 @@ pub fn get_crtc(fd: BorrowedFd<'_>, crtc_id: u32) -> io::Result { }; unsafe { - ioctl::mode::get_crtc(fd.as_raw_fd(), &mut info)?; + ioctl::mode::get_crtc(fd.as_fd(), &mut info)?; } Ok(info) @@ -239,7 +239,7 @@ pub fn set_crtc( }; unsafe { - ioctl::mode::set_crtc(fd.as_raw_fd(), &mut crtc)?; + ioctl::mode::set_crtc(fd.as_fd(), &mut crtc)?; } Ok(crtc) @@ -263,7 +263,7 @@ pub fn get_gamma( }; unsafe { - ioctl::mode::get_gamma(fd.as_raw_fd(), &mut lut)?; + ioctl::mode::get_gamma(fd.as_fd(), &mut lut)?; } Ok(lut) @@ -287,7 +287,7 @@ pub fn set_gamma( }; unsafe { - ioctl::mode::set_gamma(fd.as_raw_fd(), &mut lut)?; + ioctl::mode::set_gamma(fd.as_fd(), &mut lut)?; } Ok(lut) @@ -315,7 +315,7 @@ pub fn set_cursor( }; unsafe { - ioctl::mode::cursor(fd.as_raw_fd(), &mut cursor)?; + ioctl::mode::cursor(fd.as_fd(), &mut cursor)?; } Ok(cursor) @@ -350,7 +350,7 @@ pub fn set_cursor2( }; unsafe { - ioctl::mode::cursor2(fd.as_raw_fd(), &mut cursor)?; + ioctl::mode::cursor2(fd.as_fd(), &mut cursor)?; } Ok(cursor) @@ -373,7 +373,7 @@ pub fn move_cursor( }; unsafe { - ioctl::mode::cursor(fd.as_raw_fd(), &mut cursor)?; + ioctl::mode::cursor(fd.as_fd(), &mut cursor)?; } Ok(cursor) @@ -404,7 +404,7 @@ pub fn get_connector( }; unsafe { - ioctl::mode::get_connector(fd.as_raw_fd(), &mut sizes)?; + ioctl::mode::get_connector(fd.as_fd(), &mut sizes)?; } let info = loop { @@ -444,7 +444,7 @@ pub fn get_connector( }; unsafe { - ioctl::mode::get_connector(fd.as_raw_fd(), &mut info)?; + ioctl::mode::get_connector(fd.as_fd(), &mut info)?; } if info.count_modes == sizes.count_modes @@ -473,7 +473,7 @@ pub fn get_encoder(fd: BorrowedFd<'_>, encoder_id: u32) -> io::Result, id: u32) -> io::Result, lessee_id: u32) -> io::Result<()> { let mut data = drm_mode_revoke_lease { lessee_id }; unsafe { - ioctl::mode::revoke_lease(fd.as_raw_fd(), &mut data)?; + ioctl::mode::revoke_lease(fd.as_fd(), &mut data)?; } Ok(()) @@ -885,7 +885,7 @@ pub mod dumbbuffer { use std::{ io, - os::unix::io::{AsRawFd, BorrowedFd}, + os::unix::io::{AsFd, BorrowedFd}, }; /// Create a dumb buffer @@ -905,7 +905,7 @@ pub mod dumbbuffer { }; unsafe { - ioctl::mode::create_dumb(fd.as_raw_fd(), &mut db)?; + ioctl::mode::create_dumb(fd.as_fd(), &mut db)?; } Ok(db) @@ -916,7 +916,7 @@ pub mod dumbbuffer { let mut db = drm_mode_destroy_dumb { handle }; unsafe { - ioctl::mode::destroy_dumb(fd.as_raw_fd(), &mut db)?; + ioctl::mode::destroy_dumb(fd.as_fd(), &mut db)?; } Ok(db) @@ -936,7 +936,7 @@ pub mod dumbbuffer { }; unsafe { - ioctl::mode::map_dumb(fd.as_raw_fd(), &mut map)?; + ioctl::mode::map_dumb(fd.as_fd(), &mut map)?; } Ok(map) diff --git a/drm-ffi/src/syncobj.rs b/drm-ffi/src/syncobj.rs index 8dd9b5d3..42ef7735 100644 --- a/drm-ffi/src/syncobj.rs +++ b/drm-ffi/src/syncobj.rs @@ -7,7 +7,7 @@ use drm_sys::*; use std::{ io, - os::unix::io::{AsRawFd, BorrowedFd}, + os::unix::io::{AsFd, AsRawFd, BorrowedFd}, }; /// Creates a syncobj. @@ -22,7 +22,7 @@ pub fn create(fd: BorrowedFd<'_>, signaled: bool) -> io::Result, handle: u32) -> io::Result, handles: &[u32]) -> io::Result, handles: &[u32]) -> io::Result