diff options
author | LongPing Wei <weilongping@huawei.com> | 2022-03-16 10:38:55 +0800 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2022-03-17 09:10:17 -0500 |
commit | 613db35596e37c16063d531de6d635f0bd3b2f52 (patch) | |
tree | 879cd76d750e315e647f08f58d65fc69abfbbbcc /lib | |
parent | 745947434342b5ae8b8147849561c5fff4b0d82b (diff) | |
download | toybox-613db35596e37c16063d531de6d635f0bd3b2f52.tar.gz |
Enable copy_file_range when it is available.
Fallback to read+write when copy_file_range failed, as both fd_in and fd_out must refer to regular files.
Signed-off-by: LongPing Wei <weilongping@huawei.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/portability.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/lib/portability.c b/lib/portability.c index 5f98138c..d7648a8f 100644 --- a/lib/portability.c +++ b/lib/portability.c @@ -629,20 +629,25 @@ int get_block_device_size(int fd, unsigned long long* size) long long sendfile_len(int in, int out, long long bytes, long long *consumed) { long long total = 0, len, ww; + int copy_file_range = CFG_TOYBOX_COPYFILERANGE; if (consumed) *consumed = 0; if (in<0) return 0; while (bytes != total) { ww = 0; len = bytes-total; - if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf); errno = 0; -#if CFG_TOYBOX_COPYFILERANGE - len = copy_file_range(in, 0, out, 0, bytes, 0); -#else - ww = len = read(in, libbuf, len); -#endif + if (copy_file_range) { + if (bytes<0) len = INT_MAX; + len = syscall(__NR_copy_file_range, in, 0, out, 0, len, 0); + if (len < 0 && errno == EINVAL) + copy_file_range = 0; + } + if (!copy_file_range) { + if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf); + ww = len = read(in, libbuf, len); + } if (len<1 && errno==EAGAIN) continue; if (len<1) break; if (consumed) *consumed += len; |