Skip to content

Commit

Permalink
Fix the build with the next version of libc
Browse files Browse the repository at this point in the history
The next version of libc includes some backwards-incompatible changes.

Fixes nix-rust#2342
  • Loading branch information
asomers committed Mar 22, 2024
1 parent 01cd697 commit f15530b
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ targets = [
]

[dependencies]
libc = { version = "0.2.153", features = ["extra_traits"] }
libc = { git = "https://github.com/rust-lang/libc", rev = "a0f5b4b21391252fe38b2df9310dc65e37b07d9f", features = ["extra_traits", "const-extern-fn"] }
bitflags = "2.3.1"
cfg-if = "1.0"
pin-utils = { version = "0.1.0", optional = true }
Expand Down
5 changes: 3 additions & 2 deletions src/sys/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
);
}
Expand Down Expand Up @@ -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<RawFd>) -> 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),
}
}
}
Expand Down
35 changes: 30 additions & 5 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,12 @@ fn to_exec_array<S: AsRef<CStr>>(args: &[S]) -> Vec<*const c_char> {
pub fn execv<S: AsRef<CStr>>(path: &CStr, argv: &[S]) -> Result<Infallible> {
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())
}
Expand All @@ -849,7 +854,12 @@ pub fn execve<SA: AsRef<CStr>, SE: AsRef<CStr>>(
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())
}
Expand All @@ -870,7 +880,12 @@ pub fn execvp<S: AsRef<CStr>>(
) -> Result<Infallible> {
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())
}
Expand All @@ -891,8 +906,13 @@ pub fn execvpe<SA: AsRef<CStr>, SE: AsRef<CStr>>(
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())
Expand All @@ -918,7 +938,12 @@ pub fn fexecve<SA: AsRef<CStr>, SE: AsRef<CStr>>(
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())
}
Expand Down
1 change: 0 additions & 1 deletion test/sys/test_timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down

0 comments on commit f15530b

Please sign in to comment.