Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e9d44cc

Browse files
author
Victor Stinner
committed
Issue #12175: FileIO.readall() now only reads the file position and size once.
1 parent 5eb5559 commit e9d44cc

2 files changed

Lines changed: 34 additions & 8 deletions

File tree

Misc/NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,10 @@ Core and Builtins
161161
Library
162162
-------
163163

164-
- Issue #12180: Fixed a few remaining errors in test_packaging when no
164+
- Issue #12175: FileIO.readall() now only reads the file position and size
165+
once.
166+
167+
- Issue #12180: Fixed a few remaining errors in test_packaging when no
165168
threading.
166169

167170
- Issue #12175: RawIOBase.readall() now returns None if read() returns None.

Modules/_io/fileio.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -547,14 +547,14 @@ fileio_readinto(fileio *self, PyObject *args)
547547
}
548548

549549
static size_t
550-
new_buffersize(fileio *self, size_t currentsize)
550+
new_buffersize(fileio *self, size_t currentsize
551+
#ifdef HAVE_FSTAT
552+
, off_t pos, off_t end
553+
#endif
554+
)
551555
{
552556
#ifdef HAVE_FSTAT
553-
off_t pos, end;
554-
struct stat st;
555-
if (fstat(self->fd, &st) == 0) {
556-
end = st.st_size;
557-
pos = lseek(self->fd, 0L, SEEK_CUR);
557+
if (end != (off_t)-1) {
558558
/* Files claiming a size smaller than SMALLCHUNK may
559559
actually be streaming pseudo-files. In this case, we
560560
apply the more aggressive algorithm below.
@@ -579,9 +579,14 @@ new_buffersize(fileio *self, size_t currentsize)
579579
static PyObject *
580580
fileio_readall(fileio *self)
581581
{
582+
#ifdef HAVE_FSTAT
583+
struct stat st;
584+
off_t pos, end;
585+
#endif
582586
PyObject *result;
583587
Py_ssize_t total = 0;
584588
int n;
589+
size_t newsize;
585590

586591
if (self->fd < 0)
587592
return err_closed();
@@ -592,8 +597,23 @@ fileio_readall(fileio *self)
592597
if (result == NULL)
593598
return NULL;
594599

600+
#ifdef HAVE_FSTAT
601+
#if defined(MS_WIN64) || defined(MS_WINDOWS)
602+
pos = _lseeki64(self->fd, 0L, SEEK_CUR);
603+
#else
604+
pos = lseek(self->fd, 0L, SEEK_CUR);
605+
#endif
606+
if (fstat(self->fd, &st) == 0)
607+
end = st.st_size;
608+
else
609+
end = (off_t)-1;
610+
#endif
595611
while (1) {
596-
size_t newsize = new_buffersize(self, total);
612+
#ifdef HAVE_FSTAT
613+
newsize = new_buffersize(self, total, pos, end);
614+
#else
615+
newsize = new_buffersize(self, total);
616+
#endif
597617
if (newsize > PY_SSIZE_T_MAX || newsize <= 0) {
598618
PyErr_SetString(PyExc_OverflowError,
599619
"unbounded read returned more bytes "
@@ -632,6 +652,9 @@ fileio_readall(fileio *self)
632652
return NULL;
633653
}
634654
total += n;
655+
#ifdef HAVE_FSTAT
656+
pos += n;
657+
#endif
635658
}
636659

637660
if (PyBytes_GET_SIZE(result) > total) {

0 commit comments

Comments
 (0)