commit: 42d1bb319f92c6b029ce986e09662a032438e7db
parent 13af4748da15c16c3e213ca8b9261fbe410130d8
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Fri, 27 Sep 2024 10:15:57 +0200
lib/fs: add auto_fd_copy based on sendfile
Diffstat:
2 files changed, 43 insertions(+), 0 deletions(-)
diff --git a/lib/fs.c b/lib/fs.c
@@ -13,6 +13,10 @@
#include <string.h> // strrchr
#include <unistd.h> // copy_file_range
+#ifdef HAS_SENDFILE
+#include <sys/sendfile.h>
+#endif
+
char *
static_basename(char *path)
{
@@ -94,3 +98,35 @@ auto_file_copy(int fd_in, int fd_out, off_t len, int flags)
return wrote;
}
#endif
+
+#ifdef HAS_SENDFILE
+ssize_t
+auto_fd_copy(int fd_in, int fd_out, size_t len)
+{
+ off_t *off = NULL;
+
+ while(1)
+ {
+ ssize_t ret = sendfile(fd_out, fd_in, off, len);
+
+ if(ret < 0)
+ {
+ switch(errno)
+ {
+ case EINVAL:
+ errno = 0;
+ return manual_file_copy(fd_in, fd_out, len, 0);
+ case EAGAIN:
+ errno = 0;
+ continue;
+ default:
+ return ret;
+ }
+ }
+
+ return ret;
+ }
+
+ return -1;
+}
+#endif // HAS_SENDFILE
+\ No newline at end of file
diff --git a/lib/fs.h b/lib/fs.h
@@ -22,3 +22,9 @@ ssize_t manual_file_copy(int fd_in, int fd_out, off_t len, int flags);
// Copy data with copy_file_range(2) for <len> amount of data, with fallback to manual_file_copy when cross-device
ssize_t auto_file_copy(int fd_in, int fd_out, off_t len, int flags);
#endif
+
+#ifndef HAS_SENDFILE
+#define auto_fd_copy(fd_in, fd_out, len) auto_file_copy(fd_in, fd_out, len, 0)
+#else
+ssize_t auto_fd_copy(int fd_in, int fd_out, size_t len);
+#endif