From 371f7a38c6ce55e7c26cb5602d5dfd3db1f1150b Mon Sep 17 00:00:00 2001 From: Jakub Stasiak Date: Thu, 12 Nov 2020 10:49:30 +0100 Subject: [PATCH] [3.8] bpo-42237: Fix os.sendfile() on illumos (GH-23154). (cherry picked from commit fd4ed57674c675e05bd5d577dd5047a333c76c78) Co-authored-by: Jakub Stasiak --- .../2020-11-10-14-27-49.bpo-42237.F363jO.rst | 1 + Modules/posixmodule.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-11-10-14-27-49.bpo-42237.F363jO.rst diff --git a/Misc/NEWS.d/next/Library/2020-11-10-14-27-49.bpo-42237.F363jO.rst b/Misc/NEWS.d/next/Library/2020-11-10-14-27-49.bpo-42237.F363jO.rst new file mode 100644 index 00000000000000..50cab6e1f11f84 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-11-10-14-27-49.bpo-42237.F363jO.rst @@ -0,0 +1 @@ +Fix `os.sendfile()` on illumos. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 726e3723f99d39..3b33186c59521c 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9281,9 +9281,27 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) if (!Py_off_t_converter(offobj, &offset)) return NULL; + +#if defined(__sun) && defined(__SVR4) + // On illumos specifically sendfile() may perform a partial write but + // return -1/an error (in one confirmed case the destination socket + // had a 5 second timeout set and errno was EAGAIN) and it's on the client + // code to check if the offset parameter was modified by sendfile(). + // + // We need this variable to track said change. + off_t original_offset = offset; +#endif + do { Py_BEGIN_ALLOW_THREADS ret = sendfile(out, in, &offset, count); +#if defined(__sun) && defined(__SVR4) + // This handles illumos-specific sendfile() partial write behavior, + // see a comment above for more details. + if (ret < 0 && offset != original_offset) { + ret = offset - original_offset; + } +#endif Py_END_ALLOW_THREADS } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0)