Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 10 pull requests #83279

Closed
wants to merge 29 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ab154fd
Only build help popup when it's really needed
GuillaumeGomez Dec 12, 2020
2cbea9f
Reuse `std::sys::unsupported::pipe` on `hermit`
CDirkx Feb 24, 2021
8c718bd
Attempt to gather similar stats as rusage on Windows
rylev Mar 4, 2021
0201e2b
Add more windows specific numbers
rylev Mar 5, 2021
a2571cf
Implement String::remove_matches
jcotton42 Mar 5, 2021
302867c
Clean up handling of child process
rylev Mar 11, 2021
5e788f2
Add Linux-specific pidfd process extensions
Aaron1011 Sep 16, 2020
3426bf7
Typo fix
joshtriplett Oct 18, 2020
704d6c5
Add PidFd type and seal traits
voidc Feb 6, 2021
766cc25
Add tracking issue and link to man-page
voidc Mar 10, 2021
d850f6b
Update libc dependency to 0.2.89
voidc Mar 15, 2021
5ac8a31
Fix test header and imports
voidc Mar 16, 2021
a266bd8
Split do_fork into two
voidc Mar 16, 2021
cfb2d72
Make do_fork unsafe
voidc Mar 16, 2021
620ecc0
Move some test-only code to test files
jyn514 Mar 17, 2021
b1de9d4
Fix gitattibutes for old git versions
Mar 16, 2021
cfb4ad4
Remove unwrap_none/expect_none from compiler/.
m-ou-se Mar 4, 2021
390d1ef
Extend `proc_macro_back_compat` lint to `actix-web`
Aaron1011 Mar 16, 2021
99b2054
Fix typo/inaccuracy in the documentation of Iterator::skip_while
steffahn Mar 18, 2021
0ef2b5e
Rollup merge of #71780 - jcotton42:string_remove_matches, r=joshtriplett
Dylan-DPC Mar 18, 2021
c28d8d2
Rollup merge of #79986 - GuillaumeGomez:build-help-when-needed, r=Nem…
Dylan-DPC Mar 18, 2021
717b6c4
Rollup merge of #81825 - voidc:pidfd, r=joshtriplett
Dylan-DPC Mar 18, 2021
0531012
Rollup merge of #82500 - CDirkx:hermit-pipe, r=joshtriplett
Dylan-DPC Mar 18, 2021
6f5015a
Rollup merge of #82754 - rylev:rusage-windows, r=pnkfelix
Dylan-DPC Mar 18, 2021
aea804f
Rollup merge of #82759 - m-ou-se:remove-unwrap-none, r=petrochenkov
Dylan-DPC Mar 18, 2021
482d7bc
Rollup merge of #83179 - Aaron1011:actix-web-lint, r=petrochenkov
Dylan-DPC Mar 18, 2021
138c057
Rollup merge of #83197 - jyn514:cfg-test-dead-code, r=joshtriplett
Dylan-DPC Mar 18, 2021
3721111
Rollup merge of #83208 - jethrogb:jb/gitignore, r=Xanewok
Dylan-DPC Mar 18, 2021
6f61327
Rollup merge of #83270 - steffahn:missing_word_in_skip_while_doc, r=j…
Dylan-DPC Mar 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add PidFd type and seal traits
Improve docs
  • Loading branch information
voidc committed Mar 15, 2021
commit 704d6c5de3bdc7127112c07f1da01a15aaef23e4
146 changes: 124 additions & 22 deletions library/std/src/os/linux/process.rs
Original file line number Diff line number Diff line change
@@ -2,40 +2,142 @@

#![unstable(feature = "linux_pidfd", issue = "none")]

use crate::process;
use crate::sys_common::AsInnerMut;
use crate::io::Result;
use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use crate::process;
use crate::sys::fd::FileDesc;
use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};

