In the docs for intrinsics::abort():
* Strengthen the recommendation by to use process::abort instead.
* Document the fact that it (ab)uses an LLVM debug trap and what the
likely consequences are.
* State that the precise behaviour is unstable.
In the docs for process::abort():
* Promise that we have the same behaviour as C `abort()`.
* Document the likely consequences, including, specifically, the
consequences on Unix.
In the internal comment for unix::abort_internal:
* Refer to the public docs for the public API functions.
* Correct and expand the description of libc::abort. Specifically:
* Do not claim that abort() unregisters signal handlers. It doesn't;
it honours the SIGABRT handler.
* Discuss, extensively, the issue with abort() flushing stdio buffers.
* Describe the glibc behaviour in some detail.
Co-authored-by: Mark Wooding <mdw@distorted.org.uk>
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Remove & from Command::args calls in documentation
Now that arrays implement `IntoIterator`, using `&` is no longer necessary. This makes examples easier to understand.
Redefine `ErrorKind::Other` and stop using it in std.
This implements the idea I shared yesterday in the libs meeting when we were discussing how to handle adding new `ErrorKind`s to the standard library: This redefines `Other` to be for *user defined errors only*, and changes all uses of `Other` in the standard library to a `#[doc(hidden)]` and permanently `#[unstable]` `ErrorKind` that users can not match on. This ensures that adding `ErrorKind`s at a later point in time is not a breaking change, since the user couldn't match on these errors anyway. This way, we use the `#[non_exhaustive]` property of the enum in a more effective way.
Open questions:
- How do we check this change doesn't cause too much breakage? Will a crate run help and be enough?
- How do we ensure we don't accidentally start using `Other` again in the standard library? We don't have a `pub(not crate)` or `#[deprecated(in this crate only)]`.
cc https://github.com/rust-lang/rust/pull/79965
cc `@rust-lang/libs` `@ijackson`
r? `@dtolnay`
It is unergnomic to have to say things like
bad.into_status().signal()
Implementing `ExitStatusExt` for `ExitStatusError` fixes this.
Unfortunately it does mean making a previously-infallible method
capable of panicing, although of course the existing impl remains
infallible.
The alternative would be a whole new `ExitStatusErrorExt` trait.
`<ExitStatus as ExitStatusExt>::into_raw()` is not particularly
ergonomic to call because of the often-required type annotation.
See for example the code in the test case in
library/std/src/sys/unix/process/process_unix/tests.rs
Perhaps we should provide equivalent free functions for `ExitStatus`
and `ExitStatusExt` in std::os::unix::process and maybe deprecate this
trait method. But I think that is for the future.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Closes#73125
This is in pursuance of
Issue #73127 Consider adding #[must_use] to std::process::ExitStatus
In
MR #81452 Add #[must_use] to [...] process::ExitStatus
we concluded that the existing arrangements in are too awkward
so adding that #[must_use] is blocked on improving the ergonomics.
I wrote a mini-RFC-style discusion of the approach in
https://github.com/rust-lang/rust/issues/73125#issuecomment-771092741
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Demonstrate best practice for feeding stdin of a child processes
Documentation change.
It's possible to create a deadlock with stdin/stdout I/O on a single thread:
* the child process may fill its stdout buffer, and have to wait for the parent process to read it,
* but the parent process may be waiting until its stdin write finishes before reading the stdout.
Therefore, the parent process should use separate threads for writing and reading.
These examples are not deadlocking in practice, because they use short strings, but I think it's better to demonstrate code that works even for long writes. The problem is non-obvious and tricky to debug (it seems that even libstd has a similar issue: #45572).
This also demonstrates how to use stdio with threads: it's not obvious that `.take()` can be used to avoid fighting with the borrow checker.
I've checked that the modified examples run fine.
It's possible to create a deadlock with stdin/stdout I/O on a single thread:
* the child process may fill its stdout buffer, and have to wait for the parent process to read it,
* but the parent process may be waiting until its stdin write finishes before reading the stdout.
Therefore, the parent process should use separate threads for writing and reading.
The use of `ExitStatus` as the Rust type name for a Unix *wait
status*, not an *exit status*, is very confusing, but sadly probably
too late to change.
This area is confusing enough in Unix already (and many programmers
are already confuxed). We can at least document it.
I chose *not* to mention the way shells like to exit with signal
numbers, thus turning signal numbers into exit statuses. This is only
relevant for Rust programs using `std::process` if they run shells.
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Drop support for all cloudabi targets
`cloudabi` is a tier-3 target, and [it is no longer being maintained upstream][no].
This PR drops supports for cloudabi targets. Those targets are:
* aarch64-unknown-cloudabi
* armv7-unknown-cloudabi
* i686-unknown-cloudabi
* x86_64-unknown-cloudabi
Since this drops supports for a target, I'd like somebody to tag `relnotes` label to this PR.
Some other issues:
* The tidy exception for `cloudabi` crate is still remained because
* `parking_lot v0.9.0` and `parking_lot v0.10.2` depends on `cloudabi v0.0.3`.
* `parking_lot v0.11.0` depends on `cloudabi v0.1.0`.
[no]: https://github.com/NuxiNL/cloudabi#note-this-project-is-unmaintained
deny(unsafe_op_in_unsafe_fn) in libstd/process.rs
The libstd/process.rs part of #73904 . Wraps the two calls to an unsafe fn Initializer::nop() in an unsafe block.
Will have to wait for #73909 to be merged, because of the feature in the libstd/lib.rs
As a relative beginner, it took a while for me to figure out I could just steal the references to avoid partially moving the child and thus retain ability to call functions on it (and store it in structs etc).