From 714d31a5925c05ae44580f9fbc333c1ed969fe11 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Fri, 22 Sep 2023 15:09:36 -0700 Subject: [PATCH] Use `rustix` instead of `nix` This is cleaner than `nix` due to the use of `OwnedFd`/`BorrowedFd`. `calloop` is already using `rustix`. --- Cargo.toml | 2 +- src/data_device_manager/data_offer.rs | 21 +++-------- src/primary_selection/offer.rs | 21 +++-------- src/shm/mod.rs | 7 ---- src/shm/raw.rs | 54 ++++++++++----------------- 5 files changed, 31 insertions(+), 74 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c0ad3f35d..ee9b15a75 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ cursor-icon = "1.0.0" dlib = "0.5" log = "0.4" memmap2 = "0.7.0" -nix = { version = "0.26.1", default-features = false, features = ["fs", "mman"] } +rustix = { version = "0.38.15", features = ["fs", "pipe", "shm"] } thiserror = "1.0.30" wayland-backend = "0.3.0" wayland-client = "0.31.1" diff --git a/src/data_device_manager/data_offer.rs b/src/data_device_manager/data_offer.rs index 18bb031db..3614a790e 100644 --- a/src/data_device_manager/data_offer.rs +++ b/src/data_device_manager/data_offer.rs @@ -1,6 +1,6 @@ use std::{ ops::{Deref, DerefMut}, - os::unix::prelude::{AsFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd}, + os::unix::prelude::{AsFd, OwnedFd}, sync::{Arc, Mutex}, }; @@ -436,18 +436,13 @@ impl PartialEq for UndeterminedOffer { /// Fails if too many file descriptors were already open and a pipe /// could not be created. pub fn receive(offer: &WlDataOffer, mime_type: String) -> std::io::Result { - use nix::fcntl::OFlag; - use nix::unistd::{close, pipe2}; + use rustix::pipe::{pipe_with, PipeFlags}; // create a pipe - let (readfd, writefd) = pipe2(OFlag::O_CLOEXEC)?; + let (readfd, writefd) = pipe_with(PipeFlags::CLOEXEC)?; - offer.receive(mime_type, unsafe { BorrowedFd::borrow_raw(writefd) }); + receive_to_fd(offer, mime_type, writefd); - if let Err(err) = close(writefd) { - log::warn!("Failed to close write pipe: {}", err); - } - - Ok(unsafe { FromRawFd::from_raw_fd(readfd) }) + Ok(ReadPipe::from(readfd)) } /// Receive data to the write end of a raw file descriptor. If you have the read end, you can read from it. @@ -464,11 +459,5 @@ pub fn receive(offer: &WlDataOffer, mime_type: String) -> std::io::Result std::io::Result { - use nix::fcntl::OFlag; - use nix::unistd::{close, pipe2}; + use rustix::pipe::{pipe_with, PipeFlags}; // create a pipe - let (readfd, writefd) = pipe2(OFlag::O_CLOEXEC)?; + let (readfd, writefd) = pipe_with(PipeFlags::CLOEXEC)?; - self.offer.receive(mime_type, unsafe { BorrowedFd::borrow_raw(writefd) }); + self.receive_to_fd(mime_type, writefd); - if let Err(err) = close(writefd) { - log::warn!("Failed to close write pipe: {}", err); - } - - Ok(unsafe { FromRawFd::from_raw_fd(readfd) }) + Ok(ReadPipe::from(readfd)) } /// Request to receive the data of a given mime type, writen to `writefd`. @@ -55,13 +50,7 @@ impl PrimarySelectionOffer { /// The provided file destructor must be a valid FD for writing, and will be closed /// once the contents are written. pub fn receive_to_fd(&self, mime_type: String, writefd: OwnedFd) { - use nix::unistd::close; - self.offer.receive(mime_type, writefd.as_fd()); - - if let Err(err) = close(writefd.into_raw_fd()) { - log::warn!("Failed to close write pipe: {}", err); - } } } diff --git a/src/shm/mod.rs b/src/shm/mod.rs index ca5ad1d2d..d660c306a 100644 --- a/src/shm/mod.rs +++ b/src/shm/mod.rs @@ -4,7 +4,6 @@ pub mod slot; use std::io; -use nix::errno::Errno; use wayland_client::{ globals::{BindError, GlobalList}, protocol::wl_shm, @@ -70,12 +69,6 @@ pub enum CreatePoolError { Create(#[from] io::Error), } -impl From for CreatePoolError { - fn from(errno: Errno) -> Self { - Into::::into(errno).into() - } -} - /// Delegates the handling of [`wl_shm`] to some [`Shm`]. /// /// This macro requires two things, the type that will delegate to [`Shm`] and a closure specifying how diff --git a/src/shm/raw.rs b/src/shm/raw.rs index a2e9b576e..690352649 100644 --- a/src/shm/raw.rs +++ b/src/shm/raw.rs @@ -3,21 +3,19 @@ //! This is intended as a safe building block for higher level shared memory pool abstractions and is not //! encouraged for most library users. +use rustix::{ + io::Errno, + shm::{Mode, ShmOFlags}, +}; use std::{ fs::File, io, - os::unix::prelude::{AsFd, FromRawFd, OwnedFd, RawFd}, + os::unix::prelude::{AsFd, OwnedFd}, sync::Arc, time::{SystemTime, UNIX_EPOCH}, }; use memmap2::MmapMut; -use nix::{ - errno::Errno, - fcntl, - sys::{mman, stat}, - unistd, -}; use wayland_client::{ backend::ObjectData, protocol::{wl_buffer, wl_shm, wl_shm_pool}, @@ -48,7 +46,7 @@ impl RawPool { ) -> Result { let shm = shm.bound_global()?; let shm_fd = RawPool::create_shm_fd()?; - let mem_file = unsafe { File::from_raw_fd(shm_fd) }; + let mem_file = File::from(shm_fd); mem_file.set_len(len as u64)?; let pool = shm @@ -170,14 +168,14 @@ impl io::Seek for RawPool { } impl RawPool { - fn create_shm_fd() -> io::Result { + fn create_shm_fd() -> io::Result { #[cfg(target_os = "linux")] { match RawPool::create_memfd() { Ok(fd) => return Ok(fd), // Not supported, use fallback. - Err(Errno::ENOSYS) => (), + Err(Errno::NOSYS) => (), Err(err) => return Err(Into::::into(err)), }; @@ -190,25 +188,20 @@ impl RawPool { ); loop { - let flags = fcntl::OFlag::O_CREAT - | fcntl::OFlag::O_EXCL - | fcntl::OFlag::O_RDWR - | fcntl::OFlag::O_CLOEXEC; + let flags = ShmOFlags::CREATE | ShmOFlags::EXCL | ShmOFlags::RDWR; - let mode = stat::Mode::S_IRUSR | stat::Mode::S_IWUSR; + let mode = Mode::RUSR | Mode::WUSR; - match mman::shm_open(mem_file_handle.as_str(), flags, mode) { - Ok(fd) => match mman::shm_unlink(mem_file_handle.as_str()) { + match rustix::shm::shm_open(mem_file_handle.as_str(), flags, mode) { + Ok(fd) => match rustix::shm::shm_unlink(mem_file_handle.as_str()) { Ok(_) => return Ok(fd), Err(errno) => { - unistd::close(fd)?; - return Err(errno.into()); } }, - Err(Errno::EEXIST) => { + Err(Errno::EXIST) => { // Change the handle if we happen to be duplicate. let time = SystemTime::now(); @@ -220,7 +213,7 @@ impl RawPool { continue; } - Err(Errno::EINTR) => continue, + Err(Errno::INTR) => continue, Err(err) => return Err(err.into()), } @@ -228,30 +221,23 @@ impl RawPool { } #[cfg(target_os = "linux")] - fn create_memfd() -> nix::Result { + fn create_memfd() -> rustix::io::Result { use std::ffi::CStr; - use nix::{ - fcntl::{FcntlArg, SealFlag}, - sys::memfd::{self, MemFdCreateFlag}, - }; + use rustix::fs::{MemfdFlags, SealFlags}; loop { let name = CStr::from_bytes_with_nul(b"smithay-client-toolkit\0").unwrap(); - let flags = MemFdCreateFlag::MFD_ALLOW_SEALING | MemFdCreateFlag::MFD_CLOEXEC; + let flags = MemfdFlags::ALLOW_SEALING | MemfdFlags::CLOEXEC; - match memfd::memfd_create(name, flags) { + match rustix::fs::memfd_create(name, flags) { Ok(fd) => { - let arg = - FcntlArg::F_ADD_SEALS(SealFlag::F_SEAL_SHRINK | SealFlag::F_SEAL_SEAL); - // We only need to seal for the purposes of optimization, ignore the errors. - let _ = fcntl::fcntl(fd, arg); - + let _ = rustix::fs::fcntl_add_seals(&fd, SealFlags::SHRINK | SealFlags::SEAL); return Ok(fd); } - Err(Errno::EINTR) => continue, + Err(Errno::INTR) => continue, Err(err) => return Err(err), }