diff options
Diffstat (limited to 'src/basic/fileio.c')
-rw-r--r-- | src/basic/fileio.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c index a025038588..277aea51a9 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -71,7 +71,7 @@ int write_string_stream_ts(FILE *f, const char *line, bool enforce_newline, stru return fflush_and_check(f); } -static int write_string_file_atomic(const char *fn, const char *line, bool enforce_newline) { +static int write_string_file_atomic(const char *fn, const char *line, bool enforce_newline, bool sync) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *p = NULL; int r; @@ -86,6 +86,9 @@ static int write_string_file_atomic(const char *fn, const char *line, bool enfor (void) fchmod_umask(fileno(f), 0644); r = write_string_stream(f, line, enforce_newline); + if (r >= 0 && sync) + r = fflush_sync_and_check(f); + if (r >= 0) { if (rename(p, fn) < 0) r = -errno; @@ -104,10 +107,14 @@ int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags assert(fn); assert(line); + /* We don't know how to verify whether the file contents is on-disk. */ + assert(!((flags & WRITE_STRING_FILE_SYNC) && (flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))); + if (flags & WRITE_STRING_FILE_ATOMIC) { assert(flags & WRITE_STRING_FILE_CREATE); - r = write_string_file_atomic(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE)); + r = write_string_file_atomic(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE), + flags & WRITE_STRING_FILE_SYNC); if (r < 0) goto fail; @@ -144,6 +151,12 @@ int write_string_file_ts(const char *fn, const char *line, WriteStringFileFlags if (r < 0) goto fail; + if (flags & WRITE_STRING_FILE_SYNC) { + r = fflush_sync_and_check(f); + if (r < 0) + return r; + } + return 0; fail: @@ -1126,6 +1139,21 @@ int fflush_and_check(FILE *f) { return 0; } +int fflush_sync_and_check(FILE *f) { + int r; + + assert(f); + + r = fflush_and_check(f); + if (r < 0) + return r; + + if (fsync(fileno(f)) < 0) + return -errno; + + return 0; +} + /* This is much like mkostemp() but is subject to umask(). */ int mkostemp_safe(char *pattern) { _cleanup_umask_ mode_t u = 0; |