mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60490 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c2be819250
commit
524e660877
2 changed files with 20 additions and 0 deletions
10
io.c
10
io.c
|
@ -10789,6 +10789,16 @@ nogvl_copy_file_range(struct copy_stream_struct *stp)
|
|||
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;
|
||||
|
|
|
@ -366,6 +366,16 @@ class TestIO < Test::Unit::TestCase
|
|||
}
|
||||
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|
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue