[issue11351] Mac OS X os.sendfile()

Steffen Daode Nurpmeso report at bugs.python.org
Tue Mar 1 13:40:19 CET 2011


Steffen Daode Nurpmeso <sdaoden at googlemail.com> added the comment:

I'm trashing your mailbox, but 
http://bugs.python.org/file20949/issue11351-2.patch should do 
'total+=blen' not 'total+=len'.
Anyway i attach yet a third patch which does some code cleanup in 
general and is a bit more of my very own coding style, because 
i have seen that gotos seem to be possible in Python, and because 
i was unable to enjoy the code (and this is beautiful C!) before. 
It also follows PEP guidelines more than before.

This compiles clean and runs the test even if i
    hg revert && hg patch
(I'm a bit messy)

----------
Added file: http://bugs.python.org/file20955/issue11351-3.patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue11351>
_______________________________________
-------------- next part --------------
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -5866,37 +5866,47 @@
 }
 
 #ifdef HAVE_SENDFILE
-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
-static int
+# if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+static Py_ssize_t
 iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
 {
     int i, j;
+    Py_ssize_t blen, total = 0;
+
     *iov = PyMem_New(struct iovec, cnt);
     if (*iov == NULL) {
         PyErr_NoMemory();
-        return 0;
-    }
+        goto jleave;
+    }
+
     *buf = PyMem_New(Py_buffer, cnt);
     if (*buf == NULL) {
         PyMem_Del(*iov);
         PyErr_NoMemory();
-        return 0;
+        goto jleave;
     }
 
     for (i = 0; i < cnt; i++) {
-        if (PyObject_GetBuffer(PySequence_GetItem(seq, i), &(*buf)[i],
-                type) == -1) {
-            PyMem_Del(*iov);
-            for (j = 0; j < i; j++) {
-                PyBuffer_Release(&(*buf)[j]);
-           }
-            PyMem_Del(*buf);
-            return 0;
-        }
+        if (PyObject_GetBuffer(PySequence_GetItem(seq, i),
+                               &(*buf)[i], type) == -1)
+            goto jrelease;
+
         (*iov)[i].iov_base = (*buf)[i].buf;
-        (*iov)[i].iov_len = (*buf)[i].len;
-    }
-    return 1;
+        blen = (*buf)[i].len;
+        (*iov)[i].iov_len = blen;
+        total += blen;
+    }
+
+jleave:
+    return total;
+
+jrelease:
+    PyMem_Del(*iov);
+    for (j = 0; j < i; j++)
+        PyBuffer_Release(&(*buf)[j]);
+    PyMem_Del(*buf);
+    total = 0;
+    goto jleave;
 }
 
 static void
@@ -5904,12 +5914,11 @@
 {
     int i;
     PyMem_Del(iov);
-    for (i = 0; i < cnt; i++) {
+    for (i = 0; i < cnt; i++)
         PyBuffer_Release(&buf[i]);
-    }
     PyMem_Del(buf);
 }
-#endif
+# endif
 
 PyDoc_STRVAR(posix_sendfile__doc__,
 "sendfile(out, in, offset, nbytes) -> byteswritten\n\
@@ -5924,10 +5933,10 @@
     Py_ssize_t ret;
     off_t offset;
 
-#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
-#ifndef __APPLE__
+# if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
+#  ifndef __APPLE__
     Py_ssize_t len;
-#endif
+#  endif
     PyObject *headers = NULL, *trailers = NULL;
     Py_buffer *hbuf, *tbuf;
     off_t sbytes;
@@ -5939,46 +5948,58 @@
                                 "offset", "count",
                                 "headers", "trailers", "flags", NULL};
 
-#ifdef __APPLE__
     if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
-        keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes,
-#else
-    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
-        keywords, &out, &in, _parse_off_t, &offset, &len,
-#endif
-                &headers, &trailers, &flags))
+                                     keywords, &out, &in, _parse_off_t,
+#  ifdef __APPLE__
+                                     &offset, _parse_off_t, &sbytes,
+#  else
+                                     &offset, &len,
+#  endif
+                                     &headers, &trailers, &flags))
             return NULL;
