@@ -157,11 +157,18 @@ pub trait CapStdExtDirExt {
157
157
/// This uses [`cap_tempfile::TempFile`], which is wrapped in a [`std::io::BufWriter`]
158
158
/// and passed to the closure.
159
159
///
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
+ ///
160
167
/// # Existing files and metadata
161
168
///
162
169
/// If the target path already exists and is a regular file (not a symbolic link or directory),
163
170
/// 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
165
172
/// require a higher level wrapper which queries the existing file and gathers such metadata
166
173
/// before replacement.
167
174
///
@@ -296,11 +303,18 @@ pub trait CapStdExtDirExtUtf8 {
296
303
/// This uses [`cap_tempfile::TempFile`], which is wrapped in a [`std::io::BufWriter`]
297
304
/// and passed to the closure.
298
305
///
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
+ ///
299
313
/// # Existing files and metadata
300
314
///
301
315
/// If the target path already exists and is a regular file (not a symbolic link or directory),
302
316
/// 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
304
318
/// require a higher level wrapper which queries the existing file and gathers such metadata
305
319
/// before replacement.
306
320
///
@@ -719,10 +733,14 @@ impl CapStdExtDirExt for Dir {
719
733
let mut bufw = std:: io:: BufWriter :: new ( t) ;
720
734
// Call the provided closure to generate the file content
721
735
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 ( ) ?;
726
744
Ok ( r)
727
745
}
728
746
0 commit comments