diff --git a/wayland-backend/Cargo.toml b/wayland-backend/Cargo.toml index 766a7a25963..fba75d33a13 100644 --- a/wayland-backend/Cargo.toml +++ b/wayland-backend/Cargo.toml @@ -19,6 +19,7 @@ log = { version = "0.4", optional = true } scoped-tls = "1.0" downcast-rs = "1.2" raw-window-handle = { version = "0.5.0", optional = true } +libc = "0.2.148" [dependencies.smallvec] version = "1.9" @@ -29,15 +30,13 @@ features = [ "const_new", # 1.51 ] -[dependencies.nix] -version = "0.26.0" -default-features = false +[dependencies.rustix] +version = "0.38.17" features = [ "event", "fs", - "poll", - "socket", - "uio", + "net", + "process", ] [build-dependencies] diff --git a/wayland-backend/src/rs/server_impl/client.rs b/wayland-backend/src/rs/server_impl/client.rs index eb845e6fa47..b324d5fb09c 100644 --- a/wayland-backend/src/rs/server_impl/client.rs +++ b/wayland-backend/src/rs/server_impl/client.rs @@ -1,6 +1,6 @@ use std::{ ffi::CString, - os::unix::io::OwnedFd, + os::unix::io::{AsFd, BorrowedFd, OwnedFd}, os::unix::{io::RawFd, net::UnixStream}, sync::Arc, }; @@ -295,13 +295,10 @@ impl Client { #[cfg(any(target_os = "linux", target_os = "android"))] pub(crate) fn get_credentials(&self) -> Credentials { - use std::os::unix::io::AsRawFd; - let creds = nix::sys::socket::getsockopt( - self.socket.as_raw_fd(), - nix::sys::socket::sockopt::PeerCredentials, - ) - .expect("getsockopt failed!?"); - Credentials { pid: creds.pid(), uid: creds.uid(), gid: creds.gid() } + let creds = + rustix::net::sockopt::get_socket_peercred(&self.socket).expect("getsockopt failed!?"); + let pid = rustix::process::Pid::as_raw(Some(creds.pid)); + Credentials { pid, uid: creds.uid.as_raw(), gid: creds.gid.as_raw() } } #[cfg(not(any(target_os = "linux", target_os = "android")))] @@ -336,7 +333,7 @@ impl Client { &mut self, ) -> std::io::Result<(Message, Object>)> { if self.killed { - return Err(nix::errno::Errno::EPIPE.into()); + return Err(rustix::io::Errno::PIPE.into()); } loop { let map = &self.map; @@ -358,7 +355,7 @@ impl Client { } Err(MessageParseError::Malformed) => { self.kill(DisconnectReason::ConnectionClosed); - return Err(nix::errno::Errno::EPROTO.into()); + return Err(rustix::io::Errno::PROTO.into()); } }; @@ -659,6 +656,12 @@ impl Client { } } +impl AsFd for Client { + fn as_fd(&self) -> BorrowedFd<'_> { + self.socket.as_fd() + } +} + #[derive(Debug)] pub(crate) struct ClientStore { clients: Vec>>, diff --git a/wayland-backend/src/rs/server_impl/common_poll.rs b/wayland-backend/src/rs/server_impl/common_poll.rs index c0b8fd4ac3b..0a9fe05bfe3 100644 --- a/wayland-backend/src/rs/server_impl/common_poll.rs +++ b/wayland-backend/src/rs/server_impl/common_poll.rs @@ -1,5 +1,5 @@ use std::{ - os::unix::io::{AsRawFd, FromRawFd}, + os::unix::io::AsRawFd, os::unix::io::{BorrowedFd, OwnedFd}, sync::{Arc, Mutex}, }; @@ -16,7 +16,7 @@ use crate::{ }; #[cfg(any(target_os = "linux", target_os = "android"))] -use nix::sys::epoll::*; +use rustix::event::epoll; #[cfg(any( target_os = "dragonfly", @@ -24,7 +24,7 @@ use nix::sys::epoll::*; target_os = "netbsd", target_os = "openbsd" ))] -use nix::sys::event::*; +use rustix::event::kqueue::*; use smallvec::SmallVec; #[derive(Debug)] @@ -35,7 +35,7 @@ pub struct InnerBackend { impl InnerBackend { pub fn new() -> Result { #[cfg(any(target_os = "linux", target_os = "android"))] - let poll_fd = epoll_create1(EpollCreateFlags::EPOLL_CLOEXEC) + let poll_fd = epoll::create(epoll::CreateFlags::CLOEXEC) .map_err(Into::into) .map_err(InitError::Io)?; @@ -47,9 +47,7 @@ impl InnerBackend { ))] let poll_fd = kqueue().map_err(Into::into).map_err(InitError::Io)?; - Ok(Self { - state: Arc::new(Mutex::new(State::new(unsafe { OwnedFd::from_raw_fd(poll_fd) }))), - }) + Ok(Self { state: Arc::new(Mutex::new(State::new(poll_fd))) }) } pub fn flush(&self, client: Option) -> std::io::Result<()> { @@ -80,18 +78,20 @@ impl InnerBackend { #[cfg(any(target_os = "linux", target_os = "android"))] pub fn dispatch_all_clients(&self, data: &mut D) -> std::io::Result { + use std::os::unix::io::AsFd; + let poll_fd = self.poll_fd(); let mut dispatched = 0; loop { - let mut events = [EpollEvent::empty(); 32]; - let nevents = epoll_wait(poll_fd.as_raw_fd(), &mut events, 0)?; + let mut events = epoll::EventVec::with_capacity(32); + epoll::wait(poll_fd.as_fd(), &mut events, 0)?; - if nevents == 0 { + if events.is_empty() { break; } - for event in events.iter().take(nevents) { - let id = InnerClientId::from_u64(event.data()); + for event in events.iter() { + let id = InnerClientId::from_u64(event.data.u64()); // remove the cb while we call it, to gracefully handle reentrancy if let Ok(count) = self.dispatch_events_for(data, id) { dispatched += count; @@ -111,19 +111,13 @@ impl InnerBackend { target_os = "openbsd" ))] pub fn dispatch_all_clients(&self, data: &mut D) -> std::io::Result { + use std::time::Duration; + let poll_fd = self.poll_fd(); let mut dispatched = 0; loop { - let mut events = [KEvent::new( - 0, - EventFilter::EVFILT_READ, - EventFlag::empty(), - FilterFlag::empty(), - 0, - 0, - ); 32]; - - let nevents = kevent(poll_fd.as_raw_fd(), &[], &mut events, 0)?; + let mut events = Vec::with_capacity(32); + let nevents = unsafe { kevent(&poll_fd, &[], &mut events, Some(Duration::ZERO))? }; if nevents == 0 { break; diff --git a/wayland-backend/src/rs/server_impl/handle.rs b/wayland-backend/src/rs/server_impl/handle.rs index 0ec5de8e4cf..5030819b279 100644 --- a/wayland-backend/src/rs/server_impl/handle.rs +++ b/wayland-backend/src/rs/server_impl/handle.rs @@ -1,10 +1,7 @@ use std::{ ffi::CString, os::unix::io::OwnedFd, - os::unix::{ - io::{AsRawFd, RawFd}, - net::UnixStream, - }, + os::unix::{io::RawFd, net::UnixStream}, sync::{Arc, Mutex, Weak}, }; @@ -314,15 +311,19 @@ impl ErasedState for State { stream: UnixStream, data: Arc, ) -> std::io::Result { - let client_fd = stream.as_raw_fd(); let id = self.clients.create_client(stream, data); + let client = self.clients.get_client(id.clone()).unwrap(); // register the client to the internal epoll #[cfg(any(target_os = "linux", target_os = "android"))] let ret = { - use nix::sys::epoll::*; - let mut evt = EpollEvent::new(EpollFlags::EPOLLIN, id.as_u64()); - epoll_ctl(self.poll_fd.as_raw_fd(), EpollOp::EpollCtlAdd, client_fd, &mut evt) + use rustix::event::epoll; + epoll::add( + &self.poll_fd, + client, + epoll::EventData::new_u64(id.as_u64()), + epoll::EventFlags::IN, + ) }; #[cfg(any( @@ -332,17 +333,17 @@ impl ErasedState for State { target_os = "openbsd" ))] let ret = { - use nix::sys::event::*; - let evt = KEvent::new( - client_fd as usize, - EventFilter::EVFILT_READ, - EventFlag::EV_ADD | EventFlag::EV_RECEIPT, - FilterFlag::empty(), - 0, + use rustix::event::kqueue::*; + use std::os::unix::io::{AsFd, AsRawFd}; + + let evt = Event::new( + EventFilter::Read(client.as_fd().as_raw_fd()), + EventFlags::ADD | EventFlags::RECEIPT, id.as_u64() as isize, ); - kevent_ts(self.poll_fd.as_raw_fd(), &[evt], &mut [], None).map(|_| ()) + let mut events = Vec::new(); + unsafe { kevent(&self.poll_fd, &[evt], &mut events, None).map(|_| ()) } }; match ret { diff --git a/wayland-backend/src/rs/socket.rs b/wayland-backend/src/rs/socket.rs index 27c7749f761..34efa98b842 100644 --- a/wayland-backend/src/rs/socket.rs +++ b/wayland-backend/src/rs/socket.rs @@ -1,11 +1,14 @@ //! Wayland socket manipulation use std::io::{ErrorKind, IoSlice, IoSliceMut, Result as IoResult}; -use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; -use std::os::unix::io::{AsRawFd, RawFd}; +use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, IntoRawFd, OwnedFd, RawFd}; use std::os::unix::net::UnixStream; +use std::slice; -use nix::sys::socket; +use rustix::net::{ + recvmsg, sendmsg, RecvAncillaryBuffer, RecvFlags, SendAncillaryBuffer, SendAncillaryMessage, + SendFlags, +}; use crate::protocol::{ArgumentType, Message}; @@ -35,14 +38,19 @@ impl Socket { /// slice should not be longer than `MAX_BYTES_OUT` otherwise the receiving /// end may lose some data. pub fn send_msg(&self, bytes: &[u8], fds: &[RawFd]) -> IoResult { - let flags = socket::MsgFlags::MSG_DONTWAIT | socket::MsgFlags::MSG_NOSIGNAL; + let flags = SendFlags::DONTWAIT | SendFlags::NOSIGNAL; let iov = [IoSlice::new(bytes)]; if !fds.is_empty() { - let cmsgs = [socket::ControlMessage::ScmRights(fds)]; - Ok(socket::sendmsg::<()>(self.stream.as_raw_fd(), &iov, &cmsgs, flags, None)?) + let mut cmsg_space = vec![0; rustix::cmsg_space!(ScmRights(1))]; + let mut cmsg_buffer = SendAncillaryBuffer::new(&mut cmsg_space); + let fds = + unsafe { slice::from_raw_parts(fds.as_ptr() as *const BorrowedFd, fds.len()) }; + cmsg_buffer.push(SendAncillaryMessage::ScmRights(fds)); + Ok(sendmsg(self, &iov, &mut cmsg_buffer, flags)?) } else { - Ok(socket::sendmsg::<()>(self.stream.as_raw_fd(), &iov, &[], flags, None)?) + let mut cmsg_buffer = SendAncillaryBuffer::new(&mut []); + Ok(sendmsg(self, &iov, &mut cmsg_buffer, flags)?) } } @@ -58,25 +66,28 @@ impl Socket { /// slice `MAX_FDS_OUT` long, otherwise some data of the received message may /// be lost. pub fn rcv_msg(&self, buffer: &mut [u8], fds: &mut [RawFd]) -> IoResult<(usize, usize)> { - let mut cmsg = nix::cmsg_space!([RawFd; MAX_FDS_OUT]); + let mut cmsg_space = vec![0; rustix::cmsg_space!(ScmRights(MAX_FDS_OUT))]; + let mut cmsg_buffer = RecvAncillaryBuffer::new(&mut cmsg_space); let mut iov = [IoSliceMut::new(buffer)]; - let msg = socket::recvmsg::<()>( - self.stream.as_raw_fd(), + let msg = recvmsg( + &self.stream, &mut iov[..], - Some(&mut cmsg), - socket::MsgFlags::MSG_DONTWAIT - | socket::MsgFlags::MSG_CMSG_CLOEXEC - | socket::MsgFlags::MSG_NOSIGNAL, + &mut cmsg_buffer, + RecvFlags::DONTWAIT | RecvFlags::CMSG_CLOEXEC, )?; let mut fd_count = 0; - let received_fds = msg.cmsgs().flat_map(|cmsg| match cmsg { - socket::ControlMessageOwned::ScmRights(s) => s, - _ => Vec::new(), - }); + let received_fds = cmsg_buffer + .drain() + .filter_map(|cmsg| match cmsg { + rustix::net::RecvAncillaryMessage::ScmRights(fds) => Some(fds), + _ => None, + }) + .flatten(); for (fd, place) in received_fds.zip(fds.iter_mut()) { fd_count += 1; - *place = fd; + // TODO use OwnedFd? + *place = fd.into_raw_fd(); } Ok((msg.bytes, fd_count)) } @@ -141,7 +152,7 @@ impl BufferedSocket { let written = self.socket.send_msg(bytes, fds)?; for &fd in fds { // once the fds are sent, we can close them - let _ = ::nix::unistd::close(fd); + let _ = unsafe { libc::close(fd) }; } written }; @@ -192,7 +203,7 @@ impl BufferedSocket { if !self.attempt_write_message(msg)? { // If this fails again, this means the message is too big // to be transmitted at all - return Err(::nix::errno::Errno::E2BIG.into()); + return Err(rustix::io::Errno::TOOBIG.into()); } } Ok(()) @@ -215,7 +226,7 @@ impl BufferedSocket { }; if in_bytes == 0 { // the other end of the socket was closed - return Err(::nix::errno::Errno::EPIPE.into()); + return Err(rustix::io::Errno::PIPE.into()); } // advance the storage self.in_data.advance(in_bytes / 4 + usize::from(in_bytes % 4 > 0)); @@ -342,14 +353,14 @@ mod tests { use crate::protocol::{AllowNull, Argument, ArgumentType, Message}; use std::ffi::CString; - use std::os::unix::io::RawFd; + use std::os::unix::io::BorrowedFd; use std::os::unix::prelude::IntoRawFd; use smallvec::smallvec; - fn same_file(a: RawFd, b: RawFd) -> bool { - let stat1 = ::nix::sys::stat::fstat(a).unwrap(); - let stat2 = ::nix::sys::stat::fstat(b).unwrap(); + fn same_file(a: BorrowedFd, b: BorrowedFd) -> bool { + let stat1 = rustix::fs::fstat(a).unwrap(); + let stat2 = rustix::fs::fstat(b).unwrap(); stat1.st_dev == stat2.st_dev && stat1.st_ino == stat2.st_ino } @@ -366,7 +377,9 @@ mod tests { assert_eq!(msg1.args.len(), msg2.args.len()); for (arg1, arg2) in msg1.args.iter().zip(msg2.args.iter()) { if let (Argument::Fd(fd1), Argument::Fd(fd2)) = (arg1, arg2) { - assert!(same_file(fd1.as_raw_fd(), fd2.as_raw_fd())); + let fd1 = unsafe { BorrowedFd::borrow_raw(fd1.as_raw_fd()) }; + let fd2 = unsafe { BorrowedFd::borrow_raw(fd2.as_raw_fd()) }; + assert!(same_file(fd1, fd2)); } else { assert_eq!(arg1, arg2); } diff --git a/wayland-backend/src/sys/client_impl/mod.rs b/wayland-backend/src/sys/client_impl/mod.rs index 7a48f8ce259..824b910a907 100644 --- a/wayland-backend/src/sys/client_impl/mod.rs +++ b/wayland-backend/src/sys/client_impl/mod.rs @@ -322,7 +322,7 @@ impl ConnectionState { #[inline] fn store_and_return_error(&mut self, err: std::io::Error) -> WaylandError { // check if it was actually a protocol error - let err = if err.raw_os_error() == Some(nix::errno::Errno::EPROTO as i32) { + let err = if err.raw_os_error() == Some(rustix::io::Errno::PROTO.raw_os_error()) { let mut object_id = 0; let mut interface = std::ptr::null(); let code = unsafe { diff --git a/wayland-backend/src/test/many_args.rs b/wayland-backend/src/test/many_args.rs index 1b65ae20902..565011a80a4 100644 --- a/wayland-backend/src/test/many_args.rs +++ b/wayland-backend/src/test/many_args.rs @@ -1,6 +1,5 @@ use std::{ ffi::{CStr, CString}, - os::unix::io::AsRawFd, sync::atomic::{AtomicBool, Ordering}, }; @@ -32,8 +31,8 @@ macro_rules! serverdata_impls { assert_eq!(&**a, &[1, 2, 3, 4, 5, 6, 7, 8, 9]); assert_eq!(&***s, CStr::from_bytes_with_nul(b"I like trains\0").unwrap()); // compare the fd to stdin - let stat1 = ::nix::sys::stat::fstat(fd.as_raw_fd()).unwrap(); - let stat2 = ::nix::sys::stat::fstat(0).unwrap(); + let stat1 = rustix::fs::fstat(&fd).unwrap(); + let stat2 = rustix::fs::fstat(std::io::stdin()).unwrap(); assert_eq!(stat1.st_dev, stat2.st_dev); assert_eq!(stat1.st_ino, stat2.st_ino); } else { @@ -105,8 +104,8 @@ macro_rules! clientdata_impls { assert_eq!(&**a, &[10, 20, 30, 40, 50, 60, 70, 80, 90]); assert_eq!(&***s, CStr::from_bytes_with_nul(b"I want cake\0").unwrap()); // compare the fd to stdout - let stat1 = ::nix::sys::stat::fstat(fd.as_raw_fd()).unwrap(); - let stat2 = ::nix::sys::stat::fstat(1).unwrap(); + let stat1 = rustix::fs::fstat(&fd).unwrap(); + let stat2 = rustix::fs::fstat(std::io::stdout()).unwrap(); assert_eq!(stat1.st_dev, stat2.st_dev); assert_eq!(stat1.st_ino, stat2.st_ino); } else { diff --git a/wayland-backend/src/types/server.rs b/wayland-backend/src/types/server.rs index 27b286a8bba..3377479078a 100644 --- a/wayland-backend/src/types/server.rs +++ b/wayland-backend/src/types/server.rs @@ -66,9 +66,9 @@ pub enum DisconnectReason { #[derive(Debug, Clone, Copy)] pub struct Credentials { /// pid of the client - pub pid: nix::libc::pid_t, + pub pid: libc::pid_t, /// uid of the client - pub uid: nix::libc::uid_t, + pub uid: libc::uid_t, /// gid of the client - pub gid: nix::libc::gid_t, + pub gid: libc::gid_t, } diff --git a/wayland-client/Cargo.toml b/wayland-client/Cargo.toml index 2aa03c1ba43..d51bb3cfa50 100644 --- a/wayland-client/Cargo.toml +++ b/wayland-client/Cargo.toml @@ -16,7 +16,7 @@ readme = "README.md" wayland-backend = { version = "0.3.1", path = "../wayland-backend" } wayland-scanner = { version = "0.31.0", path = "../wayland-scanner" } bitflags = "2" -nix = { version = "0.26.0", default-features = false } +rustix = { version = "0.38.0", features = ["event"] } log = { version = "0.4", optional = true } [dev-dependencies] diff --git a/wayland-client/src/conn.rs b/wayland-client/src/conn.rs index 3dc89af8796..489315d6c22 100644 --- a/wayland-client/src/conn.rs +++ b/wayland-client/src/conn.rs @@ -16,8 +16,6 @@ use wayland_backend::{ protocol::{ObjectInfo, ProtocolError}, }; -use nix::{fcntl, Error}; - use crate::{protocol::wl_display::WlDisplay, EventQueue, Proxy}; /// The Wayland connection @@ -50,21 +48,23 @@ impl Connection { let stream = if let Ok(txt) = env::var("WAYLAND_SOCKET") { // We should connect to the provided WAYLAND_SOCKET let fd = txt.parse::().map_err(|_| ConnectError::InvalidFd)?; + let fd = unsafe { OwnedFd::from_raw_fd(fd) }; // remove the variable so any child processes don't see it env::remove_var("WAYLAND_SOCKET"); // set the CLOEXEC flag on this FD - let flags = fcntl::fcntl(fd, fcntl::FcntlArg::F_GETFD); + let flags = rustix::io::fcntl_getfd(&fd); let result = flags - .map(|f| fcntl::FdFlag::from_bits(f).unwrap() | fcntl::FdFlag::FD_CLOEXEC) - .and_then(|f| fcntl::fcntl(fd, fcntl::FcntlArg::F_SETFD(f))); + .map(|f| f | rustix::io::FdFlags::CLOEXEC) + .and_then(|f| rustix::io::fcntl_setfd(&fd, f)); match result { Ok(_) => { // setting the O_CLOEXEC worked - unsafe { FromRawFd::from_raw_fd(fd) } + // XXX + use rustix::fd::IntoRawFd; + unsafe { FromRawFd::from_raw_fd(fd.into_raw_fd()) } } Err(_) => { // something went wrong in F_GETFD or F_SETFD - let _ = ::nix::unistd::close(fd); return Err(ConnectError::InvalidFd); } } @@ -156,7 +156,7 @@ impl Connection { crate::protocol::wl_display::Request::Sync {}, Some(done.clone()), ) - .map_err(|_| WaylandError::Io(Error::EPIPE.into()))?; + .map_err(|_| WaylandError::Io(rustix::io::Errno::PIPE.into()))?; let mut dispatched = 0; @@ -220,15 +220,16 @@ impl Connection { } pub(crate) fn blocking_read(guard: ReadEventsGuard) -> Result { - let mut fds = [nix::poll::PollFd::new( - guard.connection_fd().as_raw_fd(), - nix::poll::PollFlags::POLLIN | nix::poll::PollFlags::POLLERR, + let fd = guard.connection_fd(); + let mut fds = [rustix::event::PollFd::new( + &fd, + rustix::event::PollFlags::IN | rustix::event::PollFlags::ERR, )]; loop { - match nix::poll::poll(&mut fds, -1) { + match rustix::event::poll(&mut fds, -1) { Ok(_) => break, - Err(nix::errno::Errno::EINTR) => continue, + Err(rustix::io::Errno::INTR) => continue, Err(e) => return Err(WaylandError::Io(e.into())), } } diff --git a/wayland-client/src/event_queue.rs b/wayland-client/src/event_queue.rs index 5507ab9e98d..94674bd3747 100644 --- a/wayland-client/src/event_queue.rs +++ b/wayland-client/src/event_queue.rs @@ -6,7 +6,6 @@ use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; use std::sync::{atomic::Ordering, Arc, Condvar, Mutex}; use std::task; -use nix::Error; use wayland_backend::{ client::{Backend, ObjectData, ObjectId, ReadEventsGuard, WaylandError}, protocol::{Argument, Message}, @@ -424,7 +423,7 @@ impl EventQueue { crate::protocol::wl_display::Request::Sync {}, Some(done.clone()), ) - .map_err(|_| WaylandError::Io(Error::EPIPE.into()))?; + .map_err(|_| WaylandError::Io(rustix::io::Errno::PIPE.into()))?; let mut dispatched = 0; diff --git a/wayland-cursor/Cargo.toml b/wayland-cursor/Cargo.toml index fec81b01b1c..5d57a9e1d16 100644 --- a/wayland-cursor/Cargo.toml +++ b/wayland-cursor/Cargo.toml @@ -15,7 +15,7 @@ readme = "README.md" [dependencies] wayland-client = { version = "0.31.0", path = "../wayland-client" } xcursor = "0.3.1" -nix = { version = "0.26.0", default-features = false, features = ["mman"] } +rustix = { version = "0.38.15", features = ["shm"] } [package.metadata.docs.rs] all-features = true diff --git a/wayland-cursor/src/lib.rs b/wayland-cursor/src/lib.rs index a7e3061dc6f..ff6ae747273 100644 --- a/wayland-cursor/src/lib.rs +++ b/wayland-cursor/src/lib.rs @@ -49,16 +49,17 @@ use std::env; use std::fs::File; use std::io::{Error as IoError, Read, Result as IoResult, Seek, SeekFrom, Write}; use std::ops::{Deref, Index}; -use std::os::unix::io::{AsFd, FromRawFd, OwnedFd, RawFd}; +use std::os::unix::io::{AsFd, OwnedFd}; use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; -use nix::errno::Errno; -use nix::fcntl; -use nix::sys::{mman, stat}; -use nix::unistd; +use rustix::fs::Mode; #[cfg(any(target_os = "linux", target_os = "android"))] -use {nix::sys::memfd, std::ffi::CStr}; +use rustix::fs::{memfd_create, MemfdFlags}; +use rustix::io::Errno; +use rustix::shm::{shm_open, shm_unlink, ShmOFlags}; +#[cfg(any(target_os = "linux", target_os = "android"))] +use std::ffi::CStr; use wayland_client::backend::{InvalidId, ObjectData, WeakBackend}; use wayland_client::protocol::wl_buffer::WlBuffer; @@ -134,7 +135,7 @@ impl CursorTheme { // Create shm. let mem_fd = create_shm_fd().expect("Shm fd allocation failed"); - let mut file = unsafe { File::from_raw_fd(mem_fd) }; + let mut file = File::from(mem_fd); file.set_len(INITIAL_POOL_SIZE as u64).expect("Failed to set buffer length"); // Ensure that we have the same we requested. @@ -374,17 +375,17 @@ pub struct FrameAndDuration { } /// Create a shared file descriptor in memory. -fn create_shm_fd() -> IoResult { +fn create_shm_fd() -> IoResult { // Only try memfd on systems that provide it, (like Linux, Android) #[cfg(any(target_os = "linux", target_os = "android"))] loop { - match memfd::memfd_create( + match memfd_create( CStr::from_bytes_with_nul(b"wayland-cursor-rs\0").unwrap(), - memfd::MemFdCreateFlag::MFD_CLOEXEC, + MemfdFlags::CLOEXEC, ) { Ok(fd) => return Ok(fd), - Err(Errno::EINTR) => continue, - Err(Errno::ENOSYS) => break, + Err(Errno::INTR) => continue, + Err(Errno::NOSYS) => break, Err(errno) => return Err(errno.into()), } } @@ -396,22 +397,16 @@ fn create_shm_fd() -> IoResult { sys_time.duration_since(UNIX_EPOCH).unwrap().subsec_nanos() ); loop { - match mman::shm_open( + match shm_open( mem_file_handle.as_str(), - fcntl::OFlag::O_CREAT - | fcntl::OFlag::O_EXCL - | fcntl::OFlag::O_RDWR - | fcntl::OFlag::O_CLOEXEC, - stat::Mode::S_IRUSR | stat::Mode::S_IWUSR, + ShmOFlags::CREATE | ShmOFlags::EXCL | ShmOFlags::RDWR, + Mode::RUSR | Mode::WUSR, ) { - Ok(fd) => match mman::shm_unlink(mem_file_handle.as_str()) { + Ok(fd) => match shm_unlink(mem_file_handle.as_str()) { Ok(_) => return Ok(fd), - Err(errno) => match unistd::close(fd) { - Ok(_) => return Err(IoError::from(errno)), - Err(errno) => return Err(IoError::from(errno)), - }, + Err(errno) => return Err(IoError::from(errno)), }, - Err(Errno::EEXIST) => { + Err(Errno::EXIST) => { // If a file with that handle exists then change the handle mem_file_handle = format!( "/wayland-cursor-rs-{}", @@ -419,7 +414,7 @@ fn create_shm_fd() -> IoResult { ); continue; } - Err(Errno::EINTR) => continue, + Err(Errno::INTR) => continue, Err(errno) => return Err(IoError::from(errno)), } } diff --git a/wayland-server/Cargo.toml b/wayland-server/Cargo.toml index 020d6f37ad8..e6d80c0e85e 100644 --- a/wayland-server/Cargo.toml +++ b/wayland-server/Cargo.toml @@ -17,9 +17,9 @@ wayland-backend = { version = "0.3.0", path = "../wayland-backend" } wayland-scanner = { version = "0.31.0", path = "../wayland-scanner" } bitflags = "2" log = { version = "0.4", optional = true } -nix = { version = "0.26.0", default-features = false } downcast-rs = "1.2" io-lifetimes = "2" +rustix = { version = "0.38.14", features = ["fs"] } [package.metadata.docs.rs] all-features = true diff --git a/wayland-server/src/socket.rs b/wayland-server/src/socket.rs index ce40c838998..1b594ab1b5e 100644 --- a/wayland-server/src/socket.rs +++ b/wayland-server/src/socket.rs @@ -15,7 +15,7 @@ use std::{ path::PathBuf, }; -use nix::fcntl::{flock, FlockArg}; +use rustix::fs::{flock, FlockOperation}; /// An utility representing a unix socket on which your compositor is listening for new clients #[derive(Debug)] @@ -91,7 +91,7 @@ impl ListeningSocket { .map_err(|_| BindError::PermissionDenied)?; // lock the lockfile - if flock(_lock.as_raw_fd(), FlockArg::LockExclusiveNonblock).is_err() { + if flock(&_lock, FlockOperation::NonBlockingLockExclusive).is_err() { return Err(BindError::AlreadyInUse); }