summaryrefslogtreecommitdiff
path: root/src/sys/wait.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-12-11 16:40:02 +0000
committerGitHub <noreply@github.com>2022-12-11 16:40:02 +0000
commitb7b0a65b4d9110f5c7d456e20f3aa9361ef57a3f (patch)
treeb1379f94e777d8067f9aa9549532b9991c78f9c0 /src/sys/wait.rs
parent9f3aafcf7aaa59bbf715e626eea9024c83185c6f (diff)
parentc6e6d9201bbad2d0fea141c412611c95025b61ae (diff)
downloadnix-b7b0a65b4d9110f5c7d456e20f3aa9361ef57a3f.zip
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>
Diffstat (limited to 'src/sys/wait.rs')
-rw-r--r--src/sys/wait.rs15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/sys/wait.rs b/src/sys/wait.rs
index b6524e86..f7a63ffc 100644
--- a/src/sys/wait.rs
+++ b/src/sys/wait.rs
@@ -10,7 +10,7 @@ use std::convert::TryFrom;
target_os = "android",
all(target_os = "linux", not(target_env = "uclibc")),
))]
-use std::os::unix::io::RawFd;
+use std::os::unix::io::{AsRawFd, BorrowedFd};
libc_bitflags!(
/// Controls the behavior of [`waitpid`].
@@ -343,8 +343,8 @@ pub fn wait() -> Result<WaitStatus> {
target_os = "haiku",
all(target_os = "linux", not(target_env = "uclibc")),
))]
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub enum Id {
+#[derive(Debug)]
+pub enum Id<'fd> {
/// Wait for any child
All,
/// Wait for the child whose process ID matches the given PID
@@ -355,7 +355,11 @@ pub enum Id {
PGid(Pid),
/// 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>),
+ /// A helper variant to resolve the unused parameter (`'fd`) problem on platforms
+ /// other than Linux and Android.
+ #[doc(hidden)]
+ _Unreachable(std::marker::PhantomData<&'fd std::convert::Infallible>),
}
/// Wait for a process to change status
@@ -373,7 +377,8 @@ pub fn waitid(id: Id, flags: WaitPidFlag) -> Result<WaitStatus> {
Id::Pid(pid) => (libc::P_PID, pid.as_raw() as libc::id_t),
Id::PGid(pid) => (libc::P_PGID, pid.as_raw() as libc::id_t),
#[cfg(any(target_os = "android", target_os = "linux"))]
- Id::PIDFd(fd) => (libc::P_PIDFD, fd as libc::id_t),
+ Id::PIDFd(fd) => (libc::P_PIDFD, fd.as_raw_fd() as libc::id_t),
+ Id::_Unreachable(_) => unreachable!("This variant could never be constructed"),
};
let siginfo = unsafe {