diff -r 1492a42b8308 Objects/fileobject.c --- a/Objects/fileobject.c Wed Jul 02 23:12:48 2014 +0200 +++ b/Objects/fileobject.c Thu Jul 03 00:33:35 2014 +0200 @@ -1053,7 +1053,7 @@ file_read(PyFileObject *f, PyObject *arg { long bytesrequested = -1; size_t bytesread, buffersize, chunksize; - PyObject *v; + PyObject *v = NULL; if (f->f_fp == NULL) return err_closed(); @@ -1072,34 +1072,29 @@ file_read(PyFileObject *f, PyObject *arg buffersize = bytesrequested; if (buffersize > PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, - "requested number of bytes is more than a Python string can hold"); - return NULL; + "requested number of bytes is more than " + "a Python string can hold"); + goto error; } v = PyString_FromStringAndSize((char *)NULL, buffersize); if (v == NULL) - return NULL; + goto error; bytesread = 0; for (;;) { int interrupted; FILE_BEGIN_ALLOW_THREADS(f) - errno = 0; chunksize = Py_UniversalNewlineFread(BUF(v) + bytesread, buffersize - bytesread, f->f_fp, (PyObject *)f); interrupted = ferror(f->f_fp) && errno == EINTR; FILE_END_ALLOW_THREADS(f) - if (interrupted) { + bytesread += chunksize; + if (ferror(f->f_fp)) { clearerr(f->f_fp); - if (PyErr_CheckSignals()) { - Py_DECREF(v); - return NULL; + if (interrupted) { + if (PyErr_CheckSignals()) + goto error; + continue; } - } - if (chunksize == 0) { - if (interrupted) - continue; - if (!ferror(f->f_fp)) - break; - clearerr(f->f_fp); /* When in non-blocking mode, data shouldn't * be discarded if a blocking signal was * received. That will also happen if @@ -1107,10 +1102,10 @@ file_read(PyFileObject *f, PyObject *arg if (bytesread > 0 && BLOCKED_ERRNO(errno)) break; PyErr_SetFromErrno(PyExc_IOError); - Py_DECREF(v); - return NULL; + goto error; } - bytesread += chunksize; + if (chunksize == 0) + break; if (bytesread < buffersize && !interrupted) { clearerr(f->f_fp); break; @@ -1118,15 +1113,19 @@ file_read(PyFileObject *f, PyObject *arg if (bytesrequested < 0) { buffersize = new_buffersize(f, buffersize); if (_PyString_Resize(&v, buffersize) < 0) - return NULL; + goto error; } else { /* Got what was requested. */ break; } } if (bytesread != buffersize && _PyString_Resize(&v, bytesread)) - return NULL; + goto error; return v; + +error: + Py_XDECREF(v); + return NULL; } static PyObject * @@ -1154,33 +1153,31 @@ file_readinto(PyFileObject *f, PyObject while (ntodo > 0) { int interrupted; FILE_BEGIN_ALLOW_THREADS(f) - errno = 0; nnow = Py_UniversalNewlineFread(ptr+ndone, ntodo, f->f_fp, (PyObject *)f); interrupted = ferror(f->f_fp) && errno == EINTR; FILE_END_ALLOW_THREADS(f) - if (interrupted) { - clearerr(f->f_fp); - if (PyErr_CheckSignals()) { - PyBuffer_Release(&pbuf); - return NULL; - } - } - if (nnow == 0) { - if (interrupted) - continue; - if (!ferror(f->f_fp)) - break; - PyErr_SetFromErrno(PyExc_IOError); - clearerr(f->f_fp); - PyBuffer_Release(&pbuf); - return NULL; - } ndone += nnow; ntodo -= nnow; + if (ferror(f->f_fp)) { + clearerr(f->f_fp); + if (interrupted) { + if (PyErr_CheckSignals()) + goto error; + continue; + } + PyErr_SetFromErrno(PyExc_IOError); + goto error; + } + if (nnow == 0) + break; } PyBuffer_Release(&pbuf); return PyInt_FromSsize_t(ndone); + +error: + PyBuffer_Release(&pbuf); + return NULL; } /************************************************************************** @@ -1673,7 +1670,6 @@ file_readlines(PyFileObject *f, PyObject size_t totalread = 0; char *p, *q, *end; int err; - int shortread = 0; /* bool, did the previous read come up short? */ if (f->f_fp == NULL) return err_closed(); @@ -1689,33 +1685,35 @@ file_readlines(PyFileObject *f, PyObject if ((list = PyList_New(0)) == NULL) return NULL; for (;;) { + int shortread = 0; /* bool, did the previous read come up short? */ + int interrupted; + if (shortread) - nread = 0; - else { - FILE_BEGIN_ALLOW_THREADS(f) - errno = 0; - nread = Py_UniversalNewlineFread(buffer+nfilled, - buffersize-nfilled, f->f_fp, (PyObject *)f); - FILE_END_ALLOW_THREADS(f) - shortread = (nread < buffersize-nfilled); - } - if (nread == 0) { - sizehint = 0; - if (!ferror(f->f_fp)) - break; - if (errno == EINTR) { - if (PyErr_CheckSignals()) { + break; + + FILE_BEGIN_ALLOW_THREADS(f) + nread = Py_UniversalNewlineFread(buffer+nfilled, + buffersize-nfilled, f->f_fp, (PyObject *)f); + interrupted = ferror(f->f_fp) && errno == EINTR; + FILE_END_ALLOW_THREADS(f) + + shortread = (nread < buffersize-nfilled); + totalread += nread; + + if (ferror(f->f_fp)) { + clearerr(f->f_fp); + if (interrupted) { + if (PyErr_CheckSignals()) goto error; - } - clearerr(f->f_fp); - shortread = 0; continue; } PyErr_SetFromErrno(PyExc_IOError); - clearerr(f->f_fp); goto error; } - totalread += nread; + + if (nread == 0) + break; + p = (char *)memchr(buffer+nfilled, '\n', nread); if (p == NULL) { /* Need a larger buffer to fit this line */ @@ -1761,10 +1759,12 @@ file_readlines(PyFileObject *f, PyObject /* Move the remaining incomplete line to the start */ nfilled = end-q; memmove(buffer, q, nfilled); - if (sizehint > 0) + if (sizehint > 0) { if (totalread >= (size_t)sizehint) break; + } } + if (nfilled != 0) { /* Partial last line */ line = PyString_FromStringAndSize(buffer, nfilled); @@ -2239,6 +2239,7 @@ static int readahead(PyFileObject *f, int bufsize) { Py_ssize_t chunksize; + int interrupted; if (f->f_buf != NULL) { if( (f->f_bufend - f->f_bufptr) >= 1) @@ -2251,14 +2252,18 @@ readahead(PyFileObject *f, int bufsize) return -1; } FILE_BEGIN_ALLOW_THREADS(f) - errno = 0; chunksize = Py_UniversalNewlineFread( f->f_buf, bufsize, f->f_fp, (PyObject *)f); + interrupted = ferror(f->f_fp) && errno == EINTR; FILE_END_ALLOW_THREADS(f) - if (chunksize == 0) { - if (ferror(f->f_fp)) { + if (ferror(f->f_fp)) { + clearerr(f->f_fp); + if (interrupted) { + if (PyErr_CheckSignals()) + return -1; + } + else { PyErr_SetFromErrno(PyExc_IOError); - clearerr(f->f_fp); drop_readahead(f); return -1; } @@ -2824,6 +2829,9 @@ Py_UniversalNewlineFread(char *buf, size assert(buf != NULL); assert(stream != NULL); + clearerr(stream); + errno = 0; + if (!fobj || !PyFile_Check(fobj)) { errno = ENXIO; /* What can you do... */ return 0;