@@ -12,8 +12,8 @@ use heed_traits::Comparator;
1212use synchronoise:: SignalEvent ;
1313
1414use super :: {
15- custom_key_cmp_wrapper, get_file_fd, metadata_from_fd , DefaultComparator , EnvClosingEvent ,
16- EnvInfo , FlagSetMode , IntegerComparator , OPENED_ENV ,
15+ custom_key_cmp_wrapper, get_file_fd, DefaultComparator , EnvClosingEvent , EnvInfo , FlagSetMode ,
16+ IntegerComparator , OPENED_ENV ,
1717} ;
1818use crate :: cursor:: { MoveOperation , RoCursor } ;
1919use crate :: mdb:: ffi:: { self , MDB_env } ;
@@ -63,11 +63,27 @@ impl<T> Env<T> {
6363 /// # Ok(()) }
6464 /// ```
6565 pub fn real_disk_size ( & self ) -> Result < u64 > {
66+ Ok ( self . try_clone_inner_file ( ) ?. metadata ( ) ?. len ( ) )
67+ }
68+
69+ /// Try cloning the inner file used in the environment and return a `File`
70+ /// corresponding to the environment file.
71+ ///
72+ /// # Safety
73+ ///
74+ /// This function is safe as we are creating a cloned fd of the inner file the file
75+ /// is. Doing write operations on the file descriptor can lead to undefined behavior
76+ /// and only read-only operations while no write operations are in progress is safe.
77+ pub fn try_clone_inner_file ( & self ) -> Result < File > {
6678 let mut fd = mem:: MaybeUninit :: uninit ( ) ;
6779 unsafe { mdb_result ( ffi:: mdb_env_get_fd ( self . env_mut_ptr ( ) . as_mut ( ) , fd. as_mut_ptr ( ) ) ) ? } ;
68- let fd = unsafe { fd. assume_init ( ) } ;
69- let metadata = unsafe { metadata_from_fd ( fd) ? } ;
70- Ok ( metadata. len ( ) )
80+ let raw_fd = unsafe { fd. assume_init ( ) } ;
81+ #[ cfg( unix) ]
82+ let fd = unsafe { std:: os:: fd:: BorrowedFd :: borrow_raw ( raw_fd) } ;
83+ #[ cfg( windows) ]
84+ let fd = unsafe { std:: os:: windows:: io:: BorrowedHandle :: borrow_raw ( raw_fd) } ;
85+ let owned = fd. try_clone_to_owned ( ) ?;
86+ Ok ( File :: from ( owned) )
7187 }
7288
7389 /// Return the raw flags the environment was opened with.
0 commit comments