ops.cc: Always include ostream and ext/stdio_filebuf.h.
authorUros Bizjak <ubizjak@gmail.com>
Mon, 15 Aug 2016 11:40:37 +0000 (13:40 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 15 Aug 2016 11:40:37 +0000 (13:40 +0200)
* 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
libstdc++-v3/src/filesystem/ops.cc

index 2e4fa813dacd3363b644e21939bb1427564e074f..829f78e1409f7e7c40201748bd9f19f714894dde 100644 (file)
@@ -1,3 +1,11 @@
+2016-08-15  Uros Bizjak  <ubizjak@gmail.com>
+
+       * 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  <thomas.preudhomme@arm.com>
 
        PR libstdc++/72840
index 9fb5b639fc0bd09c8c7789d6ae17e1c47b525c9e..0ecb8b9f4d871ccb44cb34882e56edf3e7abb1e7 100644 (file)
@@ -28,7 +28,9 @@
 
 #include <experimental/filesystem>
 #include <functional>
+#include <ostream>
 #include <stack>
+#include <ext/stdio_filebuf.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <errno.h>
@@ -48,9 +50,6 @@
 #endif
 #ifdef _GLIBCXX_USE_SENDFILE
 # include <sys/sendfile.h>
-#else
-# include <ext/stdio_filebuf.h>
-# include <ostream>
 #endif
 #if _GLIBCXX_HAVE_UTIME_H
 # include <utime.h>
@@ -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<char> sbin(in.fd, std::ios::in);
+       __gnu_cxx::stdio_filebuf<char> 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<char> sbin(in.fd, std::ios::in);
-    __gnu_cxx::stdio_filebuf<char> 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