logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
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:

Mlib/fs.c37+++++++++++++++++++++++++++++++++++++
Mlib/fs.h6++++++
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