]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.8] bpo-42237: Fix os.sendfile() on illumos (GH-23154). (GH-23246)
authorJakub Stasiak <jakub@stasiak.at>
Thu, 12 Nov 2020 12:23:48 +0000 (13:23 +0100)
committerGitHub <noreply@github.com>
Thu, 12 Nov 2020 12:23:48 +0000 (14:23 +0200)
(cherry picked from commit fd4ed57674c675e05bd5d577dd5047a333c76c78)

Co-authored-by: Jakub Stasiak <jakub@stasiak.at>
Misc/NEWS.d/next/Library/2020-11-10-14-27-49.bpo-42237.F363jO.rst [new file with mode: 0644]
Modules/posixmodule.c

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 (file)
index 0000000..50cab6e
--- /dev/null
@@ -0,0 +1 @@
+Fix `os.sendfile()` on illumos.
index 726e3723f99d396a50cacd88fa1aa9a1e537af7f..3b33186c59521cbd242394472c1a911e56461ada 100644 (file)
@@ -9281,9 +9281,27 @@ done:
     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)