From 36114f363081baf0d2981bb42b1110d916541b1c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 1 Aug 2024 11:43:24 +0000 Subject: [PATCH] Write `-1` together with setting the global error value --- src/helpers.rs | 10 ++++++++++ src/shims/unix/fs.rs | 42 +++++++++++++++++------------------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index d454c09659..0f008dfc03 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -805,6 +805,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Ok(EmulateItemResult::NeedsReturn) } + fn set_io_err_and_return_neg1( + &mut self, + err: std::io::Error, + dest: &MPlaceTy<'tcx>, + ) -> InterpResult<'tcx, EmulateItemResult> { + self.set_last_error_from_io_error(err)?; + self.eval_context_mut().write_int(-1, dest)?; + Ok(EmulateItemResult::NeedsReturn) + } + /// Gets the last error variable. fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar> { let this = self.eval_context_mut(); diff --git a/src/shims/unix/fs.rs b/src/shims/unix/fs.rs index c717312116..9d9b956e31 100644 --- a/src/shims/unix/fs.rs +++ b/src/shims/unix/fs.rs @@ -657,12 +657,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // `stat` always follows symlinks. - let metadata = match FileMetadata::from_path(this, &path, true)? { + let metadata = match FileMetadata::from_path(this, &path, true, dest)? { Some(metadata) => metadata, - None => { - this.write_int(-1, dest)?; - return Ok(EmulateItemResult::NeedsReturn); - } + None => return Ok(EmulateItemResult::NeedsReturn), }; let res = this.macos_stat_write_buf(metadata, buf_op)?; this.write_int(res, dest)?; @@ -691,12 +688,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.set_libc_err_and_return_neg1("EACCES", dest); } - let metadata = match FileMetadata::from_path(this, &path, false)? { + let metadata = match FileMetadata::from_path(this, &path, false, dest)? { Some(metadata) => metadata, - None => { - this.write_int(-1, dest)?; - return Ok(EmulateItemResult::NeedsReturn); - } + None => return Ok(EmulateItemResult::NeedsReturn), }; let res = this.macos_stat_write_buf(metadata, buf_op)?; this.write_int(res, dest)?; @@ -724,12 +718,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return this.set_fd_not_found_and_return_neg1(dest); } - let metadata = match FileMetadata::from_fd(this, fd)? { + let metadata = match FileMetadata::from_fd(this, fd, dest)? { Some(metadata) => metadata, - None => { - this.write_int(-1, dest)?; - return Ok(EmulateItemResult::NeedsReturn); - } + None => return Ok(EmulateItemResult::NeedsReturn), }; let res = this.macos_stat_write_buf(metadata, buf_op)?; this.write_int(res, dest)?; @@ -814,16 +805,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // If the path is empty, and the AT_EMPTY_PATH flag is set, we query the open file // represented by dirfd, whether it's a directory or otherwise. let metadata = if path.as_os_str().is_empty() && empty_path_flag { - FileMetadata::from_fd(this, dirfd)? + FileMetadata::from_fd(this, dirfd, dest)? } else { - FileMetadata::from_path(this, &path, follow_symlink)? + FileMetadata::from_path(this, &path, follow_symlink, dest)? }; let metadata = match metadata { Some(metadata) => metadata, - None => { - this.write_int(-1, dest)?; - return Ok(EmulateItemResult::NeedsReturn); - } + None => return Ok(EmulateItemResult::NeedsReturn), }; // The `mode` field specifies the type of the file and the permissions over the file for @@ -1712,19 +1700,22 @@ impl FileMetadata { ecx: &mut MiriInterpCx<'tcx>, path: &Path, follow_symlink: bool, + dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, Option> { let metadata = if follow_symlink { std::fs::metadata(path) } else { std::fs::symlink_metadata(path) }; - FileMetadata::from_meta(ecx, metadata) + FileMetadata::from_meta(ecx, metadata, dest) } fn from_fd<'tcx>( ecx: &mut MiriInterpCx<'tcx>, fd: i32, + dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, Option> { let Some(file_description) = ecx.machine.fds.get(fd) else { - return ecx.fd_not_found().map(|_: i32| None); + ecx.set_fd_not_found_and_return_neg1(dest)?; + return Ok(None); }; let file = &file_description @@ -1738,17 +1729,18 @@ impl FileMetadata { let metadata = file.metadata(); drop(file_description); - FileMetadata::from_meta(ecx, metadata) + FileMetadata::from_meta(ecx, metadata, dest) } fn from_meta<'tcx>( ecx: &mut MiriInterpCx<'tcx>, metadata: Result, + dest: &MPlaceTy<'tcx>, ) -> InterpResult<'tcx, Option> { let metadata = match metadata { Ok(metadata) => metadata, Err(e) => { - ecx.set_last_error_from_io_error(e)?; + ecx.set_io_err_and_return_neg1(e, dest)?; return Ok(None); } };