commit: 85dd06e817da623e9a416f29daccaddb8e3e4c36
parent 54dd1707a0418662be33d1527e2d7e86efa62952
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat, 23 Nov 2024 11:47:05 +0100
lib/fs: add fsync(3) after copying data
Allows to avoid silent data corruption such as when copying a file too
big for the underlying filesystem.
Diffstat:
1 file changed, 20 insertions(+), 0 deletions(-)
diff --git a/lib/fs.c b/lib/fs.c
@@ -57,6 +57,20 @@ path_split_static(char *path, bool trim)
 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
 #endif
 
+static int
+file_sync(int fd)
+{
+	errno = 0;
+
+	int ret = fsync(fd);
+	if(ret == 0) return 0;
+
+	// Ignored cases
+	if(errno == EROFS || errno == EINVAL) return 0;
+
+	return ret;
+}
+
 ssize_t
 manual_file_copy(int fd_in, int fd_out, off_t len, int flags)
 {
@@ -76,6 +90,8 @@ manual_file_copy(int fd_in, int fd_out, off_t len, int flags)
 		wrote += nwrite;
 	} while(len > 0);
 
+	if(file_sync(fd_out) < 0) return -1;
+
 	return wrote;
 }
 
@@ -102,6 +118,8 @@ auto_file_copy(int fd_in, int fd_out, off_t len, int flags)
 		wrote += ret;
 	} while(len > 0 && ret > 0);
 
+	if(file_sync(fd_out) < 0) return -1;
+
 	return wrote;
 }
 #endif
@@ -135,6 +153,8 @@ auto_fd_copy(int fd_in, int fd_out, size_t len)
 		wrote += ret;
 		len -= ret;
 
+		if(file_sync(fd_out) < 0) return -1;
+
 		if(ret == 0) return wrote;
 	}