@@ -15,6 +15,7 @@ use std::ffi::OsStr;
1515use std:: io:: Result ;
1616use std:: io:: { self , Write } ;
1717use std:: ops:: Deref ;
18+ use std:: os:: fd:: OwnedFd ;
1819use std:: path:: Path ;
1920
2021#[ cfg( feature = "fs_utf8" ) ]
@@ -125,6 +126,14 @@ pub trait CapStdExtDirExt {
125126 perms : cap_std:: fs:: Permissions ,
126127 ) -> Result < ( ) > ;
127128
129+ /// By default, cap-std `Dir` instances are opened using `O_PATH`.
130+ /// There are some operations such as `fsync` and `fsetxattr` that
131+ /// cannot be performed on `O_PATH` file descriptors. Use this
132+ /// function to create a non-`O_PATH` copy of the directory
133+ /// file descriptor.
134+ #[ cfg( unix) ]
135+ fn reopen_as_ownedfd ( & self ) -> Result < OwnedFd > ;
136+
128137 #[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
129138 /// Returns `Some(true)` if the target is known to be a mountpoint, or
130139 /// `Some(false)` if the target is definitively known not to be a mountpoint.
@@ -532,6 +541,19 @@ impl CapStdExtDirExt for Dir {
532541 } )
533542 }
534543
544+ #[ cfg( unix) ]
545+ fn reopen_as_ownedfd ( & self ) -> Result < OwnedFd > {
546+ use rustix:: fs:: { Mode , OFlags } ;
547+ use std:: os:: fd:: AsFd ;
548+ rustix:: fs:: openat (
549+ self . as_fd ( ) ,
550+ "." ,
551+ OFlags :: CLOEXEC | OFlags :: DIRECTORY | OFlags :: RDONLY ,
552+ Mode :: empty ( ) ,
553+ )
554+ . map_err ( Into :: into)
555+ }
556+
535557 fn is_mountpoint ( & self , path : impl AsRef < Path > ) -> Result < Option < bool > > {
536558 is_mountpoint_impl_statx ( self , path. as_ref ( ) ) . map_err ( Into :: into)
537559 }
0 commit comments