rust/library/std/src
Aaron Hill 694be09b7b Add Linux-specific pidfd process extensions
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-21 10:49:11 +02:00
..
backtrace Add Frames iterator for Backtrace 2021-01-23 11:56:33 -06:00
collections Remove "length" doc aliases 2021-06-30 20:28:51 +01:00
env std: move "mod tests/benches" to separate files 2020-08-31 02:56:59 +00:00
error std: move "mod tests/benches" to separate files 2020-08-31 02:56:59 +00:00
f32 More lerp tests, altering lerp docs 2021-06-13 14:00:15 -04:00
f64 More lerp tests, altering lerp docs 2021-06-13 14:00:15 -04:00
ffi Remove "length" doc aliases 2021-06-30 20:28:51 +01:00
fs Make tests pass on old macos 2021-07-10 12:59:25 -07:00
io Rollup merge of #86794 - inquisitivecrystal:seek-rewind, r=m-ou-se 2021-07-06 02:33:15 +09:00
lazy Upgrade wasm32 image to Ubuntu 20.04 2021-02-06 13:05:56 +01:00
net Auto merge of #85746 - m-ou-se:io-error-other, r=joshtriplett 2021-07-02 09:01:42 +00:00
num rustc_expand: Mark inner #![test] attributes as soft-unstable 2020-11-20 19:35:03 +03:00
os Add Linux-specific pidfd process extensions 2021-07-21 10:49:11 +02:00
panic review: fix nits and move panic safety tests to the correct place 2020-09-25 23:10:24 +02:00
path Refactor parse_prefix on Windows 2020-11-07 16:15:48 +01:00
prelude Stabilize {std, core}::prelude::rust_*. 2021-06-14 14:44:50 +00:00
process Test that env_clear works on Windows 2021-06-24 09:32:24 +01:00
sync Rollup merge of #86783 - mark-i-m:mutex-drop-unsized, r=Xanewok 2021-07-02 06:20:33 +09:00
sys Add Linux-specific pidfd process extensions 2021-07-21 10:49:11 +02:00
sys_common Merge sys_common::bytestring into os_str_bytes 2021-06-21 12:57:14 +02:00
thread rename variable 2021-07-10 14:14:09 +02:00
time Duration::zero() -> Duration::ZERO 2020-10-21 20:44:03 -07:00
alloc.rs Rename rterr to rtprintpanic 2021-05-19 15:52:09 +02:00
ascii.rs Convert many files to intra-doc links 2020-09-02 17:37:40 -04:00
backtrace.rs make both panic display formats collapse frames 2021-06-07 21:18:55 +02:00
env.rs Use HTTPS links where possible 2021-06-23 16:26:46 -04:00
error.rs Rollup merge of #82179 - mbartlett21:patch-5, r=joshtriplett 2021-06-15 17:40:03 +09:00
f32.rs Change tracking issue 2021-06-13 14:04:43 -04:00
f64.rs Change tracking issue 2021-06-13 14:04:43 -04:00
fs.rs Update docs for fs::hard_link 2021-07-09 23:24:36 -07:00
keyword_docs.rs Fix a few misspellings. 2021-06-25 13:18:56 -07:00
lazy.rs Use DebugStruct::finish_non_exhaustive() in std. 2021-03-27 13:29:23 +01:00
lib.rs Rollup merge of #80918 - yoshuawuyts:int-log2, r=m-ou-se 2021-07-07 12:17:32 +09:00
macros.rs Change "etc." to "and similar" 2021-05-13 15:02:02 +01:00
num.rs postpone stabilizaton by one release 2021-06-22 10:20:56 +01:00
panic.rs Use diagnostic items to check for Send, UnwindSafe and RefUnwindSafe traits 2021-06-29 17:47:57 -04:00
panicking.rs Rollup merge of #84687 - a1phyr:improve_rwlock, r=m-ou-se 2021-06-10 11:02:10 +09:00
path.rs Auto merge of #85747 - maxwase:path-symlinks-methods, r=m-ou-se 2021-06-18 17:13:19 +00:00
primitive_docs.rs Use HTTPS links where possible 2021-06-23 16:26:46 -04:00
process.rs Add Linux-specific pidfd process extensions 2021-07-21 10:49:11 +02:00
rt.rs Change entry point to 🛡️ against 💥 💥-payloads 2021-06-19 11:46:56 +03:00
time.rs Use HTTPS links where possible 2021-06-23 16:26:46 -04:00