@@ -8,6 +8,7 @@ use crate::fmt;
88use crate :: fs;
99use crate :: marker:: PhantomData ;
1010use crate :: mem:: forget;
11+ use crate :: sys:: cvt;
1112use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
1213
1314/// A borrowed file descriptor.
@@ -67,6 +68,28 @@ impl BorrowedFd<'_> {
6768 }
6869}
6970
71+ impl OwnedFd {
72+ /// Creates a new `OwnedFd` instance that shares the same underlying file handle
73+ /// as the existing `OwnedFd` instance.
74+ pub fn try_clone ( & self ) -> crate :: io:: Result < Self > {
75+ // We want to atomically duplicate this file descriptor and set the
76+ // CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
77+ // is a POSIX flag that was added to Linux in 2.6.24.
78+ #[ cfg( not( target_os = "espidf" ) ) ]
79+ let cmd = libc:: F_DUPFD_CLOEXEC ;
80+
81+ // For ESP-IDF, F_DUPFD is used instead, because the CLOEXEC semantics
82+ // will never be supported, as this is a bare metal framework with
83+ // no capabilities for multi-process execution. While F_DUPFD is also
84+ // not supported yet, it might be (currently it returns ENOSYS).
85+ #[ cfg( target_os = "espidf" ) ]
86+ let cmd = libc:: F_DUPFD ;
87+
88+ let fd = cvt ( unsafe { libc:: fcntl ( self . as_raw_fd ( ) , cmd, 0 ) } ) ?;
89+ Ok ( unsafe { Self :: from_raw_fd ( fd) } )
90+ }
91+ }
92+
7093#[ unstable( feature = "io_safety" , issue = "87074" ) ]
7194impl AsRawFd for BorrowedFd < ' _ > {
7295 #[ inline]
0 commit comments