The expected behavior is that the environment's PATH should be used
to find the process. posix_spawn() could be used if we iterated
PATH to search for the binary to execute. For now just skip
posix_spawn() if PATH is modified.
spawn() is expected to return an error if the specified file could not be
executed. FreeBSD's posix_spawn() supports returning ENOENT/ENOEXEC if
the exec() fails, which not all platforms support. This brings a very
significant performance improvement for FreeBSD, involving heavy use of
Command in threads, due to fork() invoking jemalloc fork handlers and
causing lock contention. FreeBSD's posix_spawn() avoids this problem
due to using vfork() internally.
* Match definition of c_char in os/raw.rs with the libc definition
Due to historic reasons, os/raw.rs redefines types for c_char from
libc, but these didn't match. Now they do :).
* Enable signal reset on exec for L4Re
L4Re has full signal emulation and hence it needs to reset the
signal set of the child with sigemptyset. However, gid and uid
should *not* be set.
This is much nicer for callers who want to short-circuit real I/O errors
with `?`, because they can write this
if let Some(status) = foo.try_wait()? {
...
} else {
...
}
instead of this
match foo.try_wait() {
Ok(status) => {
...
}
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
...
}
Err(err) => return Err(err),
}
The original design of `try_wait` was patterned after the `Read` and
`Write` traits, which support both blocking and non-blocking
implementations in a single API. But since `try_wait` is never blocking,
it makes sense to optimize for the non-blocking case.
Tracking issue: https://github.com/rust-lang/rust/issues/38903
This commit adds a new method to the `Child` type in the `std::process` module
called `try_wait`. This method is the same as `wait` except that it will not
block the calling thread and instead only attempt to collect the exit status. On
Unix this means that we call `waitpid` with the `WNOHANG` flag and on Windows it
just means that we pass a 0 timeout to `WaitForSingleObject`.
Currently it's possible to build this method out of tree, but it's unfortunately
tricky to do so. Specifically on Unix you essentially lose ownership of the pid
for the process once a call to `waitpid` has succeeded. Although `Child` tracks
this state internally to be resilient to multiple calls to `wait` or a `kill`
after a successful wait, if the child is waited on externally then the state
inside of `Child` is not updated. This means that external implementations of
this method must be extra careful to essentially not use a `Child`'s methods
after a call to `waitpid` has succeeded (even in a nonblocking fashion).
By adding this functionality to the standard library it should help canonicalize
these external implementations and ensure they can continue to robustly reuse
the `Child` type from the standard library without worrying about pid ownership.