about summary refs log tree commit diff
path: root/library/std/src/sys/unix/process
AgeCommit message (Collapse)AuthorLines
2021-08-19I/O safety.Dan Gohman-7/+8
Introduce `OwnedFd` and `BorrowedFd`, and the `AsFd` trait, and implementations of `AsFd`, `From<OwnedFd>` and `From<T> for OwnedFd` for relevant types, along with Windows counterparts for handles and sockets. Tracking issue: - <https://github.com/rust-lang/rust/issues/87074> RFC: - <https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md>
2021-08-10STD support for the ESP-IDF frameworkivmarkov-0/+125
2021-08-01Auto merge of #81825 - voidc:pidfd, r=joshtriplettbors-3/+174
Add Linux-specific pidfd process extensions (take 2) Continuation of #77168. I addressed the following concerns from the original PR: - make `CommandExt` and `ChildExt` sealed traits - wrap file descriptors in `PidFd` struct representing ownership over the fd - add `take_pidfd` to take the fd out of `Child` - close fd when dropped Tracking Issue: #82971
2021-07-21VxWorks does provide sigemptyset and sigaddsetNicholas Baron-1/+1
2021-07-21Add tracking issue and link to man-pageDominik Stolz-1/+1
2021-07-21Add PidFd type and seal traitsDominik Stolz-88/+155
Improve docs Split do_fork into two Make do_fork unsafe Add target attribute to create_pidfd field in Command Add method to get create_pidfd value
2021-07-21Typo fixJosh Triplett-1/+1
Co-authored-by: bjorn3 <bjorn3@users.noreply.github.com>
2021-07-21Add Linux-specific pidfd process extensionsAaron Hill-6/+110
Background: Over the last year, pidfd support was added to the Linux kernel. This allows interacting with other processes. In particular, this allows waiting on a child process with a timeout in a race-free way, bypassing all of the awful signal-handler tricks that are usually required. Pidfds can be obtained for a child process (as well as any other process) via the `pidfd_open` syscall. Unfortunately, this requires several conditions to hold in order to be race-free (i.e. the pid is not reused). Per `man pidfd_open`: ``` · the disposition of SIGCHLD has not been explicitly set to SIG_IGN (see sigaction(2)); · the SA_NOCLDWAIT flag was not specified while establishing a han‐ dler for SIGCHLD or while setting the disposition of that signal to SIG_DFL (see sigaction(2)); and · the zombie process was not reaped elsewhere in the program (e.g., either by an asynchronously executed signal handler or by wait(2) or similar in another thread). If any of these conditions does not hold, then the child process (along with a PID file descriptor that refers to it) should instead be created using clone(2) with the CLONE_PIDFD flag. ``` Sadly, these conditions are impossible to guarantee once any libraries are used. For example, C code runnng in a different thread could call `wait()`, which is impossible to detect from Rust code trying to open a pidfd. While pid reuse issues should (hopefully) be rare in practice, we can do better. By passing the `CLONE_PIDFD` flag to `clone()` or `clone3()`, we can obtain a pidfd for the child process in a guaranteed race-free manner. This PR: This PR adds Linux-specific process extension methods to allow obtaining pidfds for processes spawned via the standard `Command` API. Other than being made available to user code, the standard library does not make use of these pidfds in any way. In particular, the implementation of `Child::wait` is completely unchanged. Two Linux-specific helper methods are added: `CommandExt::create_pidfd` and `ChildExt::pidfd`. These methods are intended to serve as a building block for libraries to build higher-level abstractions - in particular, waiting on a process with a timeout. I've included a basic test, which verifies that pidfds are created iff the `create_pidfd` method is used. This test is somewhat special - it should always succeed on systems with the `clone3` system call available, and always fail on systems without `clone3` available. I'm not sure how to best ensure this programatically. This PR relies on the newer `clone3` system call to pass the `CLONE_FD`, rather than the older `clone` system call. `clone3` was added to Linux in the same release as pidfds, so this shouldn't unnecessarily limit the kernel versions that this code supports. Unresolved questions: * What should the name of the feature gate be for these newly added methods? * Should the `pidfd` method distinguish between an error occurring and `create_pidfd` not being called?
2021-07-10Change `weak!` and `linkat!` to macros 2.0Aris Merchant-0/+8
`weak!` is needed in a test in another module. With macros 1.0, importing `weak!` would require reordering module declarations in `std/src/lib.rs`, which is a bit too evil.
2021-05-20Add `ExitStatusError` for `vxworks`Christiaan Dirkx-3/+29
2021-05-18Auto merge of #82973 - ijackson:exitstatuserror, r=yaahcbors-7/+52
Provide ExitStatusError Closes #73125 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
2021-05-13Tolerate SIGTRAP for panic abort after panic::always_abortIan Jackson-1/+1
Some platforma (eg ARM64) apparently generate SIGTRAP for panic abort! See eg https://github.com/rust-lang/rust/pull/81858#issuecomment-840702765 This is probably a bug, but we don't want to entangle this MR with it. When it's fixed, this commit should be reverted. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-05-12Provide ExitStatusErrorIan Jackson-7/+52
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>
2021-05-07panic/fork test: Do not run on emscriptenIan Jackson-0/+1
fork fails there. The failure message is confusing: so c.status() returns an Err, the closure panics, and the test thinks the panic was propagated from inside the child. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk> Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
2021-05-07panic ui test: Provide comprehensive test for panic after forkIan Jackson-0/+3
This tests that we can indeed safely panic after fork, both a raw libc::fork and in a Command pre_exec hook. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk> Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
2021-05-07panic tests: Command: Test that we do not unwind past forkIan Jackson-0/+23
This is safe (does not involve heap allocation) but we don't yet have a test to ensure that stays true. That will come in a moment. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk> Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
2021-05-07panic/fork: Command: Do not unwind after fork() in childIan Jackson-0/+1
Unwinding after fork() in the child is UB on some platforms, because on those (including musl) malloc can be UB in the child of a multithreaded program, and unwinding must box for the payload. Even if it's safe, unwinding past fork() in the child causes whatever traps the unwind to return twice. This is very strange and clearly not desirable. With the default behaviour of the thread library, this can even result in a panic in the child being transformed into zero exit status (ie, success) as seen in the parent! Fixes #79740. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-05-02Change 'NULL' to 'null'Brent Kerby-1/+1
2021-04-21Apply suggestions from code reviewChristiaan Dirkx-2/+4
2021-04-19Fix `vxworks` compilation errorsChristiaan Dirkx-2/+20
2021-04-19Move `sys::vxworks` code to `sys::unix`Christiaan Dirkx-8/+231
2021-03-29Simplify Command::spawn (no semantic change)Josh Triplett-33/+27
This minimizes the size of an unsafe block, and allows outdenting some complex code.
2021-03-28Rollup merge of #83462 - ijackson:exitstatus-message-wording, r=joshtriplettYuki Okushi-3/+3
ExitStatus: print "exit status: {}" rather than "exit code: {}" on unix Proper Unix terminology is "exit status" (vs "wait status"). "exit code" is imprecise on Unix and therefore unclear. (As far as I can tell, "exit code" is correct terminology on Windows.) This new wording is unfortunately inconsistent with the identifier names in the Rust stdlib. It is the identifier names that are wrong, as discussed at length in eg https://doc.rust-lang.org/nightly/std/process/struct.ExitStatus.html https://doc.rust-lang.org/nightly/std/os/unix/process/trait.ExitStatusExt.html Unfortunately for API stability reasons it would be a lot of work, and a lot of disruption, to change the names in the stdlib (eg to rename `std::process::ExitStatus` to `std::process::ChildStatus` or something), but we should fix the message output. Many (probably most) readers of these messages about exit statuses will be users and system administrators, not programmers, who won't even know that Rust has this wrong terminology. So I think the right thing is to fix the documentation (as I have already done) and, now, the terminology in the implementation. This is a user-visible change to the behaviour of all Rust programs which run Unix subprocesses. Hopefully no-one is matching against the exit status string, except perhaps in tests.
2021-03-25ExitStatus: print "exit status: {}" rather than "exit code: {}"Ian Jackson-3/+3
Proper Unix terminology is "exit status" (vs "wait status"). "exit code" is imprecise on Unix and therefore unclear. (As far as I can tell, "exit code" is correct terminology on Windows.) This new wording is unfortunately inconsistent with the identifier names in the Rust stdlib. It is the identifier names that are wrong, as discussed at length in eg https://doc.rust-lang.org/nightly/std/process/struct.ExitStatus.html https://doc.rust-lang.org/nightly/std/os/unix/process/trait.ExitStatusExt.html Unfortunately for API stability reasons it would be a lot of work, and a lot of disruption, to change the names in the stdlib (eg to rename `std::process::ExitStatus` to `std::process::ChildStatus` or something), but we should fix the message output. Many (probably most) readers of these messages about exit statuses will be users and system administrators, not programmers, who won't even know that Rust has this wrong terminology. So I think the right thing is to fix the documentation (as I have already done) and, now, the terminology in the implementation. This is a user-visible change to the behaviour of all Rust programs which run Unix subprocesses. Hopefully no-one is matching against the exit status string, except perhaps in tests. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-03-24Rollup merge of #83353 - m-ou-se:io-error-avoid-alloc, r=nagisaDylan DPC-11/+20
Add internal io::Error::new_const to avoid allocations. This makes it possible to have a io::Error containing a message with zero allocations, and uses that everywhere to avoid the *three* allocations involved in `io::Error::new(kind, "message")`. The function signature isn't perfect, because it needs a reference to the `&str`. So for now, this is just a `pub(crate)` function. Later, we'll be able to use `fn new_const<MSG: &'static str>(kind: ErrorKind)` to make that a bit better. (Then we'll also be able to use some ZST trickery if that would result in more efficient code.) See https://github.com/rust-lang/rust/issues/83352
2021-03-21Use io::Error::new_const everywhere to avoid allocations.Mara Bos-11/+20
2021-03-14Revert "Revert "use RWlock when accessing os::env #81850""The8472-3/+3
This reverts commit acdca316c3d42299d31c1b47eb792006ffdfc29c.
2021-03-10Rollup merge of #82949 - the8472:forget-envlock-on-fork, r=joshtriplettDylan DPC-6/+9
Do not attempt to unlock envlock in child process after a fork. This implements the first two points from https://github.com/rust-lang/rust/issues/64718#issuecomment-793030479 This is a breaking change for cases where the environment is accessed in a Command::pre_exec closure. Except for single-threaded programs these uses were not correct anyway since they aren't async-signal safe. Note that we had a ui test that explicitly tried `env::set_var` in `pre_exec`. As expected it failed with these changes when I tested locally.
2021-03-10Rollup merge of #82411 - ijackson:fix-exitstatus, r=dtolnayYuki Okushi-2/+45
Fixes to ExitStatus and its docs * On Unix, properly display every possible wait status (and don't panic on weird values) * In the documentation, be clear and consistent about "exit status" vs "wait status".
2021-03-09Do not attempt to unlock envlock in child process after a fork.The8472-6/+9
This is a breaking change for cases where the environment is accessed in a Command::pre_exec closure. Except for single-threaded programs these uses were not correct anyway since they aren't async-signal safe.
2021-03-09Always compile the fragile wait status test cases, just run them conditionallyIan Jackson-6/+7
Co-authored-by: David Tolnay <dtolnay@gmail.com>
2021-03-07Revert "use RWlock when accessing os::env #81850"Eric Huss-3/+3
This reverts commit 354f19cf2475148994954b6783341620c7445071, reversing changes made to 0cfba2fd090834c909d5ed9deccdee8170da791b.
2021-03-04ExitStatus tests: Make less legible to satisfy "tidy"Ian Jackson-2/+4
I strongly disagree with tidy in this case but AIUI there is no way to override it. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-03-04ExitStatus unknown wait status test: Make it Linux onlyIan Jackson-1/+1
If different unices have different bit patterns for WIFSTOPPED and WIFCONTINUED then simply being glibc is probably not good enough for this rather ad-hoc test to work. Do it on Linux only. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-03-04ExitStatus stop signal display test: Make it Linux onlyIan Jackson-2/+7
MacOS uses a different representation. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-02-23Update outdated comment in unix Command.Eric Huss-17/+5
2021-02-23process::unix: Test wait status formattingIan Jackson-0/+26
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-02-22process::unix: Handle other wait statuses in ExitStatus as DisplayIan Jackson-2/+11
Currently, on Nightly, this panics: ``` use std::process::ExitStatus; use std::os::unix::process::ExitStatusExt; fn main() { let st = ExitStatus::from_raw(0x007f); println!("st = {}", st); } ``` This is because the impl of Display assumes that if .code() is None, .signal() must be Some. That was a false assumption, although it was true with buggy code before 5b1316f78152a9c066b357ea9addf803d48e114a unix ExitStatus: Do not treat WIFSTOPPED as WIFSIGNALED This is not likely to have affected many people in practice, because `Command` will never produce such a wait status (`ExitStatus`). Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-02-08introduce StaticRWLock wrapper to make methods safeThe8472-3/+3
2021-02-07use rwlock for accessing ENVThe8472-3/+3
2021-01-21Add setgroups to std::os::unix::process::CommandExtslo1-7/+23
2021-01-20Deprecate-in-future the constants superceded by RFC 2700bstrie-1/+0
2021-01-17Don't use posix_spawn_file_actions_addchdir_np on macOS.Eric Huss-4/+14
2021-01-13Fix typos in Fuchsia unix_process_wait_moreDavid Tolnay-2/+2
2021-01-13ExitStatusExt: Fix build on FuchsiaIan Jackson-0/+44
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>
2021-01-13unix ExitStatus: Provide .continued()Ian Jackson-0/+4
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-01-13unix ExitStatus: Provide .stopped_signal()Ian Jackson-0/+4
Necessary to handle WIFSTOPPED. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-01-13unix ExitStatus: Provide .core_dumpedIan Jackson-0/+4
This is essential for proper reporting of child process status on Unix. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-01-13unix ExitStatus: Provide .into_raw()Ian Jackson-0/+4
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-01-13unix ExitStatus: Do not treat WIFSTOPPED as WIFSIGNALEDIan Jackson-1/+1
A unix wait status can contain, at least, exit statuses, termination signals, and stop signals. WTERMSIG is only valid if WIFSIGNALED. https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html It will not be easy to experience this bug with `Command`, because that doesn't pass WUNTRACED. But you could make an ExitStatus containing, say, a WIFSTOPPED, from a call to one of the libc wait functions. (In the WIFSTOPPED case, there is WSTOPSIG. But a stop signal is encoded differently to a termination signal, so WTERMSIG and WSTOPSIG are by no means the same.) Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>