PR libstdc++/83279 Use non-null offset argument for sendfile
authorJonathan Wakely <jwakely@redhat.com>
Fri, 5 Jan 2018 21:43:56 +0000 (21:43 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 5 Jan 2018 21:43:56 +0000 (21:43 +0000)
PR libstdc++/83279
* src/filesystem/std-ops.cc  (do_copy_file): Use non-null offset with
sendfile.

From-SVN: r256289

libstdc++-v3/ChangeLog
libstdc++-v3/src/filesystem/std-ops.cc

index fb2eb63a6936b9e4147d9ead1f3d71d7753265db..444c61550f84111d07b1104736f46823d172f1a0 100644 (file)
@@ -1,5 +1,9 @@
 2018-01-05  Jonathan Wakely  <jwakely@redhat.com>
 
+       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.
index 2411bbb797713a5c5687c5a7cac82574224bf2ad..bed1ad1fe2714cd570f85fdfd6479007138e1b5d 100644 (file)
@@ -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<char> sbin(in.fd, std::ios::in);
-  __gnu_cxx::stdio_filebuf<char> sbout(out.fd, std::ios::out);
+  using std::ios;
+  __gnu_cxx::stdio_filebuf<char> sbin(in.fd, ios::in|ios::binary);
+  __gnu_cxx::stdio_filebuf<char> 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))
     {