As described in https://github.com/rust-lang/rust/issues/68574, the currently exposed API for symlinks is, in fact, a thin wrapper around the corresponding syscall, and not suitable for public usage.
The reason is that the 2nd param in the call is expected to be a handle of a "preopened directory" (a WASI concept for exposing dirs), and the only way to retrieve such handle right now is by tinkering with a private `__wasilibc_find_relpath` API, which is an implementation detail and definitely not something we want users to call directly.
Making matters worse, the semantics of this param aren't obvious from its name (`fd`), and easy to misinterpret, resulting in people trying to pass a handle of the target file itself (as in https://github.com/vitiral/path_abs/pull/50), which doesn't work as expected.
I did a codesearch among open-source repos, and the usage above is so far the only usage of this API at all, but we should fix it before more people start using it incorrectly.
While this is technically a breaking API change, I believe it's a justified one, as 1) it's OS-specific and 2) there was strictly no way to correctly use the previous form of the API, and if someone does use it, they're likely doing it wrong like in the example above.
The new API does not lead to the same confusion, as it mirrors `std::os::unix::fs::symlink` and `std::os::windows::fs::symlink_{file,dir}` variants by accepting source/target paths.
Fixes#68574.
Stabilize `Seek::stream_position` (feature `seek_convenience`)
Tracking issue: #59359
Unresolved questions from tracking issue:
- "Override `stream_len` for `File`?" → we can do that in the future, this does not block stabilization.
- "Rename to `len` and `position`?" → as noted in the tracking issue, both of these shorter names have problems (`len` is usually a cheap getter, `position` clashes with `Cursor`). I do think the current names are perfectly fine.
- "Rename `stream_position` to `tell`?" → as mentioned in [the comment bringing this up](https://github.com/rust-lang/rust/issues/59359#issuecomment-559541545), `stream_position` is more descriptive. I don't think `tell` would be a good name.
What remains to decide, is whether or not adding these methods is worth it.
Trying to shrink_to greater than capacity should be no-op
Per the discussion in https://github.com/rust-lang/rust/issues/56431, `shrink_to` shouldn't panic if you try to make a vector shrink to a capacity greater than its current capacity.
Make std::future a re-export of core::future
After 1a764a7ef5, there are no `std::future`-specific items (except for `cfg(bootstrap)` items removed in 93eed402ad). So, instead of defining `std` own module, we can re-export the `core::future` directly.
Implement Error for &(impl Error)
Opening this up just to see what it breaks. It's unfortunate that `&(impl Error)` doesn't actually implement `Error`. If this direct approach doesn't work out then I'll try something different, like an `Error::by_ref` method.
**EDIT:** This is a super low-priority experiment so feel free to cancel it for more important crater runs! 🙂
-----
# Stabilization Report
## Why?
We've been working for the last few years to try "fix" the `Error` trait, which is probably one of the most fundamental in the whole standard library. One of its issues is that we commonly expect you to work with abstract errors through `dyn Trait`, but references and smart pointers over `dyn Trait` don't actually implement the `Error` trait. If you have a `&dyn Error` or a `Box<dyn Error>` you simply can't pass it to a method that wants a `impl Error`.
## What does this do?
This stabilizes the following trait impl:
```rust
impl<'a, T: Error + ?Sized + 'static> Error for &'a T;
```
This means that `&dyn Error` will now satisfy a `impl Error` bound.
It doesn't do anything with `Box<dyn Error>` directly. We discussed how we could do `Box<dyn Error>` in the thread here (and elsewhere in the past), but it seems like we need something like lattice-based specialization or a sprinkling of snowflake compiler magic to make that work. Having said that, with this new impl you _can_ now get a `impl Error` from a `Box<dyn Error>` by dereferencing it.
## What breaks?
A crater run revealed a few crates broke with something like the following:
```rust
// where e: &'short &'long dyn Error
err.source()
```
previously we'd auto-deref that `&'short &'long dyn Error` to return a `Option<&'long dyn Error>` from `source`, but now will call directly on `&'short impl Error`, so will return a `Option<&'short dyn Error>`. The fix is to manually deref:
```rust
// where e: &'short &'long dyn Error
(*err).source()
```
In the recent Libs meeting we considered this acceptable breakage.
Remove delay-binding for Win XP and Vista
The minimum supported Windows version is now Windows 7. Windows XP
and Windows Vista are no longer supported; both are already broken, and
require extra steps to use.
This commit removes the delayed-binding support for Windows API
functions that are present on all supported Windows targets. This has
several benefits: Removes needless complexity. Removes a load and
dynamic call on hot paths in mutex acquire / release. This may have
performance benefits.
* "Drop official support for Windows XP"
https://github.com/rust-lang/compiler-team/issues/378
* "Firefox has ended support for Windows XP and Vista"
https://support.mozilla.org/en-US/kb/end-support-windows-xp-and-vista
Inline methods of Path and OsString
These methods are not generic, and therefore aren't candidates for cross-crate inlining without an `#[inline]` attribute.
Document why not use concat! in dbg! macro
Original title: Reduce code generated by `dbg!` macro
The expanded code before/after: <https://rust.godbolt.org/z/hE3j95>.
---
We cannot use `concat!` since `file!` could contains `{` or the expression is a block (`{ .. }`).
Using it will generated malformed format strings.
So let's document this reason why we don't use `concat!` macro at all.
The minimum supported Windows version is now Windows 7. Windows XP
and Windows Vista are no longer supported; both are already broken, and
require extra steps to use.
This commit removes the delayed-binding support for Windows API
functions that are present on all supported Windows targets. This has
several benefits: Removes needless complexity. Removes a load and
dynamic call on hot paths in mutex acquire / release. This may have
performance benefits.
* "Drop official support for Windows XP"
https://github.com/rust-lang/compiler-team/issues/378
* "Firefox has ended support for Windows XP and Vista"
https://support.mozilla.org/en-US/kb/end-support-windows-xp-and-vista
std: Update wasi-libc commit of the wasm32-wasi target
This brings in an implementation of `current_dir` and `set_current_dir`
(emulation in `wasi-libc`) as well as an updated version of finding
relative paths. This also additionally updates clang to the latest
release to build wasi-libc with.
BufWriter: Provide into_raw_parts
If something goes wrong, one might want to unpeel the layers of nested
Writers to perform recovery actions on the underlying writer, or reuse
its resources.
`into_inner` can be used for this when the inner writer is still
working. But when the inner writer is broken, and returning errors,
`into_inner` simply gives you the error from flush, and the same
`Bufwriter` back again.
Here I provide the necessary function, which I have chosen to call
`into_raw_parts`.
I had to do something with `panicked`. Returning it to the caller as
a boolean seemed rather bare. Throwing the buffered data away in this
situation also seems unfriendly: maybe the programmer knows something
about the underlying writer and can recover somehow.
So I went for a custom Error. This may be overkill, but it does have
the nice property that a caller who actually wants to look at the
buffered data, rather than simply extracting the inner writer, will be
told by the type system if they forget to handle the panicked case.
If a caller doesn't need the buffer, it can just be discarded. That
WriterPanicked is a newtype around Vec<u8> means that hopefully the
layouts of the Ok and Err variants can be very similar, with just a
boolean discriminant. So this custom error type should compile down
to nearly no code.
*If this general idea is felt appropriate, I will open a tracking issue, etc.*
Don't use posix_spawn_file_actions_addchdir_np on macOS.
There is a bug on macOS where using `posix_spawn_file_actions_addchdir_np` with a relative executable path will cause `posix_spawnp` to return ENOENT, even though it successfully spawned the process in the given directory.
`posix_spawn_file_actions_addchdir_np` was introduced in macOS 10.15 first released in Oct 2019. I have tested macOS 10.15.7 and 11.0.1.
Example offending program:
```rust
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::process::*;
fn main() {
fs::create_dir_all("bar").unwrap();
fs::create_dir_all("foo").unwrap();
fs::write("foo/foo.sh", "#!/bin/sh\necho hello ${PWD}\n").unwrap();
let perms = fs::Permissions::from_mode(0o755);
fs::set_permissions("foo/foo.sh", perms).unwrap();
let c = Command::new("../foo/foo.sh").current_dir("bar").spawn();
eprintln!("{:?}", c);
}
```
This prints:
```
Err(Os { code: 2, kind: NotFound, message: "No such file or directory" })
hello /Users/eric/Temp/bar
```
I wanted to open this PR to get some feedback on possible solutions. Alternatives:
* Do nothing.
* Document the bug.
* Try to detect if the executable is a relative path on macOS, and avoid using `posix_spawn_file_actions_addchdir_np` only in that case.
I looked at the [XNU source code](https://opensource.apple.com/source/xnu/xnu-6153.141.1/bsd/kern/kern_exec.c.auto.html), but I didn't see anything obvious that would explain the behavior. The actual chdir succeeds, it is something else further down that fails, but I couldn't see where.
EDIT: I forgot to mention, relative exe paths with `current_dir` in general are discouraged (see #37868). I don't know if #37868 is fixable, since normalizing it would change the semantics for some platforms. Another option is to convert the executable to an absolute path with something like joining the cwd with the new cwd and the executable, but I'm uncertain about that.
Clarify what the effects of a 'logic error' are
This clarifies what a 'logic error' is (which is a term used to describe what happens if you put things in a hash table or btree and then use something like a refcell to break the internal ordering). This tries to be as vague as possible, as we don't really want to promise what happens, except "bad things, but not UB". This was discussed in #80657
This brings in an implementation of `current_dir` and `set_current_dir`
(emulation in `wasi-libc`) as well as an updated version of finding
relative paths. This also additionally updates clang to the latest
release to build wasi-libc with.
Deprecate atomic::spin_loop_hint in favour of hint::spin_loop
For https://github.com/rust-lang/rust/issues/55002
We wanted to leave `atomic::spin_loop_hint` alone when stabilizing `hint::spin_loop` so folks had some time to migrate. This now deprecates `atomic_spin_loop_hint`.
Fix handling of malicious Readers in read_to_end
A malicious `Read` impl could return overly large values from `read`, which would result in the guard's drop impl setting the buffer's length to greater than its capacity! ~~To fix this, the drop impl now uses the safe `truncate` function instead of `set_len` which ensures that this will not happen. The result of calling the function will be nonsensical, but that's fine given the contract violation of the `Read` impl.~~
~~The `Guard` type is also used by `append_to_string` which does not pass untrusted values into the length field, so I've copied the guard type into each function and only modified the one used by `read_to_end`. We could just keep a single one and modify it, but it seems a bit cleaner to keep the guard code close to the functions and related specifically to them.~~
To fix this, we now assert that the returned length is not larger than the buffer passed to the method.
For reference, this bug has been present for ~2.5 years since 1.20: ecbb896b9e.
Closes#80894.
Add a `std::io::read_to_string` function
I recognize that you're usually supposed to open an issue first, but the
implementation is very small so it's okay if this is closed and it was 'wasted
work' :)
-----
The equivalent of `std::fs::read_to_string`, but generalized to all
`Read` impls.
As the documentation on `std::io::read_to_string` says, the advantage of
this function is that it means you don't have to create a variable first
and it provides more type safety since you can only get the buffer out
if there were no errors. If you use `Read::read_to_string`, you have to
remember to check whether the read succeeded because otherwise your
buffer will be empty.
It's friendlier to newcomers and better in most cases to use an explicit
return value instead of an out parameter.
Add missing methods to unix ExitStatusExt
These are the methods corresponding to the remaining exit status examination macros from `wait.h`. `WCOREDUMP` isn't in SuS but is it is very standard. I have not done portability testing to see if this builds everywhere, so I may need to Do Something if it doesn't.
There is also a bugfix and doc improvement to `.signal()`, and an `.into_raw()` accessor.
This would fix#73128 and fix#73129. Please let me know if you like this direction, and if so I will open the tracking issue and so on.
If this MR goes well, I may tackle #73125 next - I have an idea for how to do it.
This is not particularly pretty but the current situation is a mess
and I don't think I'm making it significantly worse.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
As discussed in #79982.
I think the "new interfaces", ie the new trait and impl, must be
insta-stable. This seems OK because we are, in fact, adding a new
restriction to the stable API.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>