diff --git a/.cirrus.yml b/.cirrus.yml index 8d6e121020..c94d4b9ec1 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 @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 77d5b2a326..a7b24ff211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). +## [0.23.2] - 2022-12-03 +### Added + +### Changed + +### Fixed + +- `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)) +- 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)) +- Fix UB with `sys::socket::sockopt::SockType` using `SOCK_PACKET`. + ([#1821](https://github.com/nix-rust/nix/pull/1821)) + +### Removed + ## [0.23.1] - 2021-12-16 ### Added diff --git a/Cargo.toml b/Cargo.toml index d2ca8ee804..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" @@ -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/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}}" } 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/macros.rs b/src/macros.rs index 3ccbfdd43b..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, @@ -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/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; } } 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/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) } } 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. diff --git a/src/sys/socket/addr.rs b/src/sys/socket/addr.rs index b119642b3f..4ef435d041 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, @@ -1175,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 97eea3dcb1..49f11e4517 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. @@ -679,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) { @@ -1158,7 +1179,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()) }; @@ -1339,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 { @@ -1358,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, @@ -1371,13 +1394,15 @@ pub fn recvmmsg<'a, I>( .collect()) } -unsafe fn read_mhdr<'a, 'b>( +unsafe fn read_mhdr<'a>( mhdr: msghdr, 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) @@ -1519,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()) }; @@ -1819,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 fcb4be81be..efb9c54500 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) + } } } } @@ -128,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])* @@ -413,7 +420,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)`. @@ -718,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 { @@ -765,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 ac4247180d..6cf567ec36 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, + assert!((TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&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,15 +153,20 @@ 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, + assert!((TS_MIN_SECONDS..=TS_MAX_SECONDS).contains(&secs), "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) } + // 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 @@ -167,9 +180,11 @@ impl TimeValLike for TimeSpec { } fn num_microseconds(&self) -> i64 { - self.num_nanoseconds() / 1_000_000_000 + 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(); @@ -195,12 +210,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 { @@ -333,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 }) @@ -351,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, @@ -364,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 @@ -383,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/timerfd.rs b/src/sys/timerfd.rs index 705a3c4d65..4df3c34866 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()), @@ -157,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/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 2c89d77240..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. @@ -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, @@ -2670,32 +2670,32 @@ 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", 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 } } } @@ -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) } }) @@ -2832,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, @@ -2849,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) } } } @@ -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) } }) 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_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. 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/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()); } 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(); } }, } } 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 db2acfbf52..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), @@ -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); 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_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)); } 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);