diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-12-11 16:40:02 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-11 16:40:02 +0000 |
commit | b7b0a65b4d9110f5c7d456e20f3aa9361ef57a3f (patch) | |
tree | b1379f94e777d8067f9aa9549532b9991c78f9c0 /src/sys/wait.rs | |
parent | 9f3aafcf7aaa59bbf715e626eea9024c83185c6f (diff) | |
parent | c6e6d9201bbad2d0fea141c412611c95025b61ae (diff) | |
download | nix-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.rs | 15 |
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 { |