Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use rustix instead of nix #410

Merged
merged 1 commit into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
21 changes: 5 additions & 16 deletions src/data_device_manager/data_offer.rs
Original file line number Diff line number Diff line change
@@ -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},
};

Expand Down Expand Up @@ -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<ReadPipe> {
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.
Expand All @@ -464,11 +459,5 @@ pub fn receive(offer: &WlDataOffer, mime_type: String) -> std::io::Result<ReadPi
/// 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(offer: &WlDataOffer, mime_type: String, writefd: OwnedFd) {
use nix::unistd::close;

offer.receive(mime_type, writefd.as_fd());

if let Err(err) = close(writefd.into_raw_fd()) {
log::warn!("Failed to close write pipe: {}", err);
}
}
21 changes: 5 additions & 16 deletions src/primary_selection/offer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{
os::unix::io::{AsFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd},
os::unix::io::{AsFd, OwnedFd},
sync::Mutex,
};

Expand Down Expand Up @@ -36,32 +36,21 @@ impl PrimarySelectionOffer {
/// Fails if too many file descriptors were already open and a pipe
/// could not be created.
pub fn receive(&self, mime_type: String) -> std::io::Result<ReadPipe> {
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`.
///
/// 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);
}
}
}

Expand Down
7 changes: 0 additions & 7 deletions src/shm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pub mod slot;

use std::io;

use nix::errno::Errno;
use wayland_client::{
globals::{BindError, GlobalList},
protocol::wl_shm,
Expand Down Expand Up @@ -70,12 +69,6 @@ pub enum CreatePoolError {
Create(#[from] io::Error),
}

impl From<Errno> for CreatePoolError {
fn from(errno: Errno) -> Self {
Into::<io::Error>::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
Expand Down
54 changes: 20 additions & 34 deletions src/shm/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -48,7 +46,7 @@ impl RawPool {
) -> Result<RawPool, CreatePoolError> {
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
Expand Down Expand Up @@ -170,14 +168,14 @@ impl io::Seek for RawPool {
}

impl RawPool {
fn create_shm_fd() -> io::Result<RawFd> {
fn create_shm_fd() -> io::Result<OwnedFd> {
#[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::<io::Error>::into(err)),
};
Expand All @@ -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();

Expand All @@ -220,38 +213,31 @@ impl RawPool {
continue;
}

Err(Errno::EINTR) => continue,
Err(Errno::INTR) => continue,

Err(err) => return Err(err.into()),
}
}
}

#[cfg(target_os = "linux")]
fn create_memfd() -> nix::Result<RawFd> {
fn create_memfd() -> rustix::io::Result<OwnedFd> {
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),
}
Expand Down
Loading