Remove non-portable use of fstat

Part of #10634
This commit is contained in:
Johannes Altmanninger 2024-08-05 13:09:24 +02:00
parent b64045dc18
commit ff47c2c628
2 changed files with 28 additions and 18 deletions

View file

@ -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

View file

@ -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",