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

Skip to content

Commit cada293

Browse files
committed
As noted by Per Cederqvist, new_buffersize() sometimes returns the
buffer increment, and sometimes the new buffer size. Make it do what its name says, and fix the one place where this matters to the caller. Also add a comment explaining why we call lseek() and then ftell().
1 parent 68055ce commit cada293

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

Objects/fileobject.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,22 @@ new_buffersize(f, currentsize)
422422
struct stat st;
423423
if (fstat(fileno(f->f_fp), &st) == 0) {
424424
end = st.st_size;
425+
/* The following is not a bug: we really need to call lseek()
426+
*and* ftell(). The reason is that some stdio libraries
427+
mistakenly flush their buffer when ftell() is called and
428+
the lseek() call it makes fails, thereby throwing away
429+
data that cannot be recovered in any way. To avoid this,
430+
we first test lseek(), and only call ftell() if lseek()
431+
works. We can't use the lseek() value either, because we
432+
need to take the amount of buffered data into account.
433+
(Yet another reason why stdio stinks. :-) */
425434
pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
426435
if (pos >= 0)
427436
pos = ftell(f->f_fp);
428437
if (pos < 0)
429438
clearerr(f->f_fp);
430439
if (end > pos && pos >= 0)
431-
return end - pos + 1;
440+
return currentsize + end - pos + 1;
432441
/* Add 1 so if the file were to grow we'd notice. */
433442
}
434443
#endif
@@ -482,7 +491,7 @@ file_read(f, args)
482491
if (bytesread < buffersize)
483492
break;
484493
if (bytesrequested < 0) {
485-
buffersize = bytesread + new_buffersize(f, buffersize);
494+
buffersize = new_buffersize(f, buffersize);
486495
if (_PyString_Resize(&v, buffersize) < 0)
487496
return NULL;
488497
}

0 commit comments

Comments
 (0)