/// Os-specific extensions to [`process::Child`]
/// This type represents a file descriptor that refers to a process.
///
/// A `PidFd` can be obtained by setting the corresponding option on [`Command`]
/// with [`create_pidfd`]. Subsequently, the created pidfd can be retrieved
/// from the [`Child`] by calling [`pidfd`] or [`take_pidfd`].
///
/// Example:
/// ```no_run
/// #![feature(linux_pidfd)]
/// use std::os::linux::process::{CommandExt, ChildExt};
/// use std::process::Command;
///
/// let mut child = Command::new("echo")
/// .create_pidfd(true)
/// .spawn()
/// .expect("Failed to spawn child");
///
/// [`process::Child`]: crate::process::Child
pub trait ChildExt {
/// Obtains the pidfd created for this child process, if available.
/// let pidfd = child
/// .take_pidfd()
/// .expect("Failed to retrieve pidfd");
///
/// // The file descriptor will be closed when `pidfd` is dropped.
/// ```
/// Refer to the man page of `pidfd_open(2)` for further details.
///
/// [`Command`]: process::Command
/// [`create_pidfd`]: CommandExt::create_pidfd
/// [`Child`]: process::Child
/// [`pidfd`]: fn@ChildExt::pidfd
/// [`take_pidfd`]: ChildExt::take_pidfd
#[derive(Debug)]
pub struct PidFd {
inner: FileDesc,
}

impl AsInner<FileDesc> for PidFd {
fn as_inner(&self) -> &FileDesc {
&self.inner
}
}

impl FromInner<FileDesc> for PidFd {
fn from_inner(inner: FileDesc) -> PidFd {
PidFd { inner }
}
}

impl IntoInner<FileDesc> for PidFd {
fn into_inner(self) -> FileDesc {
self.inner
}
}

impl AsRawFd for PidFd {
fn as_raw_fd(&self) -> RawFd {
self.as_inner().raw()
}
}

impl FromRawFd for PidFd {
unsafe fn from_raw_fd(fd: RawFd) -> Self {
Self::from_inner(FileDesc::new(fd))
}
}

impl IntoRawFd for PidFd {
fn into_raw_fd(self) -> RawFd {
self.into_inner().into_raw()
}
}

mod private_child_ext {
pub trait Sealed {}
impl Sealed for crate::process::Child {}
}

/// Os-specific extensions for [`Child`]
///
/// [`Child`]: process::Child
pub trait ChildExt: private_child_ext::Sealed {
/// Obtains a reference to the [`PidFd`] created for this [`Child`], if available.
///
/// A pidfd will only be available if its creation was requested with
/// [`create_pidfd`] when the corresponding [`Command`] was created.
///
/// A pidfd will only ever be available if `create_pidfd(true)` was called
/// when the corresponding `Command` was created.
/// Even if requested, a pidfd may not be available due to an older
/// version of Linux being in use, or if some other error occurred.
///
/// [`Command`]: process::Command
/// [`create_pidfd`]: CommandExt::create_pidfd
/// [`Child`]: process::Child
fn pidfd(&self) -> Result<&PidFd>;

/// Takes ownership of the [`PidFd`] created for this [`Child`], if available.
///
/// Even if `create_pidfd(true)` is called, a pidfd may not be available
/// due to an older version of Linux being in use, or if
/// some other error occured.
/// A pidfd will only be available if its creation was requested with
/// [`create_pidfd`] when the corresponding [`Command`] was created.
///
/// See `man pidfd_open` for more details about pidfds.
fn pidfd(&self) -> Result<i32>;
/// Even if requested, a pidfd may not be available due to an older
/// version of Linux being in use, or if some other error occurred.
///
/// [`Command`]: process::Command
/// [`create_pidfd`]: CommandExt::create_pidfd
/// [`Child`]: process::Child
fn take_pidfd(&mut self) -> Result<PidFd>;
}

mod private_command_ext {
pub trait Sealed {}
impl Sealed for crate::process::Command {}
}

/// Os-specific extensions to [`process::Command`]
/// Os-specific extensions for [`Command`]
///
/// [`process::Command`]: crate::process::Command
pub trait CommandExt {
/// Sets whether or this `Command` will attempt to create a pidfd
/// for the child. If this method is never called, a pidfd will
/// not be crated.
/// [`Command`]: process::Command
pub trait CommandExt: private_command_ext::Sealed {
/// Sets whether a [`PidFd`](struct@PidFd) should be created for the [`Child`]
/// spawned by this [`Command`].
/// By default, no pidfd will be created.
///
/// The pidfd can be retrieved from the child via [`ChildExt::pidfd`]
/// The pidfd can be retrieved from the child with [`pidfd`] or [`take_pidfd`].
///
/// A pidfd will only be created if it is possible to do so
/// in a guaranteed race-free manner (e.g. if the `clone3` system call is
/// supported). Otherwise, [`ChildExit::pidfd`] will return an error.
/// in a guaranteed race-free manner (e.g. if the `clone3` system call
/// is supported). Otherwise, [`pidfd`] will return an error.
///
/// [`Command`]: process::Command
/// [`Child`]: process::Child
/// [`pidfd`]: fn@ChildExt::pidfd
/// [`take_pidfd`]: ChildExt::take_pidfd
fn create_pidfd(&mut self, val: bool) -> &mut process::Command;
}

8 changes: 4 additions & 4 deletions library/std/src/sys/unix/process/process_common.rs
Original file line number Diff line number Diff line change
@@ -79,7 +79,7 @@ pub struct Command {
stdin: Option<Stdio>,
stdout: Option<Stdio>,
stderr: Option<Stdio>,
pub(crate) make_pidfd: bool,
pub(crate) create_pidfd: bool,
}

// Create a new type for argv, so that we can make it `Send` and `Sync`
@@ -142,7 +142,7 @@ impl Command {
stdin: None,
stdout: None,
stderr: None,
make_pidfd: false,
create_pidfd: false,
}
}

@@ -178,9 +178,9 @@ impl Command {
pub fn groups(&mut self, groups: &[gid_t]) {
self.groups = Some(Box::from(groups));
}

pub fn create_pidfd(&mut self, val: bool) {
self.make_pidfd = val;
self.create_pidfd = val;
}

pub fn saw_nul(&self) -> bool {
Loading