about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2021-08-03 07:31:59 -0500
committerDan Gohman <dev@sunfishcode.online>2021-08-19 12:02:40 -0700
commitcada5fb336bac35eb34848f8619009dc7aa0f5d0 (patch)
tree6a8f571efeacd3391a5d989c06793246b0bcda48
parent1ae1eeec2589abf742f87ec747acd31990e3b00a (diff)
downloadrust-cada5fb336bac35eb34848f8619009dc7aa0f5d0.tar.gz
rust-cada5fb336bac35eb34848f8619009dc7aa0f5d0.zip
Update PidFd for the new I/O safety APIs.
-rw-r--r--library/std/src/os/linux/process.rs26
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs16
2 files changed, 33 insertions, 9 deletions
diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs
index 6daff0f003c..e3e7143c851 100644
--- a/library/std/src/os/linux/process.rs
+++ b/library/std/src/os/linux/process.rs
@@ -3,7 +3,7 @@
 #![unstable(feature = "linux_pidfd", issue = "82971")]
 
 use crate::io::Result;
-use crate::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
+use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
 use crate::process;
 use crate::sealed::Sealed;
 #[cfg(not(doc))]
@@ -69,19 +69,37 @@ impl IntoInner<FileDesc> for PidFd {
 
 impl AsRawFd for PidFd {
     fn as_raw_fd(&self) -> RawFd {
-        self.as_inner().raw()
+        self.as_inner().as_raw_fd()
     }
 }
 
 impl FromRawFd for PidFd {
     unsafe fn from_raw_fd(fd: RawFd) -> Self {
-        Self::from_inner(FileDesc::new(fd))
+        Self::from_inner(FileDesc::from_raw_fd(fd))
     }
 }
 
 impl IntoRawFd for PidFd {
     fn into_raw_fd(self) -> RawFd {
-        self.into_inner().into_raw()
+        self.into_inner().into_raw_fd()
+    }
+}
+
+impl AsFd for PidFd {
+    fn as_fd(&self) -> BorrowedFd<'_> {
+        self.as_inner().as_fd()
+    }
+}
+
+impl From<OwnedFd> for PidFd {
+    fn from(fd: OwnedFd) -> Self {
+        Self::from_inner(FileDesc::from_inner(fd))
+    }
+}
+
+impl From<PidFd> for OwnedFd {
+    fn from(pid_fd: PidFd) -> Self {
+        pid_fd.into_inner().into_inner()
     }
 }
 
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 4b210d6af13..818f9308c19 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -4,6 +4,7 @@ use crate::io::{self, Error, ErrorKind};
 use crate::mem;
 use crate::num::NonZeroI32;
 use crate::os::raw::NonZero_c_int;
+use crate::os::unix::io::FromRawFd;
 use crate::ptr;
 use crate::sys;
 use crate::sys::cvt;
@@ -97,7 +98,9 @@ impl Command {
         drop(env_lock);
         drop(output);
 
-        let mut p = Process::new(pid, pidfd);
+        // Safety: We obtained the pidfd from calling `clone3` with
+        // `CLONE_PIDFD` so it's valid an otherwise unowned.
+        let mut p = unsafe { Process::new(pid, pidfd) };
         let mut bytes = [0; 8];
 
         // loop to handle EINTR
@@ -446,7 +449,8 @@ impl Command {
             None => None,
         };
 
-        let mut p = Process::new(0, -1);
+        // Safety: -1 indicates we don't have a pidfd.
+        let mut p = unsafe { Process::new(0, -1) };
 
         struct PosixSpawnFileActions<'a>(&'a mut MaybeUninit<libc::posix_spawn_file_actions_t>);
 
@@ -545,14 +549,16 @@ pub struct Process {
 
 impl Process {
     #[cfg(target_os = "linux")]
-    fn new(pid: pid_t, pidfd: pid_t) -> Self {
+    unsafe fn new(pid: pid_t, pidfd: pid_t) -> Self {
         use crate::sys_common::FromInner;
-        let pidfd = (pidfd >= 0).then(|| PidFd::from_inner(sys::fd::FileDesc::new(pidfd)));
+        // Safety: If `pidfd` is nonnegative, we assume it's valid and otherwise unowned.
+        let pidfd = (pidfd >= 0)
+            .then(|| PidFd::from_inner(unsafe { sys::fd::FileDesc::from_raw_fd(pidfd) }));
         Process { pid, status: None, pidfd }
     }
 
     #[cfg(not(target_os = "linux"))]
-    fn new(pid: pid_t, _pidfd: pid_t) -> Self {
+    unsafe fn new(pid: pid_t, _pidfd: pid_t) -> Self {
         Process { pid, status: None }
     }