From 43cd46e9e7040b4653340f91d3b190831103ca79 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Tue, 20 Apr 2021 12:47:09 +0200 Subject: Make rename properly atomic --- src/fileutils.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src/fileutils.c') diff --git a/src/fileutils.c b/src/fileutils.c index 72d9c29..d7021dc 100644 --- a/src/fileutils.c +++ b/src/fileutils.c @@ -180,11 +180,27 @@ int file_overwrite_in_dir(const char *dir, const char *filename, const char *dat strcpy(tmp_filepath, filepath); strcpy(tmp_filepath + filepath_len, ".tmp"); - int result = file_overwrite(tmp_filepath, data, size); - if(result != 0) - return result; + int fd = open(tmp_filepath, O_CREAT | O_WRONLY, 0666); + if(fd == -1) { + perror(filepath); + return -1; + } + + ssize_t bytes_written = write(fd, data, size); + if(bytes_written != (ssize_t)size) { + fprintf(stderr, "Failed to write all bytes to file %s. Expected to write %zu bytes, only wrote %zd bytes\n", filepath, size, bytes_written); + close(fd); + return -1; + } + + if(fsync(fd) == -1) { + perror(filepath); + close(fd); + return -1; + } - /* Rename is atomic! */ + close(fd); + /* fsync + rename is atomic! */ return rename(tmp_filepath, filepath); } -- cgit v1.2.3