summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_io/fileio.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 922db3e..a09c39f7 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -73,6 +73,9 @@ _Py_IDENTIFIER(name);
#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type))
+/* Forward declarations */
+static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence);
+
int
_PyFileIO_closed(PyObject *self)
{
@@ -98,11 +101,6 @@ fileio_dealloc_warn(fileio *self, PyObject *source)
Py_RETURN_NONE;
}
-static PyObject *
-portable_lseek(int fd, PyObject *posobj, int whence);
-
-static PyObject *portable_lseek(int fd, PyObject *posobj, int whence);
-
/* Returns 0 on success, -1 with exception set on failure. */
static int
internal_close(fileio *self)
@@ -478,7 +476,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->fd, NULL, 2);
+ PyObject *pos = portable_lseek(self, NULL, 2);
if (pos == NULL)
goto error;
Py_DECREF(pos);
@@ -600,13 +598,14 @@ _io_FileIO_seekable_impl(fileio *self)
if (self->fd < 0)
return err_closed();
if (self->seekable < 0) {
- PyObject *pos = portable_lseek(self->fd, NULL, SEEK_CUR);
+ /* portable_lseek() sets the seekable attribute */
+ PyObject *pos = portable_lseek(self, NULL, SEEK_CUR);
+ assert(self->seekable >= 0);
if (pos == NULL) {
PyErr_Clear();
- self->seekable = 0;
- } else {
+ }
+ else {
Py_DECREF(pos);
- self->seekable = 1;
}
}
return PyBool_FromLong((long) self->seekable);
@@ -865,9 +864,10 @@ _io_FileIO_write_impl(fileio *self, Py_buffer *b)
/* Cribbed from posix_lseek() */
static PyObject *
-portable_lseek(int fd, PyObject *posobj, int whence)
+portable_lseek(fileio *self, PyObject *posobj, int whence)
{
Py_off_t pos, res;
+ int fd = self->fd;
#ifdef SEEK_SET
/* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
@@ -884,8 +884,9 @@ portable_lseek(int fd, PyObject *posobj, int whence)
}
#endif /* SEEK_SET */
- if (posobj == NULL)
+ if (posobj == NULL) {
pos = 0;
+ }
else {
if(PyFloat_Check(posobj)) {
PyErr_SetString(PyExc_TypeError, "an integer is required");
@@ -909,6 +910,11 @@ portable_lseek(int fd, PyObject *posobj, int whence)
#endif
_Py_END_SUPPRESS_IPH
Py_END_ALLOW_THREADS
+
+ if (self->seekable < 0) {
+ self->seekable = (res >= 0);
+ }
+
if (res < 0)
return PyErr_SetFromErrno(PyExc_OSError);
@@ -943,7 +949,7 @@ _io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence)
if (self->fd < 0)
return err_closed();
- return portable_lseek(self->fd, pos, whence);
+ return portable_lseek(self, pos, whence);
}
/*[clinic input]
@@ -961,7 +967,7 @@ _io_FileIO_tell_impl(fileio *self)
if (self->fd < 0)
return err_closed();
- return portable_lseek(self->fd, NULL, 1);
+ return portable_lseek(self, NULL, 1);
}
#ifdef HAVE_FTRUNCATE
@@ -992,7 +998,7 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj)
if (posobj == Py_None || posobj == NULL) {
/* Get the current position. */
- posobj = portable_lseek(fd, NULL, 1);
+ posobj = portable_lseek(self, NULL, 1);
if (posobj == NULL)
return NULL;
}