@@ -753,25 +753,38 @@ _trap_eintr(void)
753753 */
754754
755755static PyObject *
756- buffered_flush (buffered * self , PyObject * args )
756+ buffered_flush_and_rewind_unlocked (buffered * self )
757757{
758758 PyObject * res ;
759759
760- CHECK_INITIALIZED (self )
761- CHECK_CLOSED (self , "flush of closed file" )
762-
763- if (!ENTER_BUFFERED (self ))
764- return NULL ;
765760 res = _bufferedwriter_flush_unlocked (self , 0 );
766- if (res != NULL && self -> readable ) {
761+ if (res == NULL )
762+ return NULL ;
763+ Py_DECREF (res );
764+
765+ if (self -> readable ) {
767766 /* Rewind the raw stream so that its position corresponds to
768767 the current logical position. */
769768 Py_off_t n ;
770769 n = _buffered_raw_seek (self , - RAW_OFFSET (self ), 1 );
771- if (n == -1 )
772- Py_CLEAR (res );
773770 _bufferedreader_reset_buf (self );
771+ if (n == -1 )
772+ return NULL ;
774773 }
774+ Py_RETURN_NONE ;
775+ }
776+
777+ static PyObject *
778+ buffered_flush (buffered * self , PyObject * args )
779+ {
780+ PyObject * res ;
781+
782+ CHECK_INITIALIZED (self )
783+ CHECK_CLOSED (self , "flush of closed file" )
784+
785+ if (!ENTER_BUFFERED (self ))
786+ return NULL ;
787+ res = buffered_flush_and_rewind_unlocked (self );
775788 LEAVE_BUFFERED (self )
776789
777790 return res ;
@@ -792,7 +805,7 @@ buffered_peek(buffered *self, PyObject *args)
792805 return NULL ;
793806
794807 if (self -> writable ) {
795- res = _bufferedwriter_flush_unlocked (self , 1 );
808+ res = buffered_flush_and_rewind_unlocked (self );
796809 if (res == NULL )
797810 goto end ;
798811 Py_CLEAR (res );
@@ -827,19 +840,18 @@ buffered_read(buffered *self, PyObject *args)
827840 if (!ENTER_BUFFERED (self ))
828841 return NULL ;
829842 res = _bufferedreader_read_all (self );
830- LEAVE_BUFFERED (self )
831843 }
832844 else {
833845 res = _bufferedreader_read_fast (self , n );
834- if (res == Py_None ) {
835- Py_DECREF (res );
836- if (!ENTER_BUFFERED (self ))
837- return NULL ;
838- res = _bufferedreader_read_generic (self , n );
839- LEAVE_BUFFERED (self )
840- }
846+ if (res != Py_None )
847+ return res ;
848+ Py_DECREF (res );
849+ if (!ENTER_BUFFERED (self ))
850+ return NULL ;
851+ res = _bufferedreader_read_generic (self , n );
841852 }
842853
854+ LEAVE_BUFFERED (self )
843855 return res ;
844856}
845857
@@ -865,13 +877,6 @@ buffered_read1(buffered *self, PyObject *args)
865877 if (!ENTER_BUFFERED (self ))
866878 return NULL ;
867879
868- if (self -> writable ) {
869- res = _bufferedwriter_flush_unlocked (self , 1 );
870- if (res == NULL )
871- goto end ;
872- Py_CLEAR (res );
873- }
874-
875880 /* Return up to n bytes. If at least one byte is buffered, we
876881 only return buffered bytes. Otherwise, we do one raw read. */
877882
@@ -891,6 +896,13 @@ buffered_read1(buffered *self, PyObject *args)
891896 goto end ;
892897 }
893898
899+ if (self -> writable ) {
900+ res = buffered_flush_and_rewind_unlocked (self );
901+ if (res == NULL )
902+ goto end ;
903+ Py_DECREF (res );
904+ }
905+
894906 /* Fill the buffer from the raw stream, and copy it to the result. */
895907 _bufferedreader_reset_buf (self );
896908 r = _bufferedreader_fill_buffer (self );
@@ -939,7 +951,7 @@ buffered_readinto(buffered *self, PyObject *args)
939951 goto end_unlocked ;
940952
941953 if (self -> writable ) {
942- res = _bufferedwriter_flush_unlocked (self , 0 );
954+ res = buffered_flush_and_rewind_unlocked (self );
943955 if (res == NULL )
944956 goto end ;
945957 Py_CLEAR (res );
@@ -1022,12 +1034,6 @@ _buffered_readline(buffered *self, Py_ssize_t limit)
10221034 goto end_unlocked ;
10231035
10241036 /* Now we try to get some more from the raw stream */
1025- if (self -> writable ) {
1026- res = _bufferedwriter_flush_unlocked (self , 1 );
1027- if (res == NULL )
1028- goto end ;
1029- Py_CLEAR (res );
1030- }
10311037 chunks = PyList_New (0 );
10321038 if (chunks == NULL )
10331039 goto end ;
@@ -1041,9 +1047,16 @@ _buffered_readline(buffered *self, Py_ssize_t limit)
10411047 }
10421048 Py_CLEAR (res );
10431049 written += n ;
1050+ self -> pos += n ;
10441051 if (limit >= 0 )
10451052 limit -= n ;
10461053 }
1054+ if (self -> writable ) {
1055+ PyObject * r = buffered_flush_and_rewind_unlocked (self );
1056+ if (r == NULL )
1057+ goto end ;
1058+ Py_DECREF (r );
1059+ }
10471060
10481061 for (;;) {
10491062 _bufferedreader_reset_buf (self );
@@ -1212,20 +1225,11 @@ buffered_truncate(buffered *self, PyObject *args)
12121225 return NULL ;
12131226
12141227 if (self -> writable ) {
1215- res = _bufferedwriter_flush_unlocked (self , 0 );
1228+ res = buffered_flush_and_rewind_unlocked (self );
12161229 if (res == NULL )
12171230 goto end ;
12181231 Py_CLEAR (res );
12191232 }
1220- if (self -> readable ) {
1221- if (pos == Py_None ) {
1222- /* Rewind the raw stream so that its position corresponds to
1223- the current logical position. */
1224- if (_buffered_raw_seek (self , - RAW_OFFSET (self ), 1 ) == -1 )
1225- goto end ;
1226- }
1227- _bufferedreader_reset_buf (self );
1228- }
12291233 res = PyObject_CallMethodObjArgs (self -> raw , _PyIO_str_truncate , pos , NULL );
12301234 if (res == NULL )
12311235 goto end ;
@@ -1416,15 +1420,16 @@ _bufferedreader_read_all(buffered *self)
14161420 self -> buffer + self -> pos , current_size );
14171421 if (data == NULL )
14181422 return NULL ;
1423+ self -> pos += current_size ;
14191424 }
1420- _bufferedreader_reset_buf (self );
14211425 /* We're going past the buffer's bounds, flush it */
14221426 if (self -> writable ) {
1423- res = _bufferedwriter_flush_unlocked (self , 1 );
1427+ res = buffered_flush_and_rewind_unlocked (self );
14241428 if (res == NULL )
14251429 return NULL ;
14261430 Py_CLEAR (res );
14271431 }
1432+ _bufferedreader_reset_buf (self );
14281433
14291434 if (PyObject_HasAttr (self -> raw , _PyIO_str_readall )) {
14301435 chunk = PyObject_CallMethodObjArgs (self -> raw , _PyIO_str_readall , NULL );
@@ -1540,6 +1545,14 @@ _bufferedreader_read_generic(buffered *self, Py_ssize_t n)
15401545 memcpy (out , self -> buffer + self -> pos , current_size );
15411546 remaining -= current_size ;
15421547 written += current_size ;
1548+ self -> pos += current_size ;
1549+ }
1550+ /* Flush the write buffer if necessary */
1551+ if (self -> writable ) {
1552+ PyObject * r = buffered_flush_and_rewind_unlocked (self );
1553+ if (r == NULL )
1554+ goto error ;
1555+ Py_DECREF (r );
15431556 }
15441557 _bufferedreader_reset_buf (self );
15451558 while (remaining > 0 ) {
0 commit comments