Do not use `fcopyfile` if appending to non-empty file [Bug #18388]

`fcopyfile` appends `src` to `to` and then truncates `to` to it's
original size.
This commit is contained in:
Nobuyoshi Nakada 2021-12-05 18:08:55 +09:00
Родитель a72aecac3a
Коммит b555e659c4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7CD2805BFA3770C6
2 изменённых файлов: 19 добавлений и 0 удалений

7
io.c
Просмотреть файл

@ -11483,6 +11483,13 @@ nogvl_fcopyfile(struct copy_stream_struct *stp)
return 0;
if (lseek(stp->dst_fptr->fd, 0, SEEK_CUR) > (off_t)0) /* if dst IO was already written */
return 0;
if (fcntl(stp->dst_fptr->fd, F_GETFL) & O_APPEND) {
/* fcopyfile(3) appends src IO to dst IO and then truncates
* dst IO to src IO's original size. */
off_t end = lseek(stp->dst_fptr->fd, 0, SEEK_END);
lseek(stp->dst_fptr->fd, 0, SEEK_SET);
if (end > (off_t)0) return 0;
}
if (src_offset > (off_t)0) {
off_t r;

Просмотреть файл

@ -476,6 +476,18 @@ class TestIO < Test::Unit::TestCase
}
end
def test_copy_stream_append_to_nonempty
with_srccontent("foobar") {|src, content|
preface = 'preface'
File.write('dst', preface)
File.open('dst', 'ab') do |dst|
ret = IO.copy_stream(src, dst)
assert_equal(content.bytesize, ret)
assert_equal(preface + content, File.read("dst"))
end
}
end
def test_copy_stream_smaller
with_srccontent {|src, content|