mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-29 20:46:07 +03:00
feat: Support fstat in linux
refactor: rename `macos_fbsd_solarish_write_stat_buf` to `write_stat_buf` refactor: rename `macos_fbsd_solarish_fstat` to `fstat` feat: support `fstat` in linux test: testing support of `fstat` in linux fix: missed add `Os::Linux` for supported OSs in `fstat` feat: add nanosecond fields to file metadata in `EvalContextExtPrivate` add `fstat` to foreign items in unix enhance test of `fstat` fix the test
This commit is contained in:
@@ -345,6 +345,11 @@ fn emulate_foreign_item_inner(
|
||||
let result = this.symlink(target, linkpath)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"fstat" => {
|
||||
let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"rename" => {
|
||||
let [oldpath, newpath] = this.check_shim_sig(
|
||||
shim_sig!(extern "C" fn(*const _, *const _) -> i32),
|
||||
|
||||
@@ -150,7 +150,7 @@ fn emulate_foreign_item_inner(
|
||||
}
|
||||
"fstat" | "fstat@FBSD_1.0" => {
|
||||
let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
|
||||
let result = this.fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"readdir_r" | "readdir_r@FBSD_1.0" => {
|
||||
|
||||
@@ -118,7 +118,7 @@ fn flock<'tcx>(
|
||||
|
||||
impl<'tcx> EvalContextExtPrivate<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn macos_fbsd_solarish_write_stat_buf(
|
||||
fn write_stat_buf(
|
||||
&mut self,
|
||||
metadata: FileMetadata,
|
||||
buf_op: &OpTy<'tcx>,
|
||||
@@ -141,8 +141,11 @@ fn macos_fbsd_solarish_write_stat_buf(
|
||||
("st_gid", metadata.gid.into()),
|
||||
("st_rdev", 0),
|
||||
("st_atime", access_sec.into()),
|
||||
("st_atime_nsec", access_nsec.into()),
|
||||
("st_mtime", modified_sec.into()),
|
||||
("st_mtime_nsec", modified_nsec.into()),
|
||||
("st_ctime", 0),
|
||||
("st_ctime_nsec", 0),
|
||||
("st_size", metadata.size.into()),
|
||||
("st_blocks", 0),
|
||||
("st_blksize", 0),
|
||||
@@ -550,7 +553,7 @@ fn macos_fbsd_solarish_stat(
|
||||
Err(err) => return this.set_last_error_and_return_i32(err),
|
||||
};
|
||||
|
||||
interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?))
|
||||
interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?))
|
||||
}
|
||||
|
||||
// `lstat` is used to get symlink metadata.
|
||||
@@ -583,22 +586,17 @@ fn macos_fbsd_solarish_lstat(
|
||||
Err(err) => return this.set_last_error_and_return_i32(err),
|
||||
};
|
||||
|
||||
interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?))
|
||||
interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?))
|
||||
}
|
||||
|
||||
fn macos_fbsd_solarish_fstat(
|
||||
&mut self,
|
||||
fd_op: &OpTy<'tcx>,
|
||||
buf_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
fn fstat(&mut self, fd_op: &OpTy<'tcx>, buf_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
if !matches!(&this.tcx.sess.target.os, Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos)
|
||||
{
|
||||
panic!(
|
||||
"`macos_fbsd_solaris_fstat` should not be called on {}",
|
||||
this.tcx.sess.target.os
|
||||
);
|
||||
if !matches!(
|
||||
&this.tcx.sess.target.os,
|
||||
Os::MacOs | Os::FreeBsd | Os::Solaris | Os::Illumos | Os::Linux
|
||||
) {
|
||||
panic!("`fstat` should not be called on {}", this.tcx.sess.target.os);
|
||||
}
|
||||
|
||||
let fd = this.read_scalar(fd_op)?.to_i32()?;
|
||||
@@ -614,7 +612,7 @@ fn macos_fbsd_solarish_fstat(
|
||||
Ok(metadata) => metadata,
|
||||
Err(err) => return this.set_last_error_and_return_i32(err),
|
||||
};
|
||||
interp_ok(Scalar::from_i32(this.macos_fbsd_solarish_write_stat_buf(metadata, buf_op)?))
|
||||
interp_ok(Scalar::from_i32(this.write_stat_buf(metadata, buf_op)?))
|
||||
}
|
||||
|
||||
fn linux_statx(
|
||||
|
||||
@@ -53,7 +53,11 @@ fn emulate_foreign_item_inner(
|
||||
let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
"fstat" => {
|
||||
let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
// epoll, eventfd
|
||||
"epoll_create1" => {
|
||||
let [flag] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
@@ -56,9 +56,9 @@ fn emulate_foreign_item_inner(
|
||||
let result = this.macos_fbsd_solarish_lstat(path, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"fstat" | "fstat64" | "fstat$INODE64" => {
|
||||
"fstat$INODE64" => {
|
||||
let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
|
||||
let result = this.fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"opendir$INODE64" => {
|
||||
|
||||
@@ -102,7 +102,7 @@ fn emulate_foreign_item_inner(
|
||||
}
|
||||
"fstat" | "fstat64" => {
|
||||
let [fd, buf] = this.check_shim_sig_lenient(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
|
||||
let result = this.fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"readdir" => {
|
||||
|
||||
@@ -42,6 +42,7 @@ fn main() {
|
||||
test_posix_fallocate::<libc::off64_t>(libc::posix_fallocate64);
|
||||
#[cfg(target_os = "linux")]
|
||||
test_sync_file_range();
|
||||
test_fstat();
|
||||
test_isatty();
|
||||
test_read_and_uninit();
|
||||
test_nofollow_not_symlink();
|
||||
@@ -452,6 +453,39 @@ fn test_sync_file_range() {
|
||||
assert_eq!(result_2, 0);
|
||||
}
|
||||
|
||||
fn test_fstat() {
|
||||
use std::mem::MaybeUninit;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
let path = utils::prepare_with_content("miri_test_libc_fstat.txt", b"hello");
|
||||
let file = File::open(&path).unwrap();
|
||||
let fd = file.as_raw_fd();
|
||||
|
||||
let mut stat: libc::stat = unsafe { MaybeUninit::zeroed().assume_init() };
|
||||
let res = unsafe { libc::fstat(fd, &mut stat) };
|
||||
assert_eq!(res, 0);
|
||||
|
||||
assert_eq!(stat.st_size, 5);
|
||||
assert_eq!(stat.st_mode & libc::S_IFMT, libc::S_IFREG);
|
||||
|
||||
let _st_nlink = stat.st_nlink;
|
||||
let _st_blksize = stat.st_blksize;
|
||||
let _st_blocks = stat.st_blocks;
|
||||
let _st_ino = stat.st_ino;
|
||||
let _st_dev = stat.st_dev;
|
||||
let _st_uid = stat.st_uid;
|
||||
let _st_gid = stat.st_gid;
|
||||
let _st_rdev = stat.st_rdev;
|
||||
let _st_atime = stat.st_atime;
|
||||
let _st_mtime = stat.st_mtime;
|
||||
let _st_ctime = stat.st_ctime;
|
||||
let _st_atime_nsec = stat.st_atime_nsec;
|
||||
let _st_mtime_nsec = stat.st_mtime_nsec;
|
||||
let _st_ctime_nsec = stat.st_ctime_nsec;
|
||||
|
||||
remove_file(&path).unwrap();
|
||||
}
|
||||
|
||||
fn test_isatty() {
|
||||
// Testing whether our isatty shim returns the right value would require controlling whether
|
||||
// these streams are actually TTYs, which is hard.
|
||||
|
||||
Reference in New Issue
Block a user