Skip to content

Instantly share code, notes, and snippets.

@mechanicker
Last active December 27, 2019 22:33
Show Gist options
  • Save mechanicker/5277d07fdf664e13b712e5f7a398b13c to your computer and use it in GitHub Desktop.
Save mechanicker/5277d07fdf664e13b712e5f7a398b13c to your computer and use it in GitHub Desktop.
Patch GNU coreutils (git://git.sv.gnu.org/coreutils) cp command to use sendfile()
commit 98fd0cba2b839cd2b77d57397998391a81baa55f
Author: Dhruva Krishnamurthy <dhruvakm@gmail.com>
Date: Fri Dec 27 11:43:06 2019 -0800
cp: Use sendfile() to copy files to redundant data copy
diff --git a/configure.ac b/configure.ac
index 18c5a99bd..bef490af9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -245,6 +245,11 @@ AM_CONDITIONAL([SINGLE_BINARY], [test "$gl_single_binary" != no])
AC_FUNC_FORK
+AC_CHECK_FUNCS_ONCE([sendfile])
+if test ac_cv_func_sendfile=yes; then
+ AC_DEFINE([HAVE_SENDFILE])
+fi
+
optional_bin_progs=
AC_CHECK_FUNCS([chroot],
gl_ADD_PROG([optional_bin_progs], [chroot]))
diff --git a/src/copy.c b/src/copy.c
index cd6104c7a..66bc0c8c1 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -110,6 +110,15 @@ rpl_mkfifo (char const *file, mode_t mode)
# define USE_ACL 0
#endif
+#ifdef HAVE_SENDFILE
+/* BSD sendfile implementation does not support file as target */
+#ifdef __linux__
+#include <sys/sendfile.h>
+#else
+#undef HAVE_SENDFILE
+#endif
+#endif
+
#define SAME_OWNER(A, B) ((A).st_uid == (B).st_uid)
#define SAME_GROUP(A, B) ((A).st_gid == (B).st_gid)
#define SAME_OWNER_AND_GROUP(A, B) (SAME_OWNER (A, B) && SAME_GROUP (A, B))
@@ -1252,6 +1261,20 @@ copy_reg (char const *src_name, char const *dst_name,
if (data_copy_required)
{
+#ifdef HAVE_SENDFILE
+ ssize_t nb;
+ ssize_t remaining = src_open_sb.st_size;
+ do {
+ nb = sendfile(dest_desc, source_desc, NULL, remaining);
+ if (nb > 0)
+ remaining -= nb;
+ } while ((nb > 0 && remaining > 0) || (nb < 0 && errno == EINTR));
+ return_val = (remaining == 0);
+ if (!return_val)
+ goto close_src_and_dst_desc;
+ goto preserve_metadata;
+#endif
+
/* Choose a suitable buffer size; it may be adjusted later. */
size_t buf_alignment = getpagesize ();
size_t buf_size = io_blksize (sb);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment