From 2526c53acf9e80a917f157b527e3d4806208f230 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 5 Jan 2018 21:43:56 +0000 Subject: [PATCH] PR libstdc++/83279 Use non-null offset argument for sendfile PR libstdc++/83279 * src/filesystem/std-ops.cc (do_copy_file): Use non-null offset with sendfile. From-SVN: r256289 --- libstdc++-v3/ChangeLog | 4 ++++ libstdc++-v3/src/filesystem/std-ops.cc | 33 ++++++++++++-------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index fb2eb63a693..444c61550f8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,9 @@ 2018-01-05 Jonathan Wakely + PR libstdc++/83279 + * src/filesystem/std-ops.cc (do_copy_file): Use non-null offset with + sendfile. + PR libstdc++/83626 * src/filesystem/ops.cc (remove(const path&, error_code&)): Do not report an error for ENOENT. diff --git a/libstdc++-v3/src/filesystem/std-ops.cc b/libstdc++-v3/src/filesystem/std-ops.cc index 2411bbb7977..bed1ad1fe27 100644 --- a/libstdc++-v3/src/filesystem/std-ops.cc +++ b/libstdc++-v3/src/filesystem/std-ops.cc @@ -382,10 +382,10 @@ fs::do_copy_file(const char* from, const char* to, return false; } - ssize_t n = 0; size_t count = from_st->st_size; #ifdef _GLIBCXX_USE_SENDFILE - n = ::sendfile(out.fd, in.fd, nullptr, count); + off_t offset = 0; + ssize_t n = ::sendfile(out.fd, in.fd, &offset, count); if (n < 0 && errno != ENOSYS && errno != EINVAL) { ec.assign(errno, std::generic_category()); @@ -405,35 +405,32 @@ fs::do_copy_file(const char* from, const char* to, count -= n; #endif // _GLIBCXX_USE_SENDFILE - __gnu_cxx::stdio_filebuf sbin(in.fd, std::ios::in); - __gnu_cxx::stdio_filebuf sbout(out.fd, std::ios::out); + using std::ios; + __gnu_cxx::stdio_filebuf sbin(in.fd, ios::in|ios::binary); + __gnu_cxx::stdio_filebuf sbout(out.fd, ios::out|ios::binary); if (sbin.is_open()) in.fd = -1; if (sbout.is_open()) out.fd = -1; - const std::streampos errpos(std::streamoff(-1)); - - if (n < 0) +#ifdef _GLIBCXX_USE_SENDFILE + if (n != 0) { - auto p1 = sbin.pubseekoff(0, std::ios_base::beg, std::ios_base::in); - auto p2 = sbout.pubseekoff(0, std::ios_base::beg, std::ios_base::out); + if (n < 0) + n = 0; + + const auto p1 = sbin.pubseekoff(n, ios::beg, ios::in); + const auto p2 = sbout.pubseekoff(n, ios::beg, ios::out); + + const std::streampos errpos(std::streamoff(-1)); if (p1 == errpos || p2 == errpos) { ec = std::make_error_code(std::errc::io_error); return false; } } - else if (n > 0) - { - auto p = sbout.pubseekoff(n, std::ios_base::beg, std::ios_base::out); - if (p == errpos) - { - ec = std::make_error_code(std::errc::io_error); - return false; - } - } +#endif if (count && !(std::ostream(&sbout) << &sbin)) {