Redo cargo-miri logic
This rewrite the cargo-miri logic for running the requested crate(s) following what we outlined in https://github.com/rust-lang/miri/issues/739: `cargo miri run/test $FLAGS` (almost) literally invokes `cargo run/test $FLAGS` but with some environment variables set so that we can control what happens:
* `RUSTC_WRAPPER` is set so that we get invoked instead of `rustc`. We use that power to mess with the flags being used for the build (things to be interpreted by Miri use a different sysroot), and when we are detecting a binary crate meant to be run by Miri, we grab the info we care about and put it into a JSON file for later use.
* `CARGO_TARGET_$TARGET_RUNNER` is set so what we get invoked when cargo wants to run a binary. At that point we take that JSON info from before and use it to invoke Miri.
Overall this works great! We get all sorts of cargo magic for free, and do not even need `cargo-metadata` any more. There's one annoying point though, which I have not managed to entirely work around yet: this means we are doing a full build, not just a check-build. Given that our sysroot is MIR-only, I was surprised that this even worked, but still -- this means we are doing more work than we should. So I also added some patching of arguments to make sure `--emit` does not contain `link`, and then more patching was required of the `--extern` flags for the binary because those referenced the `.rlib` files but now only `.rmeta` exists, and that is still not fully working because cargo seems to expect those `.rmeta` files and now triggers a rebuild each time as those files are still missing. My current plan is to make our wrapper create some empty dummy files with the right names, but the amount of hacks we are stacking on top of each other here is getting worrysome.^^ `@ehuss` your input would be welcome on this issue.
Due to re-using cargo more literally, this also changes flag parsing to match `cargo`. So `-Zmiri` flags now have to be passed via an environment variable (Cc https://github.com/rust-lang/miri/issues/1416).
This PR is not ready yet, but the parts that are there I think can be reviewed already. TODO:
* [x] [Fix Windows](https://github.com/rust-lang/miri/pull/1540#issuecomment-688733741).
* [x] Figure out how we can do check-only builds without the rebuild problem above. ~~I am also worried about cases where `build.rs` script might detect check-only builds and then do less work; I think some crates in rustc are doing that and if this is a thing in the wider ecosystem we need to find a way to support this as well.~~ (postponed that until we have a concrete example)
* [x] Currently cargo runs doctests as well, and they are not run in Miri. We should at least figure out a way to not run them at all (resolving https://github.com/rust-lang/miri/issues/584 is left for a future PR).
* [x] For some time, detect the old way of passing `-Zmiri` flags and warn that this will need updating. For some simple situations we can probably make it still support the old way, but I plan to remove those hacks after a bit. This is just to give people and me time to go around and send PRs to all projects that use Miri on CI, and update their use of the flags.
* [x] Add a test for stdin handling (https://github.com/rust-lang/miri/issues/1505). This should work now but we should be sure.
* [x] Add a test for cargo env vars (https://github.com/rust-lang/miri/issues/1515).
* [x] Check if https://github.com/rust-lang/miri/issues/1516 is resolved.
* [x] Check if https://github.com/rust-lang/miri/issues/1001 and https://github.com/rust-lang/miri/issues/1514 are resolved.
* [x] Check if https://github.com/rust-lang/miri/issues/1312 is resolved (not sure if it is wort adding a test).
* [x] Check if https://github.com/rust-lang/miri/issues/1512 is resolved (not sure if it is wort adding a test).
Fixes https://github.com/rust-lang/miri/issues/700.
Fixes https://github.com/rust-lang/miri/issues/739.
Fixes https://github.com/rust-lang/miri/issues/1001.
Fixes https://github.com/rust-lang/miri/issues/1312 (without a test, as we run without cargo's stdin/stdout wrapping now, as the test for stdin confirms).
Fixes https://github.com/rust-lang/miri/issues/1416.
Fixes https://github.com/rust-lang/miri/issues/1505.
Fixes https://github.com/rust-lang/miri/issues/1512 (without a test, as cargo now does all that handling anyway, which various other tests confirm).
Fixes https://github.com/rust-lang/miri/issues/1514.
Fixes https://github.com/rust-lang/miri/issues/1516.
Cc `@alecmocatta` who reported many of the bugs above; would be great if you could help with the tests e.g. by providing some small examples I could try.
r? `@oli-obk`
Support F_DUPFD on stdin/stdout/stderr
Enable `close`-ing stdin/stdout/stderr
For `dup`, check if FD is `File` first
If not, clone the appropriate standard IO stream
Merge POSIX `close` and `dup` tests into same module
Also, add assertion that `write` on a closed FD returns an error.
Add `dup` as FileDescriptor trait fn
Also:
- Fix `close` so it drops `self` instead of reference to it
- Remove FD clamping in insert_fd_with_min_fd, since FDs 0-2 can be
closed
Fix fs_libc tests
Make error message when closing stdin/out/err more specific
Return io::Result from `FileDescriptor::dup`
Change error message when closing stdin/out/err
Refactor `FileDescriptor::dup` impl for `FileHandle`
Remove empty line
Bubble up errors from FileDescriptor::as_file_handle
Instead of indicating incorrectly that a handle was not found, return the error from `as_file_handle` indicating the operation is not supported on the FD.
Addresses some comments in #1495
Add FileDescriptor trait to abstract fn's on File's and Stdin,Stdout,Stderr
Related issue: #1486
Instead of mapping FDs to `FileHandle`, map them to a `FileDescriptor` trait object. The goal is to eventually have both `FileHandle` as well as `Stdin`, `Stdout` and `Stderr` implement this trait so that syscalls involving FDs can handle both `File`s as well as the standard IO streams.
This PR adds the `FileDescriptor` trait and an `impl` for `FileHandle`. I'll open a separate PR for implementing the trait for the standard IO streams.
The outer InterpResult will be used to indicate that a fn is not
implemented for a struct(eg. `write` for Stdin).
The inner io::Result is just the result from the read/write/seek.
Re-organize platform-specific shims
Move platform-specific code to `shims::{posix::{linux, macos}, windows}`. Also make it private in these modules to ensure we are reasonably structured.
Add file sync shims
This PR adds shim implementations for these related file syncing functions.
* `fsync`, for POSIX targets, backed by `File::sync_all()`
* `fdatasync`, for POSIX targets, backed by `File::sync_data()`
* `fcntl` with command `F_FULLFSYNC`, for macOS targets, backed by `File::sync_all()`
* `sync_file_range`, for Linux targets, backed by `File::sync_data()`
Move cargo-miri into separate package
So far, `cargo-miri` depended on the Miri library crate. That was mostly for convenience (to avoid having to deal with workspaces), but also because until recently `cargo-miri` needed access to the ["Miri default flags"](af044209b0/src/lib.rs (L75)). But with `MIRI_BE_RUSTC` that is no longer the case, so we can remove this fake dependency. :)
@oli-obk what do you think? Also I expect the rustc bootstrap integration will need updates, hints would be appreciated. :D