From 4de694a4067a1710157af6dffbec89f7e678cda0 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Mon, 28 Nov 2022 23:10:27 -0600 Subject: [PATCH 01/24] Reset changelog --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77d5b2a326..c5625df2f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). +## [Unreleased] - ReleaseDate +### Added + +### Changed + +### Fixed + +### Removed + ## [0.23.1] - 2021-12-16 ### Added From d7e073ff0c862a1a392ea73eb88fe5953869ec55 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Sun, 23 Jan 2022 13:20:19 -0600 Subject: [PATCH 02/24] InetAddr::from_std should set sin_len/sin6_len on the BSDs --- CHANGELOG.md | 3 +++ src/sys/socket/addr.rs | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5625df2f9..7dcb1746b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). ### Fixed +- `InetAddr::from_std` now sets the `sin_len`/`sin6_len` fields on the BSDs. + (#[1642](https://github.com/nix-rust/nix/pull/1642)) + ### Removed ## [0.23.1] - 2021-12-16 diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index b119642b3f..2be8c41529 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -275,6 +275,11 @@ impl InetAddr { match *std { net::SocketAddr::V4(ref addr) => { InetAddr::V4(libc::sockaddr_in { + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "hermit", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + sin_len: mem::size_of::() as u8, sin_family: AddressFamily::Inet as sa_family_t, sin_port: addr.port().to_be(), // network byte order sin_addr: Ipv4Addr::from_std(addr.ip()).0, @@ -283,6 +288,11 @@ impl InetAddr { } net::SocketAddr::V6(ref addr) => { InetAddr::V6(libc::sockaddr_in6 { + #[cfg(any(target_os = "dragonfly", target_os = "freebsd", + target_os = "haiku", target_os = "hermit", + target_os = "ios", target_os = "macos", + target_os = "netbsd", target_os = "openbsd"))] + sin6_len: mem::size_of::() as u8, sin6_family: AddressFamily::Inet6 as sa_family_t, sin6_port: addr.port().to_be(), // network byte order sin6_addr: Ipv6Addr::from_std(addr.ip()).0, From 1d437d96a82b8a90192a1f078dabdca873ee1a92 Mon Sep 17 00:00:00 2001 From: "S.J.R. van Schaik" Date: Thu, 18 Aug 2022 21:49:14 -0400 Subject: [PATCH 03/24] fix microsecond calculation for TimeSpec --- CHANGELOG.md | 2 ++ src/sys/time.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dcb1746b3..a21feda508 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). - `InetAddr::from_std` now sets the `sin_len`/`sin6_len` fields on the BSDs. (#[1642](https://github.com/nix-rust/nix/pull/1642)) +- Fix microsecond calculation for `TimeSpec`. + ([#1801](https://github.com/nix-rust/nix/pull/1801)) ### Removed diff --git a/src/sys/time.rs b/src/sys/time.rs index ac4247180d..ece5fdf1e4 100644 --- a/src/sys/time.rs +++ b/src/sys/time.rs @@ -167,7 +167,7 @@ impl TimeValLike for TimeSpec { } fn num_microseconds(&self) -> i64 { - self.num_nanoseconds() / 1_000_000_000 + self.num_nanoseconds() / 1_000 } fn num_nanoseconds(&self) -> i64 { From 450279945f468c641b7cfaeadc429e8eb34782e6 Mon Sep 17 00:00:00 2001 From: WATANABE Yuki Date: Sun, 11 Sep 2022 23:01:08 +0900 Subject: [PATCH 04/24] Handle unacceptable name gracefully in {User,Group}::from_name Calling `unwrap` on the result of `CString::new` may cause the current thread to panic, which is a bit surprising undocumented behavior. It would be more reasonable to treat the erroneous name as a non-existing user or group. --- CHANGELOG.md | 3 +++ src/unistd.rs | 10 ++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a21feda508..7fcdf918c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). (#[1642](https://github.com/nix-rust/nix/pull/1642)) - Fix microsecond calculation for `TimeSpec`. ([#1801](https://github.com/nix-rust/nix/pull/1801)) +- Fix `User::from_name` and `Group::from_name` panicking + when given a name containing a nul. + ([#1815](https://github.com/nix-rust/nix/pull/1815)) ### Removed diff --git a/src/unistd.rs b/src/unistd.rs index 2c89d77240..097eed56f1 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2823,7 +2823,10 @@ impl User { /// assert!(res.name == "root"); /// ``` pub fn from_name(name: &str) -> Result> { - let name = CString::new(name).unwrap(); + let name = match CString::new(name) { + Ok(c_str) => c_str, + Err(_nul_error) => return Ok(None), + }; User::from_anything(|pwd, cbuf, cap, res| { unsafe { libc::getpwnam_r(name.as_ptr(), pwd, cbuf, cap, res) } }) @@ -2948,7 +2951,10 @@ impl Group { /// assert!(res.name == "root"); /// ``` pub fn from_name(name: &str) -> Result> { - let name = CString::new(name).unwrap(); + let name = match CString::new(name) { + Ok(c_str) => c_str, + Err(_nul_error) => return Ok(None), + }; Group::from_anything(|grp, cbuf, cap, res| { unsafe { libc::getgrnam_r(name.as_ptr(), grp, cbuf, cap, res) } }) From b9fa51f0e4d230d44846e61f79d2e44980ba40e1 Mon Sep 17 00:00:00 2001 From: wdsgyj Date: Sun, 25 Sep 2022 02:17:51 +0800 Subject: [PATCH 05/24] fix crash on Android platform --- CHANGELOG.md | 2 ++ src/unistd.rs | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fcdf918c2..09af9e3763 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Fix `User::from_name` and `Group::from_name` panicking when given a name containing a nul. ([#1815](https://github.com/nix-rust/nix/pull/1815)) +- Fix `User::from_uid` and `User::from_name` crash on Android platform. + ([#1824](https://github.com/nix-rust/nix/pull/1824)) ### Removed diff --git a/src/unistd.rs b/src/unistd.rs index 097eed56f1..7b4fc090e2 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2670,14 +2670,14 @@ impl From<&libc::passwd> for User { fn from(pw: &libc::passwd) -> User { unsafe { User { - name: CStr::from_ptr((*pw).pw_name).to_string_lossy().into_owned(), - passwd: CString::new(CStr::from_ptr((*pw).pw_passwd).to_bytes()).unwrap(), + name: if pw.pw_name.is_null() { Default::default() } else { CStr::from_ptr(pw.pw_name).to_string_lossy().into_owned() }, + passwd: if pw.pw_passwd.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_passwd).to_bytes()).unwrap() }, #[cfg(not(all(target_os = "android", target_pointer_width = "32")))] - gecos: CString::new(CStr::from_ptr((*pw).pw_gecos).to_bytes()).unwrap(), - dir: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_dir).to_bytes())), - shell: PathBuf::from(OsStr::from_bytes(CStr::from_ptr((*pw).pw_shell).to_bytes())), - uid: Uid::from_raw((*pw).pw_uid), - gid: Gid::from_raw((*pw).pw_gid), + gecos: if pw.pw_gecos.is_null() { Default::default() } else { CString::new(CStr::from_ptr(pw.pw_gecos).to_bytes()).unwrap() }, + dir: if pw.pw_dir.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_dir).to_bytes())) }, + shell: if pw.pw_shell.is_null() { Default::default() } else { PathBuf::from(OsStr::from_bytes(CStr::from_ptr(pw.pw_shell).to_bytes())) }, + uid: Uid::from_raw(pw.pw_uid), + gid: Gid::from_raw(pw.pw_gid), #[cfg(not(any(target_os = "android", target_os = "fuchsia", target_os = "illumos", From 3cda267c79cee3f33ec2c34c41d0071ca097cae7 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Thu, 15 Sep 2022 14:58:56 -0600 Subject: [PATCH 06/24] Fix UB in the SO_TYPE sockopt When reading a value into an enum from getsockopt, we must validate it. Failing to do so can lead to UB for example with SOCK_PACKET on Linux. Perform the validation in GetSockOpt::get. Currently SockType is the only type that requires validation. Fixes #1819 --- CHANGELOG.md | 2 ++ src/sys/socket/mod.rs | 19 +++++++++++++++++++ src/sys/socket/sockopt.rs | 8 ++++++-- test/sys/test_sockopt.rs | 27 +++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09af9e3763..e36e41fc6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). ([#1815](https://github.com/nix-rust/nix/pull/1815)) - Fix `User::from_uid` and `User::from_name` crash on Android platform. ([#1824](https://github.com/nix-rust/nix/pull/1824)) +- Fix UB with `sys::socket::sockopt::SockType` using `SOCK_PACKET`. + ([#1821](https://github.com/nix-rust/nix/pull/1821)) ### Removed diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 97eea3dcb1..d679e89d71 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -6,6 +6,7 @@ use crate::{Result, errno::Errno}; use libc::{self, c_void, c_int, iovec, socklen_t, size_t, CMSG_FIRSTHDR, CMSG_NXTHDR, CMSG_DATA, CMSG_LEN}; use memoffset::offset_of; +use std::convert::TryFrom; use std::{mem, ptr, slice}; use std::os::unix::io::RawFd; #[cfg(all(target_os = "linux"))] @@ -91,6 +92,24 @@ pub enum SockType { /// guarantee ordering. Rdm = libc::SOCK_RDM, } +// The TryFrom impl could've been derived using libc_enum!. But for +// backwards-compatibility with Nix-0.25.0 we manually implement it, so as to +// keep the old variant names. +impl TryFrom for SockType { + type Error = crate::Error; + + fn try_from(x: i32) -> Result { + match x { + libc::SOCK_STREAM => Ok(Self::Stream), + libc::SOCK_DGRAM => Ok(Self::Datagram), + libc::SOCK_SEQPACKET => Ok(Self::SeqPacket), + libc::SOCK_RAW => Ok(Self::Raw), + #[cfg(not(any(target_os = "haiku")))] + libc::SOCK_RDM => Ok(Self::Rdm), + _ => Err(Errno::EINVAL) + } + } +} /// Constants used in [`socket`](fn.socket.html) and [`socketpair`](fn.socketpair.html) /// to specify the protocol to use. diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index fcb4be81be..26c1e0cbe0 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -5,6 +5,7 @@ use crate::Result; use crate::errno::Errno; use crate::sys::time::TimeVal; use libc::{self, c_int, c_void, socklen_t}; +use std::convert::TryFrom; use std::mem::{ self, MaybeUninit @@ -96,7 +97,10 @@ macro_rules! getsockopt_impl { getter.ffi_len()); Errno::result(res)?; - Ok(getter.assume_init()) + match <$ty>::try_from(getter.assume_init()) { + Err(_) => Err(Errno::EINVAL), + Ok(r) => Ok(r) + } } } } @@ -413,7 +417,7 @@ sockopt_impl!( SndBufForce, SetOnly, libc::SOL_SOCKET, libc::SO_SNDBUFFORCE, usize); sockopt_impl!( /// Gets the socket type as an integer. - SockType, GetOnly, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType); + SockType, GetOnly, libc::SOL_SOCKET, libc::SO_TYPE, super::SockType, GetStruct); sockopt_impl!( /// Returns a value indicating whether or not this socket has been marked to /// accept connections with `listen(2)`. diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 01920fd40a..0a8761e07d 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -121,6 +121,33 @@ fn test_so_tcp_maxseg() { close(ssock).unwrap(); } +#[test] +fn test_so_type() { + let sockfd = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + + assert_eq!(Ok(SockType::Stream), getsockopt(sockfd, sockopt::SockType)); +} + +/// getsockopt(_, sockopt::SockType) should gracefully handle unknown socket +/// types. Regression test for https://github.com/nix-rust/nix/issues/1819 +#[cfg(any(target_os = "android", target_os = "linux",))] +#[test] +fn test_so_type_unknown() { + use nix::errno::Errno; + + require_capability!("test_so_type", CAP_NET_RAW); + let sockfd = unsafe { libc::socket(libc::AF_PACKET, libc::SOCK_PACKET, 0) }; + assert!(sockfd >= 0, "Error opening socket: {}", nix::Error::last()); + + assert_eq!(Err(Errno::EINVAL), getsockopt(sockfd, sockopt::SockType)); +} + // The CI doesn't supported getsockopt and setsockopt on emulated processors. // It's beleived that a QEMU issue, the tests run ok on a fully emulated system. // Current CI just run the binary with QEMU but the Kernel remains the same as the host. From 89d46d518613e24713767e26bc5ba356232bf6d3 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 1 Dec 2022 19:07:11 -0500 Subject: [PATCH 07/24] Update use of libc::timespec to prepare for future libc version This is a backport of 006fc6f7975b3a6b64329847b780622aab392109. The original commit message follows: In a future release of the `libc` crate, `libc::timespec` will contain private padding fields on `*-linux-musl` targets and so the struct will no longer be able to be created using the literal initialization syntax. Update places where `libc::timespec` is created to first zero initialize the value and then update the `tv_sec` and `tv_nsec` fields manually. Many of these places are in `const fn`s so a helper function `zero_init_timespec()` is introduced to help with this as `std::mem::MaybeUninit::zeroed()` is not a `const` function. Some matches on `libc::timespec` are also updated to include a trailing `..` pattern which works when `libc::timespec` has additional, private fields as well as when it does not (like for `x86_64-unknown-linux-gnu`). --- src/sys/time.rs | 32 ++++++++++++++++++++++---------- src/sys/timerfd.rs | 18 +++++------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/sys/time.rs b/src/sys/time.rs index ece5fdf1e4..a4f4131fc7 100644 --- a/src/sys/time.rs +++ b/src/sys/time.rs @@ -5,6 +5,10 @@ use libc::{timespec, timeval}; #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 pub use libc::{time_t, suseconds_t}; +pub(crate) const TIMESPEC_ZERO: libc::timespec = unsafe { + std::mem::transmute([0u8; std::mem::size_of::()]) +}; + pub trait TimeValLike: Sized { #[inline] fn zero() -> Self { @@ -119,11 +123,15 @@ impl PartialOrd for TimeSpec { impl TimeValLike for TimeSpec { #[inline] + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 fn seconds(seconds: i64) -> TimeSpec { assert!(seconds >= TS_MIN_SECONDS && seconds <= TS_MAX_SECONDS, "TimeSpec out of bounds; seconds={}", seconds); - #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 - TimeSpec(timespec {tv_sec: seconds as time_t, tv_nsec: 0 }) + let mut ts = TIMESPEC_ZERO; + ts.tv_sec = seconds as time_t; + ts.tv_nsec = 0; + TimeSpec(ts) } #[inline] @@ -145,13 +153,16 @@ impl TimeValLike for TimeSpec { /// Makes a new `TimeSpec` with given number of nanoseconds. #[inline] + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 fn nanoseconds(nanoseconds: i64) -> TimeSpec { let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC); assert!(secs >= TS_MIN_SECONDS && secs <= TS_MAX_SECONDS, "TimeSpec out of bounds"); - #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 - TimeSpec(timespec {tv_sec: secs as time_t, - tv_nsec: nanos as timespec_tv_nsec_t }) + let mut ts = TIMESPEC_ZERO; + ts.tv_sec = secs as time_t; + ts.tv_nsec = nanos as timespec_tv_nsec_t; + TimeSpec(ts) } fn num_seconds(&self) -> i64 { @@ -195,12 +206,13 @@ impl TimeSpec { self.0.tv_nsec } + #[cfg_attr(target_env = "musl", allow(deprecated))] + // https://github.com/rust-lang/libc/issues/1848 pub const fn from_duration(duration: Duration) -> Self { - #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 - TimeSpec(timespec { - tv_sec: duration.as_secs() as time_t, - tv_nsec: duration.subsec_nanos() as timespec_tv_nsec_t - }) + let mut ts = TIMESPEC_ZERO; + ts.tv_sec = duration.as_secs() as time_t; + ts.tv_nsec = duration.subsec_nanos() as timespec_tv_nsec_t; + TimeSpec(ts) } pub const fn from_timespec(timespec: timespec) -> Self { diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs index 705a3c4d65..d02c23a6b9 100644 --- a/src/sys/timerfd.rs +++ b/src/sys/timerfd.rs @@ -28,7 +28,7 @@ //! // We wait for the timer to expire. //! timer.wait().unwrap(); //! ``` -use crate::sys::time::TimeSpec; +use crate::sys::time::{TIMESPEC_ZERO, TimeSpec}; use crate::unistd::read; use crate::{errno::Errno, Result}; use bitflags::bitflags; @@ -90,14 +90,8 @@ struct TimerSpec(libc::itimerspec); impl TimerSpec { pub const fn none() -> Self { Self(libc::itimerspec { - it_interval: libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }, - it_value: libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }, + it_interval: TIMESPEC_ZERO, + it_value: TIMESPEC_ZERO, }) } } @@ -112,10 +106,7 @@ impl From for TimerSpec { fn from(expiration: Expiration) -> TimerSpec { match expiration { Expiration::OneShot(t) => TimerSpec(libc::itimerspec { - it_interval: libc::timespec { - tv_sec: 0, - tv_nsec: 0, - }, + it_interval: TIMESPEC_ZERO, it_value: *t.as_ref(), }), Expiration::IntervalDelayed(start, interval) => TimerSpec(libc::itimerspec { @@ -138,6 +129,7 @@ impl From for Expiration { libc::timespec { tv_sec: 0, tv_nsec: 0, + .. }, it_value: ts, }) => Expiration::OneShot(ts.into()), From 92acb4a77b0ef4aa6d428e350c5ff9f974de2d41 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Sat, 25 Jun 2022 21:27:15 -0500 Subject: [PATCH 08/24] Pin cross to 0.2.1, as 0.2.2 requires Rust 1.58.1 --- .cirrus.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cirrus.yml b/.cirrus.yml index 8d6e121020..fe16ad7cdb 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -116,7 +116,7 @@ task: - curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs - sh rustup.sh -y --profile=minimal --default-toolchain $TOOLCHAIN - . $HOME/.cargo/env - - cargo install cross + - cargo install cross --version 0.2.1 # cross 0.2.2 bumped the MSRV to 1.58.1 - cp Cargo.lock.msrv Cargo.lock << : *TEST before_cache_script: rm -rf $CARGO_HOME/registry/index From 3108e46c368906e8cd5849f1a726deebf355481d Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 13 May 2022 19:02:58 -0600 Subject: [PATCH 09/24] Fix "unused_macro_rules" warnings with the latest nightly compiler. It just so happens that Redox, OpenBSD, Dragonfly, and uclibc don't use some of the rules for two internal macros. --- src/macros.rs | 3 +++ src/sys/socket/sockopt.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/macros.rs b/src/macros.rs index 3ccbfdd43b..d64d60ea6f 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -80,6 +80,9 @@ macro_rules! libc_bitflags { /// } /// } /// ``` +// Some targets don't use all rules. +#[allow(unknown_lints)] +#[allow(unused_macro_rules)] macro_rules! libc_enum { // Exit rule. (@make_enum diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 26c1e0cbe0..c24effe10e 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -132,6 +132,9 @@ macro_rules! getsockopt_impl { /// * `$ty:ty`: type of the value that will be get/set. /// * `$getter:ty`: `Get` implementation; optional; only for `GetOnly` and `Both`. /// * `$setter:ty`: `Set` implementation; optional; only for `SetOnly` and `Both`. +// Some targets don't use all rules. +#[allow(unknown_lints)] +#[allow(unused_macro_rules)] macro_rules! sockopt_impl { ($(#[$attr:meta])* $name:ident, GetOnly, $level:expr, $flag:path, bool) => { sockopt_impl!($(#[$attr])* From b708d02024ea5b59af2d7cc6a2918784919ea9a5 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 29 May 2022 14:00:48 -0600 Subject: [PATCH 10/24] Clippy cleanup for latest nightly --- src/sys/timerfd.rs | 2 +- src/unistd.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sys/timerfd.rs b/src/sys/timerfd.rs index d02c23a6b9..4df3c34866 100644 --- a/src/sys/timerfd.rs +++ b/src/sys/timerfd.rs @@ -149,7 +149,7 @@ impl From for Expiration { /// An enumeration allowing the definition of the expiration time of an alarm, /// recurring or not. -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum Expiration { OneShot(TimeSpec), IntervalDelayed(TimeSpec, TimeSpec), diff --git a/src/unistd.rs b/src/unistd.rs index 7b4fc090e2..43e798dac9 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2625,7 +2625,7 @@ pub fn access(path: &P, amode: AccessFlags) -> Result<()> { /// guaranteed to conform to [`NAME_REGEX`](https://serverfault.com/a/73101/407341), which only /// contains ASCII. #[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq)] pub struct User { /// Username pub name: String, @@ -2835,7 +2835,7 @@ impl User { /// Representation of a Group, based on `libc::group` #[cfg(not(target_os = "redox"))] // RedoxFS does not support passwd -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq)] pub struct Group { /// Group name pub name: String, From a9130d0802be836e1f5fbfe46f487d51ed9a0dc5 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 11 Sep 2022 16:25:33 -0600 Subject: [PATCH 11/24] Clippy cleanup --- src/sys/socket/mod.rs | 2 +- src/sys/socket/sockopt.rs | 2 +- test/test_fcntl.rs | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index d679e89d71..e58820453c 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1177,7 +1177,7 @@ pub fn sendmsg(fd: RawFd, iov: &[IoVec<&[u8]>], cmsgs: &[ControlMessage], // because subsequent code will not clear the padding bytes. let mut cmsg_buffer = vec![0u8; capacity]; - let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], &iov, &cmsgs, addr); + let mhdr = pack_mhdr_to_send(&mut cmsg_buffer[..], iov, cmsgs, addr); let ret = unsafe { libc::sendmsg(fd, &mhdr, flags.bits()) }; diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index c24effe10e..8a6304ff7e 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -725,7 +725,7 @@ struct SetBool { impl<'a> Set<'a, bool> for SetBool { fn new(val: &'a bool) -> SetBool { - SetBool { val: if *val { 1 } else { 0 } } + SetBool { val: i32::from(*val) } } fn ffi_ptr(&self) -> *const c_void { diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index db2acfbf52..374f221688 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -201,10 +201,8 @@ fn test_readlink() { let src = tempdir.path().join("a"); let dst = tempdir.path().join("b"); println!("a: {:?}, b: {:?}", &src, &dst); - fs::symlink(&src.as_path(), &dst.as_path()).unwrap(); - let dirfd = open(tempdir.path(), - OFlag::empty(), - Mode::empty()).unwrap(); + fs::symlink(src.as_path(), dst.as_path()).unwrap(); + let dirfd = open(tempdir.path(), OFlag::empty(), Mode::empty()).unwrap(); let expected_dir = src.to_str().unwrap(); assert_eq!(readlink(&dst).unwrap().to_str().unwrap(), expected_dir); From 101a187fa7fcc7e418c4909368976dd476ebece3 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Sat, 8 Oct 2022 13:48:59 -0500 Subject: [PATCH 12/24] Fix clippy warnings on nightly Clippy is now smarter about detecting unnecessary casts and useless conversions, which means we need to be more explicit about when the conversions are needed for a subset of platforms. Required changes found by repeatedly running the following command against a list of the supported platforms. `xargs -t -I {} sh -c "cargo clippy -Zbuild-std --target {} --all-targets -- -D warnings || exit 255"` I removed the casts it complained about, and then restored them with an `#[allow]` if a later target needed the cast. . --- src/dir.rs | 4 ++++ src/errno.rs | 4 +--- src/sys/pthread.rs | 1 + src/sys/socket/addr.rs | 12 ++++++------ src/sys/socket/mod.rs | 18 ++++++++++++------ src/sys/socket/sockopt.rs | 2 +- src/sys/statfs.rs | 4 ++++ src/sys/sysinfo.rs | 4 ++++ src/sys/termios.rs | 4 ++++ src/sys/time.rs | 18 +++++++++++++----- src/sys/uio.rs | 2 +- src/unistd.rs | 14 +++++++------- test/sys/test_ioctl.rs | 8 ++++++++ test/sys/test_stat.rs | 29 +++++++++++++++++++++++++++++ test/test_mount.rs | 19 +++++++++++++++---- 15 files changed, 110 insertions(+), 33 deletions(-) create mode 100644 test/sys/test_stat.rs diff --git a/src/dir.rs b/src/dir.rs index ed70a458ac..b27fb70425 100644 --- a/src/dir.rs +++ b/src/dir.rs @@ -186,6 +186,8 @@ pub enum Type { impl Entry { /// Returns the inode number (`d_ino`) of the underlying `dirent`. + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] #[cfg(any(target_os = "android", target_os = "emscripten", target_os = "fuchsia", @@ -212,6 +214,8 @@ impl Entry { target_os = "macos", target_os = "solaris")))] #[allow(clippy::useless_conversion)] // Not useless on all OSes + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] pub fn ino(&self) -> u64 { u64::from(self.0.d_fileno) } diff --git a/src/errno.rs b/src/errno.rs index 3da246e823..d5f644305b 100644 --- a/src/errno.rs +++ b/src/errno.rs @@ -43,9 +43,7 @@ fn clear() { /// Returns the platform-specific value of errno pub fn errno() -> i32 { - unsafe { - (*errno_location()) as i32 - } + unsafe { *errno_location() } } impl Errno { diff --git a/src/sys/pthread.rs b/src/sys/pthread.rs index d42e45d13d..1636ba8f03 100644 --- a/src/sys/pthread.rs +++ b/src/sys/pthread.rs @@ -27,6 +27,7 @@ pub fn pthread_self() -> Pthread { /// won't send any signal. /// /// [`pthread_kill(3)`]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_kill.html +#[allow(clippy::not_unsafe_ptr_arg_deref)] #[cfg(not(target_os = "redox"))] pub fn pthread_kill>>(thread: Pthread, signal: T) -> Result<()> { let sig = match signal.into() { diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index 2be8c41529..4ef435d041 100644 --- a/src/sys/socket/addr.rs +++ b/src/sys/socket/addr.rs @@ -1185,12 +1185,12 @@ mod datalink { /// Physical-layer address (MAC) pub fn addr(&self) -> [u8; 6] { [ - self.0.sll_addr[0] as u8, - self.0.sll_addr[1] as u8, - self.0.sll_addr[2] as u8, - self.0.sll_addr[3] as u8, - self.0.sll_addr[4] as u8, - self.0.sll_addr[5] as u8, + self.0.sll_addr[0], + self.0.sll_addr[1], + self.0.sll_addr[2], + self.0.sll_addr[3], + self.0.sll_addr[4], + self.0.sll_addr[5], ] } } diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index e58820453c..badb6632c5 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -698,6 +698,8 @@ impl ControlMessageOwned { unsafe fn decode_from(header: &cmsghdr) -> ControlMessageOwned { let p = CMSG_DATA(header); + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] let len = header as *const _ as usize + header.cmsg_len as usize - p as usize; match (header.cmsg_level, header.cmsg_type) { @@ -1358,7 +1360,7 @@ pub fn recvmmsg<'a, I>( } ); - (msg_controllen as usize, &mut d.cmsg_buffer) + (msg_controllen, &mut d.cmsg_buffer) }).collect(); let timeout = if let Some(mut t) = timeout { @@ -1377,6 +1379,8 @@ pub fn recvmmsg<'a, I>( .zip(addresses.iter().map(|addr| unsafe{addr.assume_init()})) .zip(results.into_iter()) .map(|((mmsghdr, address), (msg_controllen, cmsg_buffer))| { + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] unsafe { read_mhdr( mmsghdr.msg_hdr, @@ -1395,8 +1399,10 @@ unsafe fn read_mhdr<'a, 'b>( r: isize, msg_controllen: usize, address: sockaddr_storage, - cmsg_buffer: &'a mut Option<&'b mut Vec> -) -> RecvMsg<'b> { + cmsg_buffer: &mut Option<&'a mut Vec> +) -> RecvMsg<'a> { + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] let cmsghdr = { if mhdr.msg_controllen > 0 { // got control message(s) @@ -1538,7 +1544,7 @@ pub fn recvmsg<'a>(fd: RawFd, iov: &[IoVec<&mut [u8]>], let mut address = mem::MaybeUninit::uninit(); let (msg_controllen, mut mhdr) = unsafe { - pack_mhdr_to_receive(&iov, &mut cmsg_buffer, address.as_mut_ptr()) + pack_mhdr_to_receive(iov, &mut cmsg_buffer, address.as_mut_ptr()) }; let ret = unsafe { libc::recvmsg(fd, &mut mhdr, flags.bits()) }; @@ -1838,14 +1844,14 @@ pub fn sockaddr_storage_to_addr( match c_int::from(addr.ss_family) { libc::AF_INET => { - assert!(len as usize >= mem::size_of::()); + assert!(len >= mem::size_of::()); let sin = unsafe { *(addr as *const sockaddr_storage as *const sockaddr_in) }; Ok(SockAddr::Inet(InetAddr::V4(sin))) } libc::AF_INET6 => { - assert!(len as usize >= mem::size_of::()); + assert!(len >= mem::size_of::()); let sin6 = unsafe { *(addr as *const _ as *const sockaddr_in6) }; diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index 8a6304ff7e..efb9c54500 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -772,7 +772,7 @@ struct SetU8 { impl<'a> Set<'a, u8> for SetU8 { fn new(val: &'a u8) -> SetU8 { - SetU8 { val: *val as u8 } + SetU8 { val: *val } } fn ffi_ptr(&self) -> *const c_void { diff --git a/src/sys/statfs.rs b/src/sys/statfs.rs index 829be57f63..18f0820ea9 100644 --- a/src/sys/statfs.rs +++ b/src/sys/statfs.rs @@ -564,6 +564,8 @@ mod test { assert_fs_equals(fs, vfs); } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] fn assert_fs_equals(fs: Statfs, vfs: Statvfs) { assert_eq!(fs.files() as u64, vfs.files() as u64); assert_eq!(fs.blocks() as u64, vfs.blocks() as u64); @@ -611,6 +613,8 @@ mod test { assert_fs_equals_strict(fs.unwrap(), vfs.unwrap()) } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] fn assert_fs_equals_strict(fs: Statfs, vfs: Statvfs) { assert_eq!(fs.files_free() as u64, vfs.files_free() as u64); assert_eq!(fs.blocks_free() as u64, vfs.blocks_free() as u64); diff --git a/src/sys/sysinfo.rs b/src/sys/sysinfo.rs index dc943c1adc..56d8e0a3db 100644 --- a/src/sys/sysinfo.rs +++ b/src/sys/sysinfo.rs @@ -30,6 +30,8 @@ impl SysInfo { } /// Returns the time since system boot. + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] pub fn uptime(&self) -> Duration { // Truncate negative values to 0 Duration::from_secs(cmp::max(self.0.uptime, 0) as u64) @@ -64,6 +66,8 @@ impl SysInfo { self.scale_mem(self.0.freeram) } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] fn scale_mem(&self, units: mem_blocks_t) -> u64 { units as u64 * self.0.mem_unit as u64 } diff --git a/src/sys/termios.rs b/src/sys/termios.rs index 01d4608039..dcc7b2b8a3 100644 --- a/src/sys/termios.rs +++ b/src/sys/termios.rs @@ -804,6 +804,8 @@ cfg_if!{ /// [cfgetispeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)). /// /// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure. + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] pub fn cfgetispeed(termios: &Termios) -> u32 { let inner_termios = termios.get_libc_termios(); unsafe { libc::cfgetispeed(&*inner_termios) as u32 } @@ -813,6 +815,8 @@ cfg_if!{ /// [cfgetospeed(3p)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetospeed.html)). /// /// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure. + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] pub fn cfgetospeed(termios: &Termios) -> u32 { let inner_termios = termios.get_libc_termios(); unsafe { libc::cfgetospeed(&*inner_termios) as u32 } diff --git a/src/sys/time.rs b/src/sys/time.rs index a4f4131fc7..6cf567ec36 100644 --- a/src/sys/time.rs +++ b/src/sys/time.rs @@ -126,7 +126,7 @@ impl TimeValLike for TimeSpec { #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 fn seconds(seconds: i64) -> TimeSpec { - assert!(seconds >= TS_MIN_SECONDS && seconds <= TS_MAX_SECONDS, + assert!((TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&seconds), "TimeSpec out of bounds; seconds={}", seconds); let mut ts = TIMESPEC_ZERO; ts.tv_sec = seconds as time_t; @@ -157,7 +157,7 @@ impl TimeValLike for TimeSpec { // https://github.com/rust-lang/libc/issues/1848 fn nanoseconds(nanoseconds: i64) -> TimeSpec { let (secs, nanos) = div_mod_floor_64(nanoseconds, NANOS_PER_SEC); - assert!(secs >= TS_MIN_SECONDS && secs <= TS_MAX_SECONDS, + assert!((TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs), "TimeSpec out of bounds"); let mut ts = TIMESPEC_ZERO; ts.tv_sec = secs as time_t; @@ -165,6 +165,8 @@ impl TimeValLike for TimeSpec { TimeSpec(ts) } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] fn num_seconds(&self) -> i64 { if self.tv_sec() < 0 && self.tv_nsec() > 0 { (self.tv_sec() + 1) as i64 @@ -181,6 +183,8 @@ impl TimeValLike for TimeSpec { self.num_nanoseconds() / 1_000 } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] fn num_nanoseconds(&self) -> i64 { let secs = self.num_seconds() * 1_000_000_000; let nsec = self.nanos_mod_sec(); @@ -345,7 +349,7 @@ impl PartialOrd for TimeVal { impl TimeValLike for TimeVal { #[inline] fn seconds(seconds: i64) -> TimeVal { - assert!(seconds >= TV_MIN_SECONDS && seconds <= TV_MAX_SECONDS, + assert!((TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&seconds), "TimeVal out of bounds; seconds={}", seconds); #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 TimeVal(timeval {tv_sec: seconds as time_t, tv_usec: 0 }) @@ -363,7 +367,7 @@ impl TimeValLike for TimeVal { #[inline] fn microseconds(microseconds: i64) -> TimeVal { let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); - assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS, + assert!((TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), "TimeVal out of bounds"); #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 TimeVal(timeval {tv_sec: secs as time_t, @@ -376,13 +380,15 @@ impl TimeValLike for TimeVal { fn nanoseconds(nanoseconds: i64) -> TimeVal { let microseconds = nanoseconds / 1000; let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); - assert!(secs >= TV_MIN_SECONDS && secs <= TV_MAX_SECONDS, + assert!((TV_MIN_SECONDS..=TV_MAX_SECONDS).contains(&secs), "TimeVal out of bounds"); #[cfg_attr(target_env = "musl", allow(deprecated))] // https://github.com/rust-lang/libc/issues/1848 TimeVal(timeval {tv_sec: secs as time_t, tv_usec: micros as suseconds_t }) } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] fn num_seconds(&self) -> i64 { if self.tv_sec() < 0 && self.tv_usec() > 0 { (self.tv_sec() + 1) as i64 @@ -395,6 +401,8 @@ impl TimeValLike for TimeVal { self.num_microseconds() / 1_000 } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] fn num_microseconds(&self) -> i64 { let secs = self.num_seconds() * 1_000_000; let usec = self.micros_mod_sec(); diff --git a/src/sys/uio.rs b/src/sys/uio.rs index 3abcde24fe..a65a6f10c8 100644 --- a/src/sys/uio.rs +++ b/src/sys/uio.rs @@ -189,7 +189,7 @@ impl IoVec { unsafe { slice::from_raw_parts( self.0.iov_base as *const u8, - self.0.iov_len as usize) + self.0.iov_len) } } } diff --git a/src/unistd.rs b/src/unistd.rs index 43e798dac9..1cc1d5379e 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2683,19 +2683,19 @@ impl From<&libc::passwd> for User { target_os = "illumos", target_os = "linux", target_os = "solaris")))] - class: CString::new(CStr::from_ptr((*pw).pw_class).to_bytes()).unwrap(), + class: CString::new(CStr::from_ptr(pw.pw_class).to_bytes()).unwrap(), #[cfg(not(any(target_os = "android", target_os = "fuchsia", target_os = "illumos", target_os = "linux", target_os = "solaris")))] - change: (*pw).pw_change, + change: pw.pw_change, #[cfg(not(any(target_os = "android", target_os = "fuchsia", target_os = "illumos", target_os = "linux", target_os = "solaris")))] - expire: (*pw).pw_expire + expire: pw.pw_expire } } } @@ -2852,10 +2852,10 @@ impl From<&libc::group> for Group { fn from(gr: &libc::group) -> Group { unsafe { Group { - name: CStr::from_ptr((*gr).gr_name).to_string_lossy().into_owned(), - passwd: CString::new(CStr::from_ptr((*gr).gr_passwd).to_bytes()).unwrap(), - gid: Gid::from_raw((*gr).gr_gid), - mem: Group::members((*gr).gr_mem) + name: CStr::from_ptr(gr.gr_name).to_string_lossy().into_owned(), + passwd: CString::new(CStr::from_ptr(gr.gr_passwd).to_bytes()).unwrap(), + gid: Gid::from_raw(gr.gr_gid), + mem: Group::members(gr.gr_mem) } } } diff --git a/test/sys/test_ioctl.rs b/test/sys/test_ioctl.rs index 236d24268a..f34296f9ee 100644 --- a/test/sys/test_ioctl.rs +++ b/test/sys/test_ioctl.rs @@ -30,6 +30,8 @@ ioctl_readwrite_buf!(readwritebuf_test, 0, 0, u32); #[cfg(any(target_os = "linux", target_os = "android"))] mod linux { + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] #[test] fn test_op_none() { if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){ @@ -41,6 +43,8 @@ mod linux { } } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] #[test] fn test_op_write() { if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){ @@ -65,6 +69,8 @@ mod linux { } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] #[test] fn test_op_read() { if cfg!(any(target_arch = "mips", target_arch = "mips64", target_arch="powerpc", target_arch="powerpc64")){ @@ -88,6 +94,8 @@ mod linux { } } + // The cast is not unnecessary on all platforms. + #[allow(clippy::unnecessary_cast)] #[test] fn test_op_read_write() { assert_eq!(request_code_readwrite!(b'z', 10, 1) as u32, 0xC001_7A0A); diff --git a/test/sys/test_stat.rs b/test/sys/test_stat.rs new file mode 100644 index 0000000000..426b4b6588 --- /dev/null +++ b/test/sys/test_stat.rs @@ -0,0 +1,29 @@ +// The conversion is not useless on all platforms. +#[allow(clippy::useless_conversion)] +#[cfg(target_os = "freebsd")] +#[test] +fn test_chflags() { + use nix::{ + sys::stat::{fstat, FileFlag}, + unistd::chflags, + }; + use std::os::unix::io::AsRawFd; + use tempfile::NamedTempFile; + + let f = NamedTempFile::new().unwrap(); + + let initial = FileFlag::from_bits_truncate( + fstat(f.as_raw_fd()).unwrap().st_flags.into(), + ); + // UF_OFFLINE is preserved by all FreeBSD file systems, but not interpreted + // in any way, so it's handy for testing. + let commanded = initial ^ FileFlag::UF_OFFLINE; + + chflags(f.path(), commanded).unwrap(); + + let changed = FileFlag::from_bits_truncate( + fstat(f.as_raw_fd()).unwrap().st_flags.into(), + ); + + assert_eq!(commanded, changed); +} diff --git a/test/test_mount.rs b/test/test_mount.rs index 44287f975f..0767185f5a 100644 --- a/test/test_mount.rs +++ b/test/test_mount.rs @@ -95,8 +95,13 @@ exit 23"; .unwrap_or_else(|e| panic!("mount failed: {}", e)); // EROFS: Read-only file system - assert_eq!(EROFS as i32, - File::create(tempdir.path().join("test")).unwrap_err().raw_os_error().unwrap()); + assert_eq!( + EROFS, + File::create(tempdir.path().join("test")) + .unwrap_err() + .raw_os_error() + .unwrap() + ); umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e)); } @@ -133,8 +138,14 @@ exit 23"; &test_path); // EACCES: Permission denied - assert_eq!(EACCES as i32, - Command::new(&test_path).status().unwrap_err().raw_os_error().unwrap()); + assert_eq!( + EACCES, + Command::new(&test_path) + .status() + .unwrap_err() + .raw_os_error() + .unwrap() + ); umount(tempdir.path()).unwrap_or_else(|e| panic!("umount failed: {}", e)); } From 93b9221502200b32fa9c3411e01dac33a5491506 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Sun, 14 Aug 2022 10:12:57 -0600 Subject: [PATCH 13/24] Fix a new clippy lint --- test/sys/test_timerfd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sys/test_timerfd.rs b/test/sys/test_timerfd.rs index 24fb2ac002..e546d790e7 100644 --- a/test/sys/test_timerfd.rs +++ b/test/sys/test_timerfd.rs @@ -57,5 +57,5 @@ pub fn test_timerfd_unset() { timer.unset().unwrap(); - assert!(timer.get().unwrap() == None); + assert!(timer.get().unwrap().is_none()); } From 81d1fdcac4dcffa22935657f08fd7f49ff2f0833 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Wed, 12 Oct 2022 20:36:15 -0500 Subject: [PATCH 14/24] fix '' being interpreted as html --- src/unistd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/unistd.rs b/src/unistd.rs index 1cc1d5379e..23bed1cbbb 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -2052,7 +2052,7 @@ pub enum SysconfVar { /// Unless otherwise noted, the maximum length, in bytes, of a utility's /// input line (either standard input or another file), when the utility is /// described as processing text files. The length includes room for the - /// trailing . + /// trailing newline. #[cfg(not(target_os = "redox"))] LINE_MAX = libc::_SC_LINE_MAX, /// Maximum length of a login name. From c15906679fd9300cd6fe7d1367b09762f3ffe405 Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Sun, 6 Nov 2022 11:40:46 -0800 Subject: [PATCH 15/24] Run a round of clippy to fix CI Signed-off-by: Alex Saveau --- test/test_dir.rs | 4 ++-- test/test_fcntl.rs | 8 ++++---- test/test_kmod/mod.rs | 10 ++++++---- test/test_unistd.rs | 10 +++++----- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/test/test_dir.rs b/test/test_dir.rs index 2940b6eafb..8cbb8ff5d3 100644 --- a/test/test_dir.rs +++ b/test/test_dir.rs @@ -20,8 +20,8 @@ fn flags() -> OFlag { #[allow(clippy::unnecessary_sort_by)] // False positive fn read() { let tmp = tempdir().unwrap(); - File::create(&tmp.path().join("foo")).unwrap(); - ::std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap(); + File::create(tmp.path().join("foo")).unwrap(); + std::os::unix::fs::symlink("foo", tmp.path().join("bar")).unwrap(); let mut dir = Dir::open(tmp.path(), flags(), Mode::empty()).unwrap(); let mut entries: Vec<_> = dir.iter().map(|e| e.unwrap()).collect(); entries.sort_by(|a, b| a.file_name().cmp(b.file_name())); diff --git a/test/test_fcntl.rs b/test/test_fcntl.rs index 374f221688..b7d50a4096 100644 --- a/test/test_fcntl.rs +++ b/test/test_fcntl.rs @@ -57,7 +57,7 @@ fn test_renameat() { let old_dir = tempfile::tempdir().unwrap(); let old_dirfd = open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); let old_path = old_dir.path().join("old"); - File::create(&old_path).unwrap(); + File::create(old_path).unwrap(); let new_dir = tempfile::tempdir().unwrap(); let new_dirfd = open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); renameat(Some(old_dirfd), "old", Some(new_dirfd), "new").unwrap(); @@ -83,7 +83,7 @@ fn test_renameat2_behaves_like_renameat_with_no_flags() { let old_dir = tempfile::tempdir().unwrap(); let old_dirfd = open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); let old_path = old_dir.path().join("old"); - File::create(&old_path).unwrap(); + File::create(old_path).unwrap(); let new_dir = tempfile::tempdir().unwrap(); let new_dirfd = open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); renameat2( @@ -171,11 +171,11 @@ fn test_renameat2_noreplace() { let old_dir = tempfile::tempdir().unwrap(); let old_dirfd = open(old_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); let old_path = old_dir.path().join("old"); - File::create(&old_path).unwrap(); + File::create(old_path).unwrap(); let new_dir = tempfile::tempdir().unwrap(); let new_dirfd = open(new_dir.path(), OFlag::empty(), Mode::empty()).unwrap(); let new_path = new_dir.path().join("new"); - File::create(&new_path).unwrap(); + File::create(new_path).unwrap(); assert_eq!( renameat2( Some(old_dirfd), diff --git a/test/test_kmod/mod.rs b/test/test_kmod/mod.rs index 8eef5384a3..246aec66b4 100644 --- a/test/test_kmod/mod.rs +++ b/test/test_kmod/mod.rs @@ -11,12 +11,14 @@ fn compile_kernel_module() -> (PathBuf, String, TempDir) { copy( "test/test_kmod/hello_mod/hello.c", - &tmp_dir.path().join("hello.c"), - ).expect("unable to copy hello.c to temporary build directory"); + tmp_dir.path().join("hello.c"), + ) + .expect("unable to copy hello.c to temporary build directory"); copy( "test/test_kmod/hello_mod/Makefile", - &tmp_dir.path().join("Makefile"), - ).expect("unable to copy Makefile to temporary build directory"); + tmp_dir.path().join("Makefile"), + ) + .expect("unable to copy Makefile to temporary build directory"); let status = Command::new("make") .current_dir(tmp_dir.path()) diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 61062ad229..f5942030c5 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -820,7 +820,7 @@ fn test_linkat_file() { let newfilepath = tempdir.path().join(newfilename); // Create file - File::create(&oldfilepath).unwrap(); + File::create(oldfilepath).unwrap(); // Get file descriptor for base directory let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); @@ -844,7 +844,7 @@ fn test_linkat_olddirfd_none() { let newfilepath = tempdir_newfile.path().join(newfilename); // Create file - File::create(&oldfilepath).unwrap(); + File::create(oldfilepath).unwrap(); // Get file descriptor for base directory of new file let dirfd = fcntl::open(tempdir_newfile.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); @@ -869,7 +869,7 @@ fn test_linkat_newdirfd_none() { let newfilepath = tempdir_newfile.path().join(newfilename); // Create file - File::create(&oldfilepath).unwrap(); + File::create(oldfilepath).unwrap(); // Get file descriptor for base directory of old file let dirfd = fcntl::open(tempdir_oldfile.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); @@ -963,7 +963,7 @@ fn test_unlinkat_dir_noremovedir() { let dirpath = tempdir.path().join(dirname); // Create dir - DirBuilder::new().recursive(true).create(&dirpath).unwrap(); + DirBuilder::new().recursive(true).create(dirpath).unwrap(); // Get file descriptor for base directory let dirfd = fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty()).unwrap(); @@ -1049,7 +1049,7 @@ fn test_setfsuid() { let file = tempfile::NamedTempFile::new_in("/var/tmp").unwrap(); let temp_path = file.into_temp_path(); dbg!(&temp_path); - let temp_path_2 = (&temp_path).to_path_buf(); + let temp_path_2 = temp_path.to_path_buf(); let mut permissions = fs::metadata(&temp_path).unwrap().permissions(); permissions.set_mode(0o640); From b9cc511d2a35023c53750ac571b9343082a3404d Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Mon, 28 Nov 2022 22:19:44 -0600 Subject: [PATCH 16/24] clippy: elide lifetime parameter --- src/sys/socket/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index badb6632c5..49f11e4517 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -1394,7 +1394,7 @@ pub fn recvmmsg<'a, I>( .collect()) } -unsafe fn read_mhdr<'a, 'b>( +unsafe fn read_mhdr<'a>( mhdr: msghdr, r: isize, msg_controllen: usize, From 6d9ebf271cec48c4715157f1a69d44aa15ecf110 Mon Sep 17 00:00:00 2001 From: Alex Rawson Date: Tue, 31 May 2022 17:51:45 -0500 Subject: [PATCH 17/24] Ignore doctests for unexported macros Due to rust-lang/rust#97030, cargo test will fail to doctest macros unless they are exported, breaking the examples for libc_bitflags! and libc_enum!. Adds `ignore` to the examples for these macros to stop tests from failing. --- src/macros.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index d64d60ea6f..b73f666c48 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -5,7 +5,7 @@ /// The `libc` crate must be in scope with the name `libc`. /// /// # Example -/// ``` +/// ```ignore /// libc_bitflags!{ /// pub struct ProtFlags: libc::c_int { /// PROT_NONE; @@ -25,7 +25,7 @@ /// various flags have different types, so we cast the broken ones to the right /// type. /// -/// ``` +/// ```ignore /// libc_bitflags!{ /// pub struct SaFlags: libc::c_ulong { /// SA_NOCLDSTOP as libc::c_ulong; @@ -66,7 +66,7 @@ macro_rules! libc_bitflags { /// The `libc` crate must be in scope with the name `libc`. /// /// # Example -/// ``` +/// ```ignore /// libc_enum!{ /// pub enum ProtFlags { /// PROT_NONE, From e8c39880f60172f99a8b4507f63063a2cd39f829 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Thu, 1 Dec 2022 19:05:17 -0600 Subject: [PATCH 18/24] Fix clippy warnings from backporting --- test/sys/test_uio.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs index c63b58103c..99dad0cad6 100644 --- a/test/sys/test_uio.rs +++ b/test/sys/test_uio.rs @@ -47,7 +47,7 @@ fn test_writev() { let read_res = read(reader, &mut read_buf[..]); // Successful read assert!(read_res.is_ok()); - let read = read_res.ok().unwrap() as usize; + let read = read_res.ok().unwrap(); // Check we have read as much as we written assert_eq!(read, written); // Check equality of written and read data @@ -249,7 +249,7 @@ fn test_process_vm_readv() { } let _ = write(w, b"\0"); let _ = close(w); - loop { let _ = pause(); } + loop { pause(); } }, } } From 0842aa4fe6e7caa8a9b1ea946daa8c86e8380843 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Thu, 1 Dec 2022 20:20:35 -0600 Subject: [PATCH 19/24] Suppress EventFlag::EV_SYSFLAGS deprecation --- src/sys/event.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sys/event.rs b/src/sys/event.rs index c648f5ebc8..660a5357c2 100644 --- a/src/sys/event.rs +++ b/src/sys/event.rs @@ -114,6 +114,9 @@ libc_bitflags!{ target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))] EV_RECEIPT; + // Removed in 0.24 by 84e3c56bcc144fb4964caa69fb1dddeccb35be82, + // but leaving around in older versions. + #[allow(deprecated)] EV_SYSFLAGS; } } From 55e15f0b2eb85e00d6c1641ff3389a4902a74c57 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Thu, 1 Dec 2022 21:05:52 -0600 Subject: [PATCH 20/24] Suppress clippy::not_unsafe_ptr_arg_deref where appropriate --- src/sys/ptrace/bsd.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sys/ptrace/bsd.rs b/src/sys/ptrace/bsd.rs index a62881ef34..68cb2309c0 100644 --- a/src/sys/ptrace/bsd.rs +++ b/src/sys/ptrace/bsd.rs @@ -162,6 +162,9 @@ pub fn step>>(pid: Pid, sig: T) -> Result<()> { } /// Reads a word from a processes memory at the given address +// Technically, ptrace doesn't dereference the pointer. It passes it directly +// to the kernel. +#[allow(clippy::not_unsafe_ptr_arg_deref)] pub fn read(pid: Pid, addr: AddressType) -> Result { unsafe { // Traditionally there was a difference between reading data or @@ -171,6 +174,9 @@ pub fn read(pid: Pid, addr: AddressType) -> Result { } /// Writes a word into the processes memory at the given address +// Technically, ptrace doesn't dereference the pointer. It passes it directly +// to the kernel. +#[allow(clippy::not_unsafe_ptr_arg_deref)] pub fn write(pid: Pid, addr: AddressType, data: c_int) -> Result<()> { unsafe { ptrace_other(Request::PT_WRITE_D, pid, addr, data).map(drop) } } From 34e1ca20e097ef6dc7a4e44d365e3c0fb9c13d0a Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 25 Mar 2022 18:09:37 -0600 Subject: [PATCH 21/24] Use the nightly toolchain for Redox The latest redox-syscall crate requires at least Rust 1.59.0, but they don't define an MSRV policy. And the version given in the rust-toolchain file in the Redox repository doesn't work. So until they clarify their MSRV, use nightly. https://gitlab.redox-os.org/redox-os/syscall/-/commit/30f29c32952343412bb6c36c9fda136d26e9431f --- .cirrus.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index fe16ad7cdb..c94d4b9ec1 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -244,11 +244,9 @@ task: BUILD: check name: Redox x86_64 env: - TARGET: x86_64-unknown-redox - # Redox requires a nightly compiler. - # If stuff breaks, change nightly to the date at - # https://gitlab.redox-os.org/redox-os/redox/-/blob/master/rust-toolchain - TOOLCHAIN: nightly-2021-06-15 + TARGET: x86_64-unknown-redox + # Redox's MSRV policy is unclear. Until they define it, use nightly. + TOOLCHAIN: nightly setup_script: - rustup target add $TARGET - rustup toolchain install $TOOLCHAIN --profile minimal --target $TARGET From 967143f2419e4830b0100ce8929ffd2b05909b7d Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Sun, 20 Mar 2022 09:24:21 -0500 Subject: [PATCH 22/24] Redox renamed sigaction.sa_handler to .sa_sigaction --- Cargo.toml | 2 +- src/sys/signal.rs | 34 ++-------------------------------- 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d2ca8ee804..62aee5e857 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ targets = [ ] [dependencies] -libc = { version = "0.2.102", features = [ "extra_traits" ] } +libc = { version = "0.2.121", features = [ "extra_traits" ] } bitflags = "1.1" cfg-if = "1.0" diff --git a/src/sys/signal.rs b/src/sys/signal.rs index 61bdc74aef..ee0f7dc594 100644 --- a/src/sys/signal.rs +++ b/src/sys/signal.rs @@ -589,21 +589,12 @@ impl SigAction { /// is the `SigAction` variant). `mask` specifies other signals to block during execution of /// the signal-catching function. pub fn new(handler: SigHandler, flags: SaFlags, mask: SigSet) -> SigAction { - #[cfg(target_os = "redox")] - unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) { - (*p).sa_handler = match handler { - SigHandler::SigDfl => libc::SIG_DFL, - SigHandler::SigIgn => libc::SIG_IGN, - SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize, - }; - } - - #[cfg(not(target_os = "redox"))] unsafe fn install_sig(p: *mut libc::sigaction, handler: SigHandler) { (*p).sa_sigaction = match handler { SigHandler::SigDfl => libc::SIG_DFL, SigHandler::SigIgn => libc::SIG_IGN, SigHandler::Handler(f) => f as *const extern fn(libc::c_int) as usize, + #[cfg(not(target_os = "redox"))] SigHandler::SigAction(f) => f as *const extern fn(libc::c_int, *mut libc::siginfo_t, *mut libc::c_void) as usize, }; } @@ -635,11 +626,11 @@ impl SigAction { } /// Returns the action's handler. - #[cfg(not(target_os = "redox"))] pub fn handler(&self) -> SigHandler { match self.sigaction.sa_sigaction { libc::SIG_DFL => SigHandler::SigDfl, libc::SIG_IGN => SigHandler::SigIgn, + #[cfg(not(target_os = "redox"))] p if self.flags().contains(SaFlags::SA_SIGINFO) => SigHandler::SigAction( // Safe for one of two reasons: @@ -667,27 +658,6 @@ impl SigAction { as extern fn(libc::c_int)), } } - - /// Returns the action's handler. - #[cfg(target_os = "redox")] - pub fn handler(&self) -> SigHandler { - match self.sigaction.sa_handler { - libc::SIG_DFL => SigHandler::SigDfl, - libc::SIG_IGN => SigHandler::SigIgn, - p => SigHandler::Handler( - // Safe for one of two reasons: - // * The SigHandler was created by SigHandler::new, in which - // case the pointer is correct, or - // * The SigHandler was created by signal or sigaction, which - // are unsafe functions, so the caller should've somehow - // ensured that it is correctly initialized. - unsafe{ - *(&p as *const usize - as *const extern fn(libc::c_int)) - } - as extern fn(libc::c_int)), - } - } } /// Changes the action taken by a process on receipt of a specific signal. From 5393542c12e825f6a35fd5401ee1788070d018f0 Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Sat, 3 Dec 2022 11:07:17 -0600 Subject: [PATCH 23/24] Remove no-dev-version This should fix newer versions of cargo-release. --- release.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/release.toml b/release.toml index df2c9da45d..23488fbfa5 100644 --- a/release.toml +++ b/release.toml @@ -1,4 +1,3 @@ -no-dev-version = true pre-release-replacements = [ { file="CHANGELOG.md", search="Unreleased", replace="{{version}}" }, { file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}" } From 3e9cfda3a66a1fafec94867b16f6cab3a06225fa Mon Sep 17 00:00:00 2001 From: Ryan Zoeller Date: Sat, 3 Dec 2022 11:11:46 -0600 Subject: [PATCH 24/24] chore: Release nix version 0.23.2 --- CHANGELOG.md | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e36e41fc6c..a7b24ff211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). -## [Unreleased] - ReleaseDate +## [0.23.2] - 2022-12-03 ### Added ### Changed diff --git a/Cargo.toml b/Cargo.toml index 62aee5e857..f3e3df3df7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "nix" description = "Rust friendly bindings to *nix APIs" edition = "2018" -version = "0.23.1" +version = "0.23.2" rust-version = "1.46" authors = ["The nix-rust Project Developers"] repository = "https://github.com/nix-rust/nix" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy