serhiy-storchaka · GitHub

Bug report

os.sendfile() on Solaris/illumos can return a bogus number of transferred bytes instead of raising an error.

illumos sendfile(3EXT) is a wrapper around the sendfilev(3EXT) system call. It returns the number of transferred bytes by adding it to *off, but does not initialize it, so *off is advanced by an indeterminate value if the transfer failed before writing any data.

os_sendfile_impl() derives the number of transferred bytes from the change of the offset, to support partial writes (gh-86403), and therefore turns such errors into a positive result:

>>> import os
>>> fd = os.open("file", os.O_RDONLY)   # not writable, sendfile() fails with EBADF
>>> os.sendfile(fd, fd, 0, 65536)
3

shutil.copyfile() can therefore silently leave the destination file incomplete, and test_shutil.TestZeroCopySendfile.test_same_file fails.

sendfilev() reports the number of transferred bytes in an explicit out parameter and can be used instead.

Linked PRs

Read the original on github.com ↗