3
3
#define PY_SSIZE_T_CLEAN
4
4
#include "Python.h"
5
5
#include "structmember.h"
6
+ #include <stdbool.h>
6
7
#ifdef HAVE_SYS_TYPES_H
7
8
#include <sys/types.h>
8
9
#endif
@@ -74,7 +75,7 @@ _Py_IDENTIFIER(name);
74
75
#define PyFileIO_Check (op ) (PyObject_TypeCheck((op), &PyFileIO_Type))
75
76
76
77
/* Forward declarations */
77
- static PyObject * portable_lseek (fileio * self , PyObject * posobj , int whence );
78
+ static PyObject * portable_lseek (fileio * self , PyObject * posobj , int whence , bool suppress_pipe_error );
78
79
79
80
int
80
81
_PyFileIO_closed (PyObject * self )
@@ -475,7 +476,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
475
476
/* For consistent behaviour, we explicitly seek to the
476
477
end of file (otherwise, it might be done only on the
477
478
first write()). */
478
- PyObject * pos = portable_lseek (self , NULL , 2 );
479
+ PyObject * pos = portable_lseek (self , NULL , 2 , true );
479
480
if (pos == NULL )
480
481
goto error ;
481
482
Py_DECREF (pos );
@@ -598,7 +599,7 @@ _io_FileIO_seekable_impl(fileio *self)
598
599
return err_closed ();
599
600
if (self -> seekable < 0 ) {
600
601
/* portable_lseek() sets the seekable attribute */
601
- PyObject * pos = portable_lseek (self , NULL , SEEK_CUR );
602
+ PyObject * pos = portable_lseek (self , NULL , SEEK_CUR , false );
602
603
assert (self -> seekable >= 0 );
603
604
if (pos == NULL ) {
604
605
PyErr_Clear ();
@@ -865,7 +866,7 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b)
865
866
866
867
/* Cribbed from posix_lseek() */
867
868
static PyObject *
868
- portable_lseek (fileio * self , PyObject * posobj , int whence )
869
+ portable_lseek (fileio * self , PyObject * posobj , int whence , bool suppress_pipe_error )
869
870
{
870
871
Py_off_t pos , res ;
871
872
int fd = self -> fd ;
@@ -916,8 +917,13 @@ portable_lseek(fileio *self, PyObject *posobj, int whence)
916
917
self -> seekable = (res >= 0 );
917
918
}
918
919
919
- if (res < 0 )
920
- return PyErr_SetFromErrno (PyExc_OSError );
920
+ if (res < 0 ) {
921
+ if (suppress_pipe_error && errno == ESPIPE ) {
922
+ res = 0 ;
923
+ } else {
924
+ return PyErr_SetFromErrno (PyExc_OSError );
925
+ }
926
+ }
921
927
922
928
#if defined(HAVE_LARGEFILE_SUPPORT )
923
929
return PyLong_FromLongLong (res );
@@ -950,7 +956,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
950
956
if (self -> fd < 0 )
951
957
return err_closed ();
952
958
953
- return portable_lseek (self , pos , whence );
959
+ return portable_lseek (self , pos , whence , false );
954
960
}
955
961
956
962
/*[clinic input]
@@ -968,7 +974,7 @@ _io_FileIO_tell_impl(fileio *self)
968
974
if (self -> fd < 0 )
969
975
return err_closed ();
970
976
971
- return portable_lseek (self , NULL , 1 );
977
+ return portable_lseek (self , NULL , 1 , false );
972
978
}
973
979
974
980
#ifdef HAVE_FTRUNCATE
@@ -999,7 +1005,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
999
1005
1000
1006
if (posobj == Py_None || posobj == NULL ) {
1001
1007
/* Get the current position. */
1002
- posobj = portable_lseek (self , NULL , 1 );
1008
+ posobj = portable_lseek (self , NULL , 1 , false );
1003
1009
if (posobj == NULL )
1004
1010
return NULL ;
1005
1011
}
0 commit comments