From ff47c2c6286fd203ae677eedc4a4716b9fc9f2e6 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Mon, 5 Aug 2024 13:09:24 +0200 Subject: [PATCH] Remove non-portable use of fstat Part of #10634 --- src/builtins/source.rs | 27 ++++++++++++++++----------- src/history.rs | 19 ++++++++++++------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/builtins/source.rs b/src/builtins/source.rs index 5f3bb84b9..6b283eb4a 100644 --- a/src/builtins/source.rs +++ b/src/builtins/source.rs @@ -1,4 +1,5 @@ use std::os::fd::AsRawFd; +use std::os::unix::fs::MetadataExt; use crate::{ common::{escape, scoped_push_replacer, FilenameRef}, @@ -6,6 +7,7 @@ use crate::{ nix::isatty, parser::Block, reader::reader_read, + wutil::fstat, }; use libc::{S_IFMT, S_IFREG}; use nix::{fcntl::OFlag, sys::stat::Mode}; @@ -68,18 +70,21 @@ pub fn source(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr]) -> O }; fd = opened_file.as_raw_fd(); - let mut buf: libc::stat = unsafe { std::mem::zeroed() }; - if unsafe { libc::fstat(fd, &mut buf) } == -1 { - let esc = escape(args[optind]); - streams.err.append(wgettext_fmt!( - "%ls: Error encountered while sourcing file '%ls':\n", - cmd, - &esc - )); - return STATUS_CMD_ERROR; - } + let md = match fstat(fd) { + Ok(md) => md, + Err(_) => { + let esc = escape(args[optind]); + streams.err.append(wgettext_fmt!( + "%ls: Error encountered while sourcing file '%ls':\n", + cmd, + &esc + )); + return STATUS_CMD_ERROR; + } + }; - if buf.st_mode & S_IFMT != S_IFREG { + #[allow(clippy::useless_conversion)] + if md.mode() & u32::from(S_IFMT) != u32::from(S_IFREG) { let esc = escape(args[optind]); streams .err diff --git a/src/history.rs b/src/history.rs index 63910b885..3ccc10dd8 100644 --- a/src/history.rs +++ b/src/history.rs @@ -23,16 +23,18 @@ use std::{ ffi::CString, fs::File, io::{BufRead, Read, Seek, SeekFrom, Write}, - mem, num::NonZeroUsize, ops::ControlFlow, - os::fd::{AsFd, AsRawFd, RawFd}, + os::{ + fd::{AsFd, AsRawFd, RawFd}, + unix::fs::MetadataExt, + }, sync::{Arc, Mutex, MutexGuard}, time::{Duration, SystemTime, UNIX_EPOCH}, }; use bitflags::bitflags; -use libc::{fchmod, fchown, flock, fstat, LOCK_EX, LOCK_SH, LOCK_UN}; +use libc::{fchmod, fchown, flock, LOCK_EX, LOCK_SH, LOCK_UN}; use lru::LruCache; use nix::{fcntl::OFlag, sys::stat::Mode}; use rand::Rng; @@ -62,6 +64,7 @@ use crate::{ wchar::prelude::*, wcstringutil::subsequence_in_string, wildcard::{wildcard_match, ANY_STRING}, + wutil::fstat, wutil::{ file_id_for_fd, file_id_for_path, wgettext_fmt, wrealpath, wrename, wstat, wunlink, FileId, INVALID_FILE_ID, @@ -718,16 +721,18 @@ impl HistoryImpl { // did, it would be tricky to set the permissions correctly. (bash doesn't get this // case right either). if let Ok(target_fd_after) = target_fd_after.as_ref() { - let mut sbuf: libc::stat = unsafe { mem::zeroed() }; - if unsafe { fstat(target_fd_after.as_raw_fd(), &mut sbuf) } >= 0 { - if unsafe { fchown(tmp_file.as_raw_fd(), sbuf.st_uid, sbuf.st_gid) } == -1 { + if let Ok(md) = fstat(target_fd_after.as_raw_fd()) { + if unsafe { fchown(tmp_file.as_raw_fd(), md.uid(), md.gid()) } == -1 { FLOGF!( history_file, "Error %d when changing ownership of history file", errno::errno().0 ); } - if unsafe { fchmod(tmp_file.as_raw_fd(), sbuf.st_mode) } == -1 { + #[allow(clippy::useless_conversion)] + if unsafe { fchmod(tmp_file.as_raw_fd(), md.mode().try_into().unwrap()) } + == -1 + { FLOGF!( history_file, "Error %d when changing mode of history file",