From 7b91d432748703921d740eec291f3bcb3e648a69 Mon Sep 17 00:00:00 2001 From: ejurgensen Date: Sun, 27 Jul 2025 22:40:33 +0200 Subject: [PATCH] [scan] Fix for platforms without fcopyfile() or copy_file_range() Add @cagney's fallback copy function. Use feature tests in configure.ac for fcopyfile() and copy_file_range(). Fixes #1901 --- configure.ac | 8 +++++++- src/library/filescanner_ffmpeg.c | 25 +++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index c4c2b1b4..e2c25e04 100644 --- a/configure.ac +++ b/configure.ac @@ -96,7 +96,13 @@ AC_SEARCH_LIBS([pthread_getthreadid_np], [pthread], [Define to 1 if you have pthread_getthreadid_np])]) AC_SEARCH_LIBS([uuid_generate_random], [uuid], [AC_DEFINE([HAVE_UUID], 1, - [Define to 1 if you have uuid_generate_random function])]) + [Define to 1 if you have uuid_generate_random])]) +AC_SEARCH_LIBS([copy_file_range], [c], + [AC_DEFINE([HAVE_COPY_FILE_RANGE], 1, + [Define to 1 if you have copy_file_range])]) +AC_SEARCH_LIBS([fcopyfile], [c], + [AC_DEFINE([HAVE_FCOPYFILE], 1, + [Define to 1 if you have fcopyfile])]) AC_SEARCH_LIBS([log10], [m]) AC_SEARCH_LIBS([lrint], [m]) diff --git a/src/library/filescanner_ffmpeg.c b/src/library/filescanner_ffmpeg.c index e7d440a5..e544e582 100644 --- a/src/library/filescanner_ffmpeg.c +++ b/src/library/filescanner_ffmpeg.c @@ -31,9 +31,9 @@ #include #include -// For file copy +// For file copy (fcopyfile currently Mac OSX only) #include -#if defined(__APPLE__) +#if defined(HAVE_FCOPYFILE) #include #endif @@ -810,9 +810,9 @@ static int fast_copy(int fd_dst, int fd_src) { // Here we use kernel-space copying for performance reasons -#if defined(__APPLE__) +#if defined(HAVE_FCOPYFILE) return fcopyfile(fd_src, fd_dst, 0, COPYFILE_ALL); -#else +#elif defined(HAVE_COPY_FILE_RANGE) struct stat fileinfo = { 0 }; ssize_t bytes_copied; @@ -821,6 +821,23 @@ fast_copy(int fd_dst, int fd_src) if (bytes_copied < 0 || bytes_copied != fileinfo.st_size) return -1; + return 0; +#else + unsigned char buf[4096]; + ssize_t nr; + + while (1) + { + nr = read(fd_src, buf, sizeof(buf)); + if (nr == -1) + return -1; + else if (nr == 0) + return 0; + + if (write(fd_dst, buf, nr) != nr) + return -1; + } + return 0; #endif }