+
     if (headers != NULL) {
         if (!PySequence_Check(headers)) {
             PyErr_SetString(PyExc_TypeError,
-                "sendfile() headers must be a sequence or None");
+                            "sendfile() headers must be a sequence or None");
             return NULL;
         } else {
+            Py_ssize_t i = 0; /* (Avoid uninitialized warning) */
             sf.hdr_cnt = PySequence_Size(headers);
-            if (sf.hdr_cnt > 0 && !iov_setup(&(sf.headers), &hbuf,
-                    headers, sf.hdr_cnt, PyBUF_SIMPLE))
+            if (sf.hdr_cnt > 0 &&
+                (i = iov_setup(&(sf.headers), &hbuf,
+                               headers, sf.hdr_cnt, PyBUF_SIMPLE)) == 0)
                 return NULL;
+#  ifdef __APPLE__
+            sbytes += i;
+#  endif
         }
     }
+
     if (trailers != NULL) {
         if (!PySequence_Check(trailers)) {
             PyErr_SetString(PyExc_TypeError,
-                "sendfile() trailers must be a sequence or None");
+                            "sendfile() trailers must be a sequence or None");
             return NULL;
         } else {
+            Py_ssize_t i = 0; /* (Avoid uninitialized warning) */
             sf.trl_cnt = PySequence_Size(trailers);
-            if (sf.trl_cnt > 0 && !iov_setup(&(sf.trailers), &tbuf,
-                    trailers, sf.trl_cnt, PyBUF_SIMPLE))
+            if (sf.trl_cnt > 0 &&
+                (i = iov_setup(&(sf.trailers), &tbuf,
+                               trailers, sf.trl_cnt, PyBUF_SIMPLE)) == 0)
                 return NULL;
+#  ifdef __APPLE__
+            sbytes += i;
+#  endif
         }
     }
 
     Py_BEGIN_ALLOW_THREADS
-#ifdef __APPLE__
+#  ifdef __APPLE__
     ret = sendfile(in, out, offset, &sbytes, &sf, flags);
-#else
+#  else
     ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
-#endif
+#  endif
     Py_END_ALLOW_THREADS
 
     if (sf.headers != NULL)
@@ -5988,36 +6009,35 @@
 
     if (ret < 0) {
         if ((errno == EAGAIN) || (errno == EBUSY)) {
-            if (sbytes != 0) {
-                // some data has been sent
+            /* Some data has been sent */
+            if (sbytes != 0)
                 goto done;
-            }
-            else {
-                // no data has been sent; upper application is supposed
-                // to retry on EAGAIN or EBUSY
-                return posix_error();
-            }
+            /* No data has been sent; upper application is supposed to retry on
+             * EAGAIN or EBUSY */
+            return posix_error();
         }
         return posix_error();
     }
     goto done;
 
 done:
-    #if !defined(HAVE_LARGEFILE_SUPPORT)
+#  if !defined(HAVE_LARGEFILE_SUPPORT)
         return Py_BuildValue("l", sbytes);
-    #else
+#  else
         return Py_BuildValue("L", sbytes);
-    #endif
-
-#else
+#  endif
+
+# else
     Py_ssize_t count;
     PyObject *offobj;
     static char *keywords[] = {"out", "in",
                                 "offset", "count", NULL};
+
     if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
-            keywords, &out, &in, &offobj, &count))
-        return NULL;
-#ifdef linux
+                                     keywords, &out, &in, &offobj, &count))
+        return NULL;
+
+#  ifdef linux
     if (offobj == Py_None) {
         Py_BEGIN_ALLOW_THREADS
         ret = sendfile(out, in, NULL, count);
@@ -6027,16 +6047,17 @@
         Py_INCREF(Py_None);
         return Py_BuildValue("nO", ret, Py_None);
     }
-#endif
+#  endif
     if (!_parse_off_t(offobj, &offset))
         return NULL;
+
     Py_BEGIN_ALLOW_THREADS
     ret = sendfile(out, in, &offset, count);
     Py_END_ALLOW_THREADS
     if (ret < 0)
         return posix_error();
     return Py_BuildValue("n", ret);
-#endif
+# endif
 }
 #endif
 


More information about the Python-bugs-list mailing list