[前][次][番号順一覧][スレッド一覧]

ruby-changes:48376

From: normal <ko1@a...>
Date: Sat, 28 Oct 2017 03:37:30 +0900 (JST)
Subject: [ruby-changes:48376] normal:r60490 (trunk): io.c: fix IO.copy_stream on O_APPEND destination on Linux

normal	2017-10-28 03:37:23 +0900 (Sat, 28 Oct 2017)

  New Revision: 60490

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60490

  Log:
    io.c: fix IO.copy_stream on O_APPEND destination on Linux
    
    Linux copy_file_range(2) fails with EBADF if the destination FD
    has O_APPEND set.  Preserve existing (Ruby <= 2.4) behavior by
    falling back to alternative copy mechanisms if this is the case
    (instead of raising Errno::EBADF).
    
    * io.c (nogvl_copy_file_range): do not raise on O_APPEND dst
    * test/ruby/test_io.rb (test_copy_stream_append): new test
      [Feature #13867]

  Modified files:
    trunk/io.c
    trunk/test/ruby/test_io.rb
Index: io.c
===================================================================
--- io.c	(revision 60489)
+++ io.c	(revision 60490)
@@ -10789,6 +10789,16 @@ nogvl_copy_file_range(struct copy_stream https://github.com/ruby/ruby/blob/trunk/io.c#L10789
             if (nogvl_copy_stream_wait_write(stp) == -1)
                 return -1;
             goto retry_copy_file_range;
+	  case EBADF:
+	    {
+		int e = errno;
+		int flags = fcntl(stp->dst_fd, F_GETFL);
+
+		if (flags != -1 && flags & O_APPEND) {
+		    return 0;
+		}
+		errno = e;
+	    }
         }
         stp->syserr = "copy_file_range";
         stp->error_no = errno;
Index: test/ruby/test_io.rb
===================================================================
--- test/ruby/test_io.rb	(revision 60489)
+++ test/ruby/test_io.rb	(revision 60490)
@@ -366,6 +366,16 @@ class TestIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io.rb#L366
     }
   end
 
+  def test_copy_stream_append
+    with_srccontent("foobar") {|src, content|
+      File.open('dst', 'ab') do |dst|
+        ret = IO.copy_stream(src, dst)
+        assert_equal(content.bytesize, ret)
+        assert_equal(content, File.read("dst"))
+      end
+    }
+  end
+
   def test_copy_stream_smaller
     with_srccontent {|src, content|
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]