summaryrefslogtreecommitdiff
path: root/tests/clar
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2020-05-23 15:42:51 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2020-06-02 09:03:48 +0100
commitd03fd331f5f1fa54f13e7e8eed8e540ca4137e8b (patch)
tree60baae91d0d80d4f6f6458ca1829979531f6a3b4 /tests/clar
parent8df4f51956ba711ca69e93b8c93366ba7eaaab0b (diff)
downloadlibgit2-d03fd331f5f1fa54f13e7e8eed8e540ca4137e8b.tar.gz
clar: copy files with sendfile on linux
Diffstat (limited to 'tests/clar')
-rw-r--r--tests/clar/fs.h33
1 files changed, 27 insertions, 6 deletions
diff --git a/tests/clar/fs.h b/tests/clar/fs.h
index 696874270..b683171fe 100644
--- a/tests/clar/fs.h
+++ b/tests/clar/fs.h
@@ -1,5 +1,10 @@
-/* fcopyfile on macOS is slower than a simple read/write loop? */
+/*
+ * By default, use a read/write loop to copy files on POSIX systems.
+ * On Linux, use sendfile by default as it's slightly faster. On
+ * macOS, we avoid fcopyfile by default because it's slightly slower.
+ */
#undef USE_FCOPYFILE
+#define USE_SENDFILE 1
#ifdef _WIN32
@@ -264,6 +269,10 @@ cl_fs_cleanup(void)
#include <sys/types.h>
#include <sys/stat.h>
+#if defined(__linux__)
+# include <sys/sendfile.h>
+#endif
+
#if defined(__APPLE__) || defined(__FreeBSD__)
# include <copyfile.h>
#endif
@@ -341,12 +350,12 @@ static char *joinpath(const char *dir, const char *base, int base_len)
}
static void
-fs_copydir_helper(const char *source, const char *dest, int dmode)
+fs_copydir_helper(const char *source, const char *dest, int dest_mode)
{
DIR *source_dir;
struct dirent *d;
- mkdir(dest, dmode);
+ mkdir(dest, dest_mode);
cl_assert_(source_dir = opendir(source), "Could not open source dir");
while ((d = (errno = 0, readdir(source_dir))) != NULL) {
@@ -366,20 +375,32 @@ fs_copydir_helper(const char *source, const char *dest, int dmode)
}
static void
-fs_copyfile_helper(const char *source, const char *dest, int dmode)
+fs_copyfile_helper(const char *source, size_t source_len, const char *dest, int dest_mode)
{
int in, out;
cl_must_pass((in = open(source, O_RDONLY)));
- cl_must_pass((out = open(dest, O_WRONLY|O_CREAT|O_TRUNC, dmode)));
+ cl_must_pass((out = open(dest, O_WRONLY|O_CREAT|O_TRUNC, dest_mode)));
#if USE_FCOPYFILE && (defined(__APPLE__) || defined(__FreeBSD__))
+ ((void)(source_len)); /* unused */
cl_must_pass(fcopyfile(in, out, 0, COPYFILE_DATA));
+#elif USE_SENDFILE && defined(__linux__)
+ {
+ ssize_t ret = 0;
+
+ while (source_len && (ret = sendfile(out, in, NULL, source_len)) > 0) {
+ source_len -= (size_t)ret;
+ }
+ cl_assert(ret >= 0);
+ }
#else
{
char buf[131072];
ssize_t ret;
+ ((void)(source_len)); /* unused */
+
while ((ret = read(in, buf, sizeof(buf))) > 0) {
size_t len = (size_t)ret;
@@ -427,7 +448,7 @@ fs_copy(const char *source, const char *_dest)
if (S_ISDIR(source_st.st_mode)) {
fs_copydir_helper(source, dest, source_st.st_mode);
} else {
- fs_copyfile_helper(source, dest, source_st.st_mode);
+ fs_copyfile_helper(source, source_st.st_size, dest, source_st.st_mode);
}
free(dbuf);