diff options
author | Benjamin Peterson <benjamin@python.org> | 2019-11-12 22:51:34 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-12 22:51:34 (GMT) |
commit | 74fa9f723f700a342e582b5ad4b51a2c4801cd1c (patch) | |
tree | 0d34e5bbb923f72121243ba0c425a39c08d4d411 /Modules/_io | |
parent | d593881505c1f4acfd17f41312b27cc898451816 (diff) | |
download | cpython-74fa9f723f700a342e582b5ad4b51a2c4801cd1c.zip cpython-74fa9f723f700a342e582b5ad4b51a2c4801cd1c.tar.gz cpython-74fa9f723f700a342e582b5ad4b51a2c4801cd1c.tar.bz2 |
closes bpo-27805: Ignore ESPIPE in initializing seek of append-mode files. (GH-17112)
This change, which follows the behavior of C stdio's fdopen and Python 2's file object, allows pipes to be opened in append mode.
Diffstat (limited to 'Modules/_io')
-rw-r--r-- | Modules/_io/fileio.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index fd32b19..1855b83 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -4,6 +4,7 @@ #include "Python.h" #include "pycore_object.h" #include "structmember.h" +#include <stdbool.h> #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif @@ -75,7 +76,7 @@ _Py_IDENTIFIER(name); #define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) /* Forward declarations */ -static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence); +static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); int _PyFileIO_closed(PyObject *self) @@ -480,7 +481,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, /* For consistent behaviour, we explicitly seek to the end of file (otherwise, it might be done only on the first write()). */ - PyObject *pos = portable_lseek(self, NULL, 2); + PyObject *pos = portable_lseek(self, NULL, 2, true); if (pos == NULL) goto error; Py_DECREF(pos); @@ -603,7 +604,7 @@ _io_FileIO_seekable_impl(fileio *self) return err_closed(); if (self->seekable < 0) { /* portable_lseek() sets the seekable attribute */ - PyObject *pos = portable_lseek(self, NULL, SEEK_CUR); + PyObject *pos = portable_lseek(self, NULL, SEEK_CUR, false); assert(self->seekable >= 0); if (pos == NULL) { PyErr_Clear(); @@ -870,7 +871,7 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b) /* Cribbed from posix_lseek() */ static PyObject * -portable_lseek(fileio *self, PyObject *posobj, int whence) +portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error) { Py_off_t pos, res; int fd = self->fd; @@ -921,8 +922,13 @@ portable_lseek(fileio *self, PyObject *posobj, int whence) self->seekable = (res >= 0); } - if (res < 0) - return PyErr_SetFromErrno(PyExc_OSError); + if (res < 0) { + if (suppress_pipe_error && errno == ESPIPE) { + res = 0; + } else { + return PyErr_SetFromErrno(PyExc_OSError); + } + } #if defined(HAVE_LARGEFILE_SUPPORT) return PyLong_FromLongLong(res); @@ -955,7 +961,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) if (self->fd < 0) return err_closed(); - return portable_lseek(self, pos, whence); + return portable_lseek(self, pos, whence, false); } /*[clinic input] @@ -973,7 +979,7 @@ _io_FileIO_tell_impl(fileio *self) if (self->fd < 0) return err_closed(); - return portable_lseek(self, NULL, 1); + return portable_lseek(self, NULL, 1, false); } #ifdef HAVE_FTRUNCATE @@ -1004,7 +1010,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) if (posobj == Py_None) { /* Get the current position. */ - posobj = portable_lseek(self, NULL, 1); + posobj = portable_lseek(self, NULL, 1, false); if (posobj == NULL) return NULL; } |