5656#include "cpdup.h"
5757#include "hclink.h"
5858#include "hcproto.h"
59+ #if defined(__FreeBSD__ )
60+ #include <sys/param.h>
61+ #endif
5962
6063#define HSIZE 8192
6164#define HMASK (HSIZE-1)
@@ -177,6 +180,14 @@ int64_t CountLinkedItems;
177180static struct HostConf SrcHost ;
178181static struct HostConf DstHost ;
179182
183+ #if defined(__linux__ ) || (defined(__FreeBSD__ ) && __FreeBSD_version > 1300037 )
184+ static inline int
185+ chk_ENOTSUP (int err )
186+ {
187+ return err == EOPNOTSUPP || (ENOTSUP != EOPNOTSUPP && err == ENOTSUP );
188+ }
189+ #endif
190+
180191int
181192main (int ac , char * * av )
182193{
@@ -1131,7 +1142,38 @@ DoCopy(copy_info_t info, struct stat *stat1, int depth)
11311142 const char * op ;
11321143 char * iobuf1 = malloc (GETIOSIZE );
11331144 int n ;
1145+ #if defined(USE_COPY_FILE_RANGE ) || (defined(__FreeBSD__ ) && __FreeBSD_version > 1300037 )
1146+ int do_std_copy = 0 ;
11341147
1148+ /*
1149+ * For local file transfers try copy_file_range(2)
1150+ */
1151+ if (SrcHost .host == NULL && DstHost .host == NULL ) {
1152+ ssize_t wcnt ;
1153+ do {
1154+ wcnt = copy_file_range (fd1 , NULL , fd2 , NULL ,
1155+ SSIZE_MAX , 0 );
1156+ } while (wcnt > 0 );
1157+ if (wcnt < 0 ) {
1158+ /*
1159+ * On selected errnos we retry with standard copy
1160+ */
1161+ if (errno == EINVAL || errno == EBADF ||
1162+ errno == ENOSYS || errno == EXDEV ||
1163+ errno == ETXTBSY || chk_ENOTSUP (errno ))
1164+ do_std_copy = 1 ;
1165+ else
1166+ n = -1 ;
1167+ } else
1168+ n = 0 ;
1169+ } else
1170+ do_std_copy = 1 ;
1171+
1172+ /*
1173+ * Do standard copy if remote or copy_file_range(2) has failed
1174+ */
1175+ if (do_std_copy ) {
1176+ #endif
11351177 /*
11361178 * Matt: What about holes?
11371179 */
@@ -1142,6 +1184,9 @@ DoCopy(copy_info_t info, struct stat *stat1, int depth)
11421184 break ;
11431185 op = "read" ;
11441186 }
1187+ #if defined(USE_COPY_FILE_RANGEE ) || (defined(__FreeBSD__ ) && __FreeBSD_version > 1300037 )
1188+ }
1189+ #endif
11451190 hc_close (& DstHost , fd2 );
11461191 if (n == 0 ) {
11471192 struct timeval tv [2 ];
0 commit comments