From 0657379e3b391dad8c337468fd065e2e583189fd Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 15 Aug 2016 13:40:37 +0200 Subject: [PATCH] ops.cc: Always include ostream and ext/stdio_filebuf.h. * src/filesystem/ops.cc: Always include ostream and ext/stdio_filebuf.h. (do_copy_file): Check if _GLIBCXX_USE_FCHMODAT is defined. [_GLIBCXX_USE_SENDFILE]: Fallback to read/write operations in case sendfile fails with ENOSYS or EINVAL. From-SVN: r239479 --- libstdc++-v3/ChangeLog | 8 ++++++ libstdc++-v3/src/filesystem/ops.cc | 51 ++++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 2e4fa81..829f78e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2016-08-15 Uros Bizjak + + * src/filesystem/ops.cc: Always include ostream and + ext/stdio_filebuf.h. + (do_copy_file): Check if _GLIBCXX_USE_FCHMODAT is defined. + [_GLIBCXX_USE_SENDFILE]: Fallback to read/write operations in case + sendfile fails with ENOSYS or EINVAL. + 2016-08-15 Thomas Preud'homme PR libstdc++/72840 diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index 9fb5b63..0ecb8b9 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -28,7 +28,9 @@ #include #include +#include #include +#include #include #include #include @@ -48,9 +50,6 @@ #endif #ifdef _GLIBCXX_USE_SENDFILE # include -#else -# include -# include #endif #if _GLIBCXX_HAVE_UTIME_H # include @@ -416,7 +415,7 @@ namespace #ifdef _GLIBCXX_USE_FCHMOD if (::fchmod(out.fd, from_st->st_mode)) -#elif _GLIBCXX_USE_FCHMODAT +#elif defined _GLIBCXX_USE_FCHMODAT if (::fchmodat(AT_FDCWD, to.c_str(), from_st->st_mode, 0)) #else if (::chmod(to.c_str(), from_st->st_mode)) @@ -428,37 +427,45 @@ namespace #ifdef _GLIBCXX_USE_SENDFILE const auto n = ::sendfile(out.fd, in.fd, nullptr, from_st->st_size); - if (n != from_st->st_size) + if (n < 0 && (errno == ENOSYS || errno == EINVAL)) { - ec.assign(errno, std::generic_category()); - return false; +#endif + __gnu_cxx::stdio_filebuf sbin(in.fd, std::ios::in); + __gnu_cxx::stdio_filebuf sbout(out.fd, std::ios::out); + if (sbin.is_open()) + in.fd = -1; + if (sbout.is_open()) + out.fd = -1; + if (from_st->st_size && !(std::ostream(&sbout) << &sbin)) + { + ec = std::make_error_code(std::errc::io_error); + return false; + } + if (!sbout.close() || !sbin.close()) + { + ec.assign(errno, std::generic_category()); + return false; + } + + ec.clear(); + return true; + +#ifdef _GLIBCXX_USE_SENDFILE } - if (!out.close() || !in.close()) + if (n != from_st->st_size) { ec.assign(errno, std::generic_category()); return false; } -#else - __gnu_cxx::stdio_filebuf sbin(in.fd, std::ios::in); - __gnu_cxx::stdio_filebuf sbout(out.fd, std::ios::out); - if (sbin.is_open()) - in.fd = -1; - if (sbout.is_open()) - out.fd = -1; - if (from_st->st_size && !(std::ostream(&sbout) << &sbin)) - { - ec = std::make_error_code(std::errc::io_error); - return false; - } - if (!sbout.close() || !sbin.close()) + if (!out.close() || !in.close()) { ec.assign(errno, std::generic_category()); return false; } -#endif ec.clear(); return true; +#endif } } #endif -- 2.7.4