Skip to content
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

Support getting file metadata on Windows #4067

Open
wants to merge 22 commits into
base: master
Choose a base branch
from

Conversation

CraftSpider
Copy link
Contributor

@CraftSpider CraftSpider commented Dec 2, 2024

Main changes are the first two commits - one refactors handles a bit to make their usage more consistent and adds the file variant, the other actually adds the metadata shims.

This also changes miri to never return invalid handle errors, instead always treating them as an error. This behavior matches that of code running under the MSVC debugger - invalid handles are treated as exceptions in debug contexts.

Split off #4043

- consistent handling, invalid handles are always an abort
- Helper for reading handles that does the checking and machine stop
- Use real handle types more places
- Adds `File` and `Invalid` types of handle. File support will be added next
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also add a test that directly calls the relevant Windows API functions? std sometimes changes what it uses and then we lose test coverge, which is not great.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a windows-fs test for the shims directly

Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Here are some comments for the first and last commit, I skipped the second one for now.

src/shims/windows/handle.rs Outdated Show resolved Hide resolved
src/shims/windows/handle.rs Show resolved Hide resolved
src/shims/windows/handle.rs Outdated Show resolved Hide resolved
src/shims/windows/handle.rs Outdated Show resolved Hide resolved
src/shims/windows/handle.rs Show resolved Hide resolved
src/shims/windows/handle.rs Outdated Show resolved Hide resolved
src/shims/windows/handle.rs Outdated Show resolved Hide resolved
src/shims/windows/handle.rs Outdated Show resolved Hide resolved
tests/pass/shims/fs.rs Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
@CraftSpider
Copy link
Contributor Author

CraftSpider commented Dec 6, 2024

Before we get too much further on this PR, I'd like to point out 296d806 (which I just pushed) on the big PR. It's the changes needed to FileDescription methods to make them platform-agnostic enough for Windows use-cases. If they look fine, we can continue, but if you think it's a bad design then the FileDescription trait will need entirely split in two, which will change code even in this PR.

@RalfJung
Copy link
Member

RalfJung commented Dec 6, 2024

Reducing the places where we have to use global state like errno seems like an improvement. But please use Result<_, IoError> (with Miri's IoError type).

@CraftSpider
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added the S-waiting-on-review Status: Waiting for a review to complete label Dec 6, 2024
src/shims/windows/handle.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
const TIME_TO_EPOCH: u64 = 31_556_926 * 369 * 10_000_000;
match time.ok() {
Some(time) => {
let duration = system_time_to_duration(&time)?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably rename this to system_time_since_unix_epoch. (Can be a future PR though.)

@RalfJung
Copy link
Member

RalfJung commented Dec 7, 2024

Okay I finally had a look at the core new file in this PR. :)
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels Dec 7, 2024
src/shims/windows/fs.rs Outdated Show resolved Hide resolved
@CraftSpider
Copy link
Contributor Author

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Waiting for a review to complete and removed S-waiting-on-author Status: Waiting for the PR author to address review comments labels Dec 9, 2024
@bors
Copy link
Contributor

bors commented Dec 12, 2024

☔ The latest upstream changes (presumably #4068) made this pull request unmergeable. Please resolve the merge conflicts.

Comment on lines 113 to 115
if !(file_attribute_normal | file_flag_backup_semantics | file_flag_open_reparse_point)
& flags_and_attributes
!= 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another one of these bitmasks where validation is separate from interpretation. I don't understand all these flags so I am not sure, can this be done in a better way? There should be one if for each of these 3 cases, performing whatever action the respective flag should perform.

Maybe Windows file flag parsing is so complicated that we should have a separate function that takes in the raw flaws as u32s and returns some nice typed representation?

file_flag_backup_semantics is sus because it is considered supported here but entirely ignored later.

options.create_new(true);
// Per `create_new` documentation:
// If the specified file does not exist and is a valid path to a writable location, the
// function creates a file and the last-error code is set to zero.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setting to zero does not seem to happen here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the wrong copy-paste - I meant to put the std docs for create_new here. Microsoft doesn't say anything about zero error here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have access to a Windows host, maybe you can try this:

  • make sure the last error is non-zero
  • then call CreateFile in one of the cases where the docs say nothing about the last error, and see what the last error looks like when the function returns successfully

}
options.create(true);
} else if creation_disposition == open_existing {
// Nothing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this does not reset the error code to 0?

Maybe we should just set it to 0 at the top, to make sure we don't forget?

@@ -275,6 +275,9 @@ impl VisitProvenance for WeakFileDescriptionRef {
}
}

/// Internal type of a file-descriptor - this is what [`FdTable`] expects
pub type FdNum = i32;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also use this type in the definition of FdTable

Comment on lines 205 to 209
// This is racy, but there doesn't appear to be an std API that both succeeds if a file
// exists but tells us it isn't new. Either we accept racing one way or another, or we
// use an iffy heuristic like file creation time. This implementation prefers to fail in the
// direction of erroring more often.
let exists = file_name.exists();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is too early, since one doesn't know yet that this is used for. IMO it'd be better placed at the if exists below.

(Also, no need to let-bind, I don't feel like this makes things much clearer.)

@RalfJung
Copy link
Member

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: Waiting for the PR author to address review comments and removed S-waiting-on-review Status: Waiting for a review to complete labels Dec 12, 2024
/// This must be passed to allow getting directory handles. If not passed, we error on trying
/// to open directories
const BACKUP_SEMANTICS = 1 << 1;
const OPEN_REPARSE = 1 << 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you doc-comment this one as well? "reparse" is not standard terminology outside the Windows world.

Comment on lines +137 to +139
if out == FileAttributes::ZERO {
out = FileAttributes::NORMAL;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this done?

this.set_last_error(IoError::WindowsError("ERROR_ALREADY_EXISTS"))?;
} else {
this.set_last_error(IoError::Raw(Scalar::from_u32(0)))?;
OpenExisting => (), // Nothing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
OpenExisting => (), // Nothing
OpenExisting => {} // Default options

@rustbot
Copy link
Collaborator

rustbot commented Dec 29, 2024

☔ The latest upstream changes (possibly 887b498) made this pull request unmergeable. Please resolve the merge conflicts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: Waiting for the PR author to address review comments
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants