Skip to content

Commit b7b0a65

Browse files
bors[bot]SteveLauC
andauthored
Merge #1923
1923: feat: I/O safety for 'sys/wait' r=asomers a=SteveLauC #### What this PR does: 1. Adds I/O safety for `sys/wait` ---------- Actually, I am not sure about which type to use here: ```rust pub enum Id<'fd> { /// Wait for the child referred to by the given PID file descriptor #[cfg(any(target_os = "android", target_os = "linux"))] PIDFd(RawFd), PIDFd(BorrowedFd<'fd>), } ``` If we use `Fd: AsFd` ```rust pub enum Id<'fd, Fd: AsFd> { /// Wait for the child referred to by the given PID file descriptor #[cfg(any(target_os = "android", target_os = "linux"))] PIDFd(RawFd), PIDFd(&'fd Fd), } ``` then the user has to specify that generic type when using this interface, which is kinda user-unfriendly... ------ The typical usage of this interface will be something like: ```rust // Thought currently we don't have pidfd_open(2) in `Nix` let fd_referring_to_a_process: OwnedFd = pidfd_open().unwrap(); let status = waitid(Id::PIDFd(fd_referring_to_a_process), WaitPidFlag::XXXX).unwrap(); ``` UPDATE: `pidfd_open(2)` will be added in #1859 or #1868 . Co-authored-by: Steve Lau <stevelauc@outlook.com>
2 parents 9f3aafc + c6e6d92 commit b7b0a65

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

src/sys/wait.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::convert::TryFrom;
1010
target_os = "android",
1111
all(target_os = "linux", not(target_env = "uclibc")),
1212
))]
13-
use std::os::unix::io::RawFd;
13+
use std::os::unix::io::{AsRawFd, BorrowedFd};
1414

1515
libc_bitflags!(
1616
/// Controls the behavior of [`waitpid`].
@@ -343,8 +343,8 @@ pub fn wait() -> Result<WaitStatus> {
343343
target_os = "haiku",
344344
all(target_os = "linux", not(target_env = "uclibc")),
345345
))]
346-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
347-
pub enum Id {
346+
#[derive(Debug)]
347+
pub enum Id<'fd> {
348348
/// Wait for any child
349349
All,
350350
/// Wait for the child whose process ID matches the given PID
@@ -355,7 +355,11 @@ pub enum Id {
355355
PGid(Pid),
356356
/// Wait for the child referred to by the given PID file descriptor
357357
#[cfg(any(target_os = "android", target_os = "linux"))]
358-
PIDFd(RawFd),
358+
PIDFd(BorrowedFd<'fd>),
359+
/// A helper variant to resolve the unused parameter (`'fd`) problem on platforms
360+
/// other than Linux and Android.
361+
#[doc(hidden)]
362+
_Unreachable(std::marker::PhantomData<&'fd std::convert::Infallible>),
359363
}
360364

361365
/// Wait for a process to change status
@@ -373,7 +377,8 @@ pub fn waitid(id: Id, flags: WaitPidFlag) -> Result<WaitStatus> {
373377
Id::Pid(pid) => (libc::P_PID, pid.as_raw() as libc::id_t),
374378
Id::PGid(pid) => (libc::P_PGID, pid.as_raw() as libc::id_t),
375379
#[cfg(any(target_os = "android", target_os = "linux"))]
376-
Id::PIDFd(fd) => (libc::P_PIDFD, fd as libc::id_t),
380+
Id::PIDFd(fd) => (libc::P_PIDFD, fd.as_raw_fd() as libc::id_t),
381+
Id::_Unreachable(_) => unreachable!("This variant could never be constructed"),
377382
};
378383

379384
let siginfo = unsafe {

0 commit comments

Comments
 (0)