4
4
#include "Python.h"
5
5
#include "pycore_object.h"
6
6
#include "structmember.h"
7
+ #include <stdbool.h>
7
8
#ifdef HAVE_SYS_TYPES_H
8
9
#include <sys/types.h>
9
10
#endif
@@ -75,7 +76,7 @@ _Py_IDENTIFIER(name);
75
76
#define PyFileIO_Check (op ) (PyObject_TypeCheck((op), &PyFileIO_Type))
76
77
77
78
/* Forward declarations */
78
- static PyObject * portable_lseek (fileio * self , PyObject * posobj , int whence );
79
+ static PyObject * portable_lseek (fileio * self , PyObject * posobj , int whence , bool suppress_pipe_error );
79
80
80
81
int
81
82
_PyFileIO_closed (PyObject * self )
@@ -480,7 +481,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
480
481
/* For consistent behaviour, we explicitly seek to the
481
482
end of file (otherwise, it might be done only on the
482
483
first write()). */
483
- PyObject * pos = portable_lseek (self , NULL , 2 );
484
+ PyObject * pos = portable_lseek (self , NULL , 2 , true );
484
485
if (pos == NULL )
485
486
goto error ;
486
487
Py_DECREF (pos );
@@ -603,7 +604,7 @@ _io_FileIO_seekable_impl(fileio *self)
603
604
return err_closed ();
604
605
if (self -> seekable < 0 ) {
605
606
/* portable_lseek() sets the seekable attribute */
606
- PyObject * pos = portable_lseek (self , NULL , SEEK_CUR );
607
+ PyObject * pos = portable_lseek (self , NULL , SEEK_CUR , false );
607
608
assert (self -> seekable >= 0 );
608
609
if (pos == NULL ) {
609
610
PyErr_Clear ();
@@ -870,7 +871,7 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b)
870
871
871
872
/* Cribbed from posix_lseek() */
872
873
static PyObject *
873
- portable_lseek (fileio * self , PyObject * posobj , int whence )
874
+ portable_lseek (fileio * self , PyObject * posobj , int whence , bool suppress_pipe_error )
874
875
{
875
876
Py_off_t pos , res ;
876
877
int fd = self -> fd ;
@@ -921,8 +922,13 @@ portable_lseek(fileio *self, PyObject *posobj, int whence)
921
922
self -> seekable = (res >= 0 );
922
923
}
923
924
924
- if (res < 0 )
925
- return PyErr_SetFromErrno (PyExc_OSError );
925
+ if (res < 0 ) {
926
+ if (suppress_pipe_error && errno == ESPIPE ) {
927
+ res = 0 ;
928
+ } else {
929
+ return PyErr_SetFromErrno (PyExc_OSError );
930
+ }
931
+ }
926
932
927
933
#if defined(HAVE_LARGEFILE_SUPPORT )
928
934
return PyLong_FromLongLong (res );
@@ -955,7 +961,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
955
961
if (self -> fd < 0 )
956
962
return err_closed ();
957
963
958
- return portable_lseek (self , pos , whence );
964
+ return portable_lseek (self , pos , whence , false );
959
965
}
960
966
961
967
/*[clinic input]
@@ -973,7 +979,7 @@ _io_FileIO_tell_impl(fileio *self)
973
979
if (self -> fd < 0 )
974
980
return err_closed ();
975
981
976
- return portable_lseek (self , NULL , 1 );
982
+ return portable_lseek (self , NULL , 1 , false );
977
983
}
978
984
979
985
#ifdef HAVE_FTRUNCATE
@@ -1004,7 +1010,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
1004
1010
1005
1011
if (posobj == Py_None ) {
1006
1012
/* Get the current position. */
1007
- posobj = portable_lseek (self , NULL , 1 );
1013
+ posobj = portable_lseek (self , NULL , 1 , false );
1008
1014
if (posobj == NULL )
1009
1015
return NULL ;
1010
1016
}
0 commit comments