-
Notifications
You must be signed in to change notification settings - Fork 356
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
Add shim for realpath
on unix
#2294
Conversation
This will likely fail on windows as I haven't tested it there yet (I don't have access to a windows box). |
086c8ee
to
55da284
Compare
I'm not sure why this test ran on windows, the file has |
As I said, everything in the test file refers to the target architecture. The failing test is running a Linux target on a Windows host. |
// Make sure we get an error for long paths. | ||
use std::convert::TryInto; | ||
let too_long = "x/".repeat(libc::PATH_MAX.try_into().unwrap()); | ||
assert!(canonicalize(too_long).is_err()); |
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.
Here we can also test the error kind, can't we?
tests/pass/libc.rs
Outdated
|
||
// Test that a long path returns an error. | ||
// | ||
// Linux first checks if the path to exists and macos does not. |
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 is that the behavior of running the code for real, or in Miri?
If the answer is "both", doesn't that mean that using a Linux target on a macOS host will behave differently than on a Linux host? Not sure if that is a problem though.
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.
Without miri, the test with a non-existent path fails on Linux and the same code succeeds on macos.
Yes, I am not sure it matters in practice though. I guess to be extra thorough I can catch the error in std::fs::canonicalize()
and adjust if target != host
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.
Is there an existing function that checks if target != host? I can't seem to find one though I feel like it probably exists in the codebase.
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.
No there is not. We don't want to ever actually check the host if we can help it, since behavior should be host-independent.
I guess POSIX does not specify whether a non-existing path returns an error or not? In that case this seems fine but there should be a comment in the implementation.
☔ The latest upstream changes (presumably #2306) made this pull request unmergeable. Please resolve the merge conflicts. |
Co-authored-by: Ralf Jung <[email protected]>
Co-authored-by: Ralf Jung <[email protected]>
I need to think about this some more but I am not sure the Windows path issue is workable based on the current fs code. Paths are part of the host environment leaking into the target environment. The target doesn't know how to operate on a host path. This hasn't been a problem because other syscalls just treat a path as an opaque pointer/handle to the filesystem, but the test I wrote for Because I think we need our own path abstraction so we can differentiate / translate between different path formats in miri code, or we need an entire filesystem abstraction? |
Yes. We had that problem before, in Note that functions like |
// the resolved pathname, and returns a pointer to this buffer. The | ||
// caller should deallocate this buffer using free(3)." | ||
// <https://man7.org/linux/man-pages/man3/realpath.3.html> | ||
this.alloc_os_str_as_c_str(resolved.as_os_str(), MiriMemoryKind::C.into())? |
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.
Oh I just realized this is a general os_str function, but it should be a path function to do the directory separator conversion. We need alloc_path_as_c_str
but such a function does not exist yet. Can you add it?
// before constructing a `PathBuf` | ||
|
||
#[cfg(windows)] | ||
return PathBuf::from(tmp.replace("/", "\\")); | ||
|
||
#[cfg(not(windows))] | ||
return PathBuf::from(tmp.replace("\\", "/")); |
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.
// before constructing a `PathBuf` | |
#[cfg(windows)] | |
return PathBuf::from(tmp.replace("/", "\\")); | |
#[cfg(not(windows))] | |
return PathBuf::from(tmp.replace("\\", "/")); | |
// before constructing a `PathBuf`. | |
return PathBuf::from(tmp.replace("\\", "/")); |
This is a non-windows test.
I'm still not sure this is enough. For example, unix target code calling https://doc.rust-lang.org/stable/std/path/struct.Path.html#method.has_root will use the unix logic described there but the underlying string will be in windows/host format so the result is not correct. Do we have a way to say "when running under miri, even though the target OS is unix, use the windows implementation of std::path::Path"?`` But even with that, non-std code can still go from a Path to an OSString and code under test may expect a certain format of the OSString. |
Yeah it's not perfect. But it might work for the test suite?
No, when the target is Unix, then we only have MIR for the Unix part of std available. |
☔ The latest upstream changes (presumably #2349) made this pull request unmergeable. Please resolve the merge conflicts. |
Going to close this and retool it a bit. |
What do you mean by "retool"? This was pretty closed to finished, I think. |
// | ||
// Rather than creating a bunch of directories, we create two directories containing symlinks. | ||
// Sadly we can't avoid creating directories and instead use a path like "./././././" or "./../../" as linux | ||
// appears to collapse "." and ".." before checking path length. |
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 see how this test makes any sense... the actual real path after resolving all those symlinks to /tmp/.../x
, i.e., it is very short. The test creates a very long input path but the interesting case is a very long output.
On my system this test produces a FilesystemLoop error.
Add shim for realpath on unix Salvaged from #2294 by `@LegNeato`
No description provided.