Issue #12175: FileIO.readall() now only reads the file position and size once.

This commit is contained in:
Victor Stinner 2011-05-26 00:16:44 +02:00
parent 5eb555990a
commit e9d44ccb22
2 changed files with 34 additions and 8 deletions

View File

@ -161,7 +161,10 @@ Core and Builtins
Library
-------
- Issue #12180: Fixed a few remaining errors in test_packaging when no
- Issue #12175: FileIO.readall() now only reads the file position and size
once.
- Issue #12180: Fixed a few remaining errors in test_packaging when no
threading.
- Issue #12175: RawIOBase.readall() now returns None if read() returns None.

View File

@ -547,14 +547,14 @@ fileio_readinto(fileio *self, PyObject *args)
}
static size_t
new_buffersize(fileio *self, size_t currentsize)
new_buffersize(fileio *self, size_t currentsize
#ifdef HAVE_FSTAT
, off_t pos, off_t end
#endif
)
{
#ifdef HAVE_FSTAT
off_t pos, end;
struct stat st;
if (fstat(self->fd, &st) == 0) {
end = st.st_size;
pos = lseek(self->fd, 0L, SEEK_CUR);
if (end != (off_t)-1) {
/* Files claiming a size smaller than SMALLCHUNK may
actually be streaming pseudo-files. In this case, we
apply the more aggressive algorithm below.
@ -579,9 +579,14 @@ new_buffersize(fileio *self, size_t currentsize)
static PyObject *
fileio_readall(fileio *self)
{
#ifdef HAVE_FSTAT
struct stat st;
off_t pos, end;
#endif
PyObject *result;
Py_ssize_t total = 0;
int n;
size_t newsize;
if (self->fd < 0)
return err_closed();
@ -592,8 +597,23 @@ fileio_readall(fileio *self)
if (result == NULL)
return NULL;
#ifdef HAVE_FSTAT
#if defined(MS_WIN64) || defined(MS_WINDOWS)
pos = _lseeki64(self->fd, 0L, SEEK_CUR);
#else
pos = lseek(self->fd, 0L, SEEK_CUR);
#endif
if (fstat(self->fd, &st) == 0)
end = st.st_size;
else
end = (off_t)-1;
#endif
while (1) {
size_t newsize = new_buffersize(self, total);
#ifdef HAVE_FSTAT
newsize = new_buffersize(self, total, pos, end);
#else
newsize = new_buffersize(self, total);
#endif
if (newsize > PY_SSIZE_T_MAX || newsize <= 0) {
PyErr_SetString(PyExc_OverflowError,
"unbounded read returned more bytes "
@ -632,6 +652,9 @@ fileio_readall(fileio *self)
return NULL;
}
total += n;
#ifdef HAVE_FSTAT
pos += n;
#endif
}
if (PyBytes_GET_SIZE(result) > total) {