1
+ use crate :: errno:: Errno ;
2
+ use crate :: Result ;
3
+ use std:: convert:: TryFrom ;
4
+ use std:: os:: unix:: io:: { AsRawFd , FromRawFd , OwnedFd } ;
5
+
6
+ /// Allocates a new file descriptor in the calling process. This new file descriptor is a duplicate
7
+ /// of an existing file descriptor, `target`, in the process referred to by the PID file descriptor
8
+ /// `pid`.
9
+ ///
10
+ /// The duplicate file descriptor refers to the same open file description (see
11
+ /// [open(2)](https://man7.org/linux/man-pages/man2/open.2.html)) as the original file descriptor in
12
+ /// the process referred to by `pid`. The two file descriptors thus share file status flags and
13
+ /// file offset. Furthermore, operations on the underlying file object (for example, assigning an
14
+ /// address to a socket object using [bind(2)](https://man7.org/linux/man-pages/man2/bind.2.html))
15
+ /// can equally be performed via the duplicate file descriptor.
16
+ ///
17
+ /// The close-on-exec flag ([`libc::FD_CLOEXEC`]; see
18
+ /// [fcntl(2)](https://man7.org/linux/man-pages/man2/fcntl.2.html)) is set on the returned file
19
+ /// descriptor.
20
+ ///
21
+ /// Permission to duplicate another process's file descriptor is governed by a ptrace access mode
22
+ /// PTRACE_MODE_ATTACH_REALCREDS check (see
23
+ /// [ptrace(2)](https://man7.org/linux/man-pages/man2/ptrace.2.html)).
24
+ pub fn pidfd_getfd < PFd : AsRawFd , TFd : AsRawFd > (
25
+ pid : PFd ,
26
+ target : TFd ,
27
+ ) -> Result < OwnedFd > {
28
+ #[ allow( clippy:: useless_conversion) ] // Not useless on all OSes
29
+ match unsafe {
30
+ libc:: syscall (
31
+ libc:: SYS_pidfd_getfd ,
32
+ pid. as_raw_fd ( ) ,
33
+ target. as_raw_fd ( ) ,
34
+ 0 ,
35
+ )
36
+ } {
37
+ -1 => Err ( Errno :: last ( ) ) ,
38
+ fd @ 0 .. => {
39
+ Ok ( unsafe { OwnedFd :: from_raw_fd ( i32:: try_from ( fd) . unwrap ( ) ) } )
40
+ }
41
+ _ => unreachable ! ( ) ,
42
+ }
43
+ }
0 commit comments