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/