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

AltStyle によって変換されたページ (->オリジナル) /