@@ -157,11 +157,18 @@ pub trait CapStdExtDirExt {
157157 /// This uses [`cap_tempfile::TempFile`], which is wrapped in a [`std::io::BufWriter`]
158158 /// and passed to the closure.
159159 ///
160+ /// # Atomicity
161+ ///
162+ /// The function takes care of:
163+ /// - flushing the BufWriter
164+ /// - calling sync_all() on the TempFile
165+ /// - calling sync_all() on the parent directory (after the rename)
166+ ///
160167 /// # Existing files and metadata
161168 ///
162169 /// If the target path already exists and is a regular file (not a symbolic link or directory),
163170 /// then its access permissions (Unix mode) will be preserved. However, other metadata
164- /// such as extended attributes will *not* be preserved automatically. To do this will
171+ /// such as extended attributes will *not* be preserved automatically. To do this will
165172 /// require a higher level wrapper which queries the existing file and gathers such metadata
166173 /// before replacement.
167174 ///
@@ -296,11 +303,18 @@ pub trait CapStdExtDirExtUtf8 {
296303 /// This uses [`cap_tempfile::TempFile`], which is wrapped in a [`std::io::BufWriter`]
297304 /// and passed to the closure.
298305 ///
306+ /// # Atomicity
307+ ///
308+ /// The function takes care of:
309+ /// - flushing the BufWriter
310+ /// - calling sync_all() on the TempFile
311+ /// - calling sync_all() on the parent directory (after the rename)
312+ ///
299313 /// # Existing files and metadata
300314 ///
301315 /// If the target path already exists and is a regular file (not a symbolic link or directory),
302316 /// then its access permissions (Unix mode) will be preserved. However, other metadata
303- /// such as extended attributes will *not* be preserved automatically. To do this will
317+ /// such as extended attributes will *not* be preserved automatically. To do this will
304318 /// require a higher level wrapper which queries the existing file and gathers such metadata
305319 /// before replacement.
306320 ///
@@ -719,10 +733,14 @@ impl CapStdExtDirExt for Dir {
719733 let mut bufw = std:: io:: BufWriter :: new ( t) ;
720734 // Call the provided closure to generate the file content
721735 let r = f ( & mut bufw) ?;
722- // Flush the buffer, and rename the temporary file into place
723- bufw. into_inner ( )
724- . map_err ( From :: from)
725- . and_then ( |t| t. replace ( name) ) ?;
736+ // Flush the buffer, get the TempFile
737+ t = bufw. into_inner ( ) . map_err ( From :: from) ?;
738+ // fsync the TempFile
739+ t. as_file ( ) . sync_all ( ) ?;
740+ // rename the TempFile
741+ t. replace ( name) ?;
742+ // fsync the directory
743+ d. open ( "." ) ?. sync_all ( ) ?;
726744 Ok ( r)
727745 }
728746
0 commit comments