Skip to content

Commit 7ae19ef

Browse files
bpo-42237: Fix os.sendfile() on illumos (GH-23154)
(cherry picked from commit fd4ed57) Co-authored-by: Jakub Stasiak <jakub@stasiak.at>
1 parent 33922cb commit 7ae19ef

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix `os.sendfile()` on illumos.

Modules/posixmodule.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9469,11 +9469,26 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj,
94699469
if (offset >= st.st_size) {
94709470
return Py_BuildValue("i", 0);
94719471
}
9472+
9473+
// On illumos specifically sendfile() may perform a partial write but
9474+
// return -1/an error (in one confirmed case the destination socket
9475+
// had a 5 second timeout set and errno was EAGAIN) and it's on the client
9476+
// code to check if the offset parameter was modified by sendfile().
9477+
//
9478+
// We need this variable to track said change.
9479+
off_t original_offset = offset;
94729480
#endif
94739481

94749482
do {
94759483
Py_BEGIN_ALLOW_THREADS
94769484
ret = sendfile(out_fd, in_fd, &offset, count);
9485+
#if defined(__sun) && defined(__SVR4)
9486+
// This handles illumos-specific sendfile() partial write behavior,
9487+
// see a comment above for more details.
9488+
if (ret < 0 && offset != original_offset) {
9489+
ret = offset - original_offset;
9490+
}
9491+
#endif
94779492
Py_END_ALLOW_THREADS
94789493
} while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
94799494
if (ret < 0)

0 commit comments

Comments
 (0)