From 0c643b8d3e50063ce014bb982601e27bb9da3f45 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 22 Mar 2024 14:50:56 -0600 Subject: [PATCH] Fix the build with the next version of libc The next version of libc includes some backwards-incompatible changes. Fixes #2342 --- .cirrus.yml | 4 ++-- .github/workflows/ci.yml | 2 +- Cargo.toml | 2 +- README.md | 2 +- src/sys/epoll.rs | 36 ++++++++++++++++++------------------ src/sys/select.rs | 5 +++-- src/unistd.rs | 35 ++++++++++++++++++++++++++++++----- test/sys/test_select.rs | 1 + test/sys/test_timer.rs | 1 - 9 files changed, 57 insertions(+), 31 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 1daf2c8ad1..b28439ed22 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -9,7 +9,7 @@ env: RUSTFLAGS: -D warnings RUSTDOCFLAGS: -D warnings TOOL: cargo - MSRV: 1.69.0 + MSRV: 1.71.0 ZFLAGS: # Tests that don't require executing the build binaries @@ -70,7 +70,7 @@ task: matrix: - name: Linux aarch64 arm_container: - image: rust:1.69.0 + image: rust:1.71.0 cpu: 1 env: TARGET: aarch64-unknown-linux-gnu diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed51548a7a..46bf1fc9a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ permissions: contents: read env: - MSRV: 1.69.0 + MSRV: 1.71.0 jobs: macos: diff --git a/Cargo.toml b/Cargo.toml index facd5afb09..07ddd3784c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ targets = [ ] [dependencies] -libc = { git="https://github.com/wlkrm/libc.git", branch="patched", features = ["extra_traits"] } +libc = { git="https://github.com/wlkrm/libc.git", branch="patched", features = ["extra_traits", "const-extern-fn"] } bitflags = "2.3.1" cfg-if = "1.0" pin-utils = { version = "0.1.0", optional = true } diff --git a/README.md b/README.md index fb9f84ca44..392d28469a 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ The following targets are supported by `nix`: ## Minimum Supported Rust Version (MSRV) -nix is supported on Rust 1.69 and higher. Its MSRV will not be +nix is supported on Rust 1.71 and higher. Its MSRV will not be changed in the future without bumping the major or minor version. ## Contributing diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs index ec146a8c53..b58ae7b31e 100644 --- a/src/sys/epoll.rs +++ b/src/sys/epoll.rs @@ -6,23 +6,23 @@ use std::mem; use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd}; libc_bitflags!( - pub struct EpollFlags: c_int { - EPOLLIN; - EPOLLPRI; - EPOLLOUT; - EPOLLRDNORM; - EPOLLRDBAND; - EPOLLWRNORM; - EPOLLWRBAND; - EPOLLMSG; - EPOLLERR; - EPOLLHUP; - EPOLLRDHUP; - EPOLLEXCLUSIVE; + pub struct EpollFlags: u32 { + EPOLLIN as u32; + EPOLLPRI as u32; + EPOLLOUT as u32; + EPOLLRDNORM as u32; + EPOLLRDBAND as u32; + EPOLLWRNORM as u32; + EPOLLWRBAND as u32; + EPOLLMSG as u32; + EPOLLERR as u32; + EPOLLHUP as u32; + EPOLLRDHUP as u32; + EPOLLEXCLUSIVE as u32; #[cfg(not(target_arch = "mips"))] - EPOLLWAKEUP; - EPOLLONESHOT; - EPOLLET; + EPOLLWAKEUP as u32; + EPOLLONESHOT as u32; + EPOLLET as u32; } ); @@ -51,7 +51,7 @@ impl EpollEvent { pub fn new(events: EpollFlags, data: u64) -> Self { EpollEvent { event: libc::epoll_event { - events: events.bits() as u32, + events: events.bits(), u64: data, }, } @@ -62,7 +62,7 @@ impl EpollEvent { } pub fn events(&self) -> EpollFlags { - EpollFlags::from_bits(self.event.events as c_int).unwrap() + EpollFlags::from_bits(self.event.events).unwrap() } pub fn data(&self) -> u64 { diff --git a/src/sys/select.rs b/src/sys/select.rs index 64a8e258cf..16b3d8ea98 100644 --- a/src/sys/select.rs +++ b/src/sys/select.rs @@ -22,7 +22,7 @@ pub struct FdSet<'fd> { fn assert_fd_valid(fd: RawFd) { assert!( - usize::try_from(fd).map_or(false, |fd| fd < FD_SETSIZE), + fd < RawFd::try_from(FD_SETSIZE).unwrap_or(RawFd::min_value()), "fd must be in the range 0..FD_SETSIZE", ); } @@ -107,10 +107,11 @@ impl<'fd> FdSet<'fd> { /// assert_eq!(fds, vec![4, 9]); /// ``` #[inline] + #[allow(clippy::unnecessary_cast)] // Not unnecessary with libc 0.2.154+ pub fn fds(&self, highest: Option) -> Fds { Fds { set: self, - range: 0..highest.map(|h| h as usize + 1).unwrap_or(FD_SETSIZE), + range: 0..highest.map(|h| h as usize + 1).unwrap_or(FD_SETSIZE as usize), } } } diff --git a/src/unistd.rs b/src/unistd.rs index 58ede6eb9b..6976ada2a3 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -823,7 +823,12 @@ fn to_exec_array>(args: &[S]) -> Vec<*const c_char> { pub fn execv>(path: &CStr, argv: &[S]) -> Result { let args_p = to_exec_array(argv); - unsafe { libc::execv(path.as_ptr(), args_p.as_ptr()) }; + // SAFETY: + // The const cast looks unsafe. But it's actually fine. The problem is that POSIX requires + // "execv" and friends to take mutable pointers in their signatures, even while it prohibits + // them from actually modifying those arguments. See discussion at + // https://github.com/rust-lang/libc/issues/1272 . + unsafe { libc::execv(path.as_ptr(), args_p.as_ptr() as *const _) }; Err(Errno::last()) } @@ -849,7 +854,12 @@ pub fn execve, SE: AsRef>( let args_p = to_exec_array(args); let env_p = to_exec_array(env); - unsafe { libc::execve(path.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) }; + // SAFETY: + // The const cast looks unsafe. But it's actually fine. The problem is that POSIX requires + // "execv" and friends to take mutable pointers in their signatures, even while it prohibits + // them from actually modifying those arguments. See discussion at + // https://github.com/rust-lang/libc/issues/1272 . + unsafe { libc::execve(path.as_ptr(), args_p.as_ptr() as *const _, env_p.as_ptr() as *const _) }; Err(Errno::last()) } @@ -870,7 +880,12 @@ pub fn execvp>( ) -> Result { let args_p = to_exec_array(args); - unsafe { libc::execvp(filename.as_ptr(), args_p.as_ptr()) }; + // SAFETY: + // The const cast looks unsafe. But it's actually fine. The problem is that POSIX requires + // "execv" and friends to take mutable pointers in their signatures, even while it prohibits + // them from actually modifying those arguments. See discussion at + // https://github.com/rust-lang/libc/issues/1272 . + unsafe { libc::execvp(filename.as_ptr(), args_p.as_ptr() as *const _) }; Err(Errno::last()) } @@ -891,8 +906,13 @@ pub fn execvpe, SE: AsRef>( let args_p = to_exec_array(args); let env_p = to_exec_array(env); + // SAFETY: + // The const cast looks unsafe. But it's actually fine. The problem is that POSIX requires + // "execv" and friends to take mutable pointers in their signatures, even while it prohibits + // them from actually modifying those arguments. See discussion at + // https://github.com/rust-lang/libc/issues/1272 . unsafe { - libc::execvpe(filename.as_ptr(), args_p.as_ptr(), env_p.as_ptr()) + libc::execvpe(filename.as_ptr(), args_p.as_ptr() as *const _, env_p.as_ptr() as *const _) }; Err(Errno::last()) @@ -918,7 +938,12 @@ pub fn fexecve, SE: AsRef>( let args_p = to_exec_array(args); let env_p = to_exec_array(env); - unsafe { libc::fexecve(fd, args_p.as_ptr(), env_p.as_ptr()) }; + // SAFETY: + // The const cast looks unsafe. But it's actually fine. The problem is that POSIX requires + // "execv" and friends to take mutable pointers in their signatures, even while it prohibits + // them from actually modifying those arguments. See discussion at + // https://github.com/rust-lang/libc/issues/1272 . + unsafe { libc::fexecve(fd, args_p.as_ptr() as *const _, env_p.as_ptr() as *const _) }; Err(Errno::last()) } diff --git a/test/sys/test_select.rs b/test/sys/test_select.rs index e39a31923a..f07a0503ad 100644 --- a/test/sys/test_select.rs +++ b/test/sys/test_select.rs @@ -66,6 +66,7 @@ macro_rules! generate_fdset_bad_fd_tests { } } +#[allow(clippy::useless_conversion)] // Not unnecessary with libc 0.2.153 mod test_fdset_too_large_fd { use super::*; generate_fdset_bad_fd_tests!( diff --git a/test/sys/test_timer.rs b/test/sys/test_timer.rs index ffd146867b..c18876fc78 100644 --- a/test/sys/test_timer.rs +++ b/test/sys/test_timer.rs @@ -4,7 +4,6 @@ use nix::sys::signal::{ }; use nix::sys::timer::{Expiration, Timer, TimerSetTimeFlags}; use nix::time::ClockId; -use std::convert::TryFrom; use std::sync::atomic::{AtomicBool, Ordering}; use std::thread; use std::time::{Duration, Instant};