-
Notifications
You must be signed in to change notification settings - Fork 352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: handle writing to dest within the foreign item handler #3779
base: master
Are you sure you want to change the base?
Conversation
src/shims/unix/fs.rs
Outdated
Some(metadata) => metadata, | ||
None => return Ok(Scalar::from_i32(-1)), // `FileMetadata` has set errno | ||
None => return Ok(EmulateItemResult::NeedsReturn), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None => return Ok(EmulateItemResult::NeedsReturn), | |
None => return Ok(EmulateItemResult::NeedsReturn), // `FileMetadata::from_path` has set the return value |
But this is a bit odd, seems cleaner to instead have from_path
return a Result
and do the errno+return handling here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit annoying as I have to return a Result<T, Scalar>
to be able to handle both EBADF and io::Error
, but generally nicer indeed
☔ The latest upstream changes (presumably #3804) made this pull request unmergeable. Please resolve the merge conflicts. |
2918e74
to
f162e51
Compare
if this is to your liking, I'll port everything @rustbot ready |
☔ The latest upstream changes (presumably #3923) made this pull request unmergeable. Please resolve the merge conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally like it, modulo the comments here. Note that this has more overlap with #3930 than I thought, so we should be careful to avoid conflicts.
) -> InterpResult<'tcx> { | ||
self.set_last_error(err)?; | ||
self.eval_context_mut().write_int(-1, dest) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both of these new functions are superseded by the helper that @tiif added and that I extended. You should be able to use set_last_error_and_return
now (after a rebase).
/// Helper function that consumes an `std::io::Result<i32>` and writes the `Ok` integer | ||
/// to the destination. In case the result is an error, this function writes | ||
/// `-1` and sets the last OS error accordingly. | ||
fn write_io_result( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this to the new io_error.rs file, and put it right below try_unwrap_io_result
(since it extends that helper).
Some(metadata) => metadata, | ||
None => return Ok(Scalar::from_i32(-1)), // `FileMetadata` has set errno | ||
Ok(metadata) => metadata, | ||
Err(e) => return this.set_last_err_and_return_neg1(e, dest), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the feeling we will have this pattern a lot... given an io::Result<T>
, call return this.set_last_error_and_return
on the error path and unwrap the T
otherwise. Do you think that'd be worth a try!
-like macro?
@@ -1050,7 +1051,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | |||
this.reject_in_isolation("`readdir`", reject_with)?; | |||
let eacc = this.eval_libc("EBADF"); | |||
this.set_last_error(eacc)?; | |||
return Ok(Scalar::null_ptr(this)); | |||
return this.write_scalar(eacc, dest); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes behavior, doesn't it? We should be returning a null pointer but you made it return eacc
now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should fix this one in a separate PR with a test that shows the behaviour change. The previous behaviour is buggy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it was. readdir returns null on error.
readdir_r works different, but this is readdir.
@@ -1710,9 +1709,9 @@ impl FileMetadata { | |||
fn from_fd_num<'tcx>( | |||
ecx: &mut MiriInterpCx<'tcx>, | |||
fd_num: i32, | |||
) -> InterpResult<'tcx, Option<FileMetadata>> { | |||
) -> InterpResult<'tcx, Result<FileMetadata, Scalar>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a doc comment explaining the meaning of this return type. (Same for the next function.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not necessary, I can use your new error enum instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, even better :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#3990 did this part :)
@@ -1148,14 +1150,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | |||
// Reject if isolation is enabled. | |||
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op { | |||
this.reject_in_isolation("`readdir_r`", reject_with)?; | |||
// Set error code as "EBADF" (bad fd) | |||
return Ok(Scalar::from_i32(this.fd_not_found()?)); | |||
// return positive error number on error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// return positive error number on error | |
// Return positive error number on error (*without* setting errno!) |
@@ -27,7 +27,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { | |||
flags: &OpTy<'tcx>, | |||
fd: &OpTy<'tcx>, | |||
offset: i128, | |||
) -> InterpResult<'tcx, Scalar> { | |||
dest: &MPlaceTy<'tcx>, | |||
) -> InterpResult<'tcx, EmulateItemResult> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So these here now return EmulateItemResult
but the ones in fs.rs
do not. As I said here I'd prefer to avoid having the EmulateItemResult
for functions that don't need it. It is extremely rare to need this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably just an oversight, I wanted to change all of them back.
@rustbot author |
Replace set_last_error with set_last_error_and_return Took care of the simple patterns. Other patterns involved setting an error and then using `write_int` or setting metadata and returning -1. Unsure if those are in the scope of this change Looks like this has conflicts with #3779, so I can update when how to handle that is decided. Part of #3930.
Replace set_last_error with set_last_error_and_return Took care of the simple patterns. Other patterns involved setting an error and then using `write_int` or setting metadata and returning -1. Unsure if those are in the scope of this change Looks like this has conflicts with #3779, so I can update when how to handle that is decided. Part of #3930.
Replace set_last_error with set_last_error_and_return Took care of the simple patterns. Other patterns involved setting an error and then using `write_int` or setting metadata and returning -1. Unsure if those are in the scope of this change Looks like this has conflicts with #3779, so I can update when how to handle that is decided. Part of #3930.
Replace set_last_error with set_last_error_and_return Took care of the simple patterns. Other patterns involved setting an error and then using `write_int` or setting metadata and returning -1. Unsure if those are in the scope of this change Looks like this has conflicts with #3779, so I can update when how to handle that is decided. Part of #3930.
alternative to #3777