From 57233cb3f9d59233711e63034cc1e84360f0da15 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 26 Oct 2007 17:19:33 +0000 Subject: [PATCH] Patch 1330 by Christian Heimes (with some TLC applied by myself). Move most of the messiness with truncate() on Windows into _fileio.c. Still keep the flush() call in io.py though. --- Lib/io.py | 18 ++++-------------- Modules/_fileio.c | 25 ++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/Lib/io.py b/Lib/io.py index b201cb2bb2b..c2d803ccfed 100644 --- a/Lib/io.py +++ b/Lib/io.py @@ -597,24 +597,14 @@ class _BufferedIOMixin(BufferedIOBase): return self.raw.tell() def truncate(self, pos=None): - # On Windows, the truncate operation changes the current position - # to the end of the file, which may leave us with desynchronized - # buffers. - # Since we promise that truncate() won't change the current position, - # the easiest thing is to capture current pos now and seek back to - # it at the end. - - initialpos = self.tell() - if pos is None: - pos = initialpos - # Flush the stream. We're mixing buffered I/O with lower-level I/O, # and a flush may be necessary to synch both views of the current # file state. self.flush() - newpos = self.raw.truncate(pos) - self.seek(initialpos) - return newpos + + if pos is None: + pos = self.tell() + return self.raw.truncate(pos) ### Flush and close ### diff --git a/Modules/_fileio.c b/Modules/_fileio.c index 7757af97892..bc707e85968 100644 --- a/Modules/_fileio.c +++ b/Modules/_fileio.c @@ -628,14 +628,21 @@ fileio_truncate(PyFileIOObject *self, PyObject *args) so don't even try using it. */ { HANDLE hFile; - PyObject *pos2; + PyObject *pos2, *oldposobj; + + /* store the current position */ + oldposobj = portable_lseek(self->fd, NULL, 1); + if (oldposobj == NULL) { + Py_DECREF(posobj); + return NULL; + } /* Have to move current pos to desired endpoint on Windows. */ errno = 0; pos2 = portable_lseek(fd, posobj, SEEK_SET); - if (pos2 == NULL) - { + if (pos2 == NULL) { Py_DECREF(posobj); + Py_DECREF(oldposobj); return NULL; } Py_DECREF(pos2); @@ -651,6 +658,18 @@ fileio_truncate(PyFileIOObject *self, PyObject *args) errno = EACCES; } Py_END_ALLOW_THREADS + + if (ret == 0) { + /* Move to the previous position in the file */ + pos2 = portable_lseek(fd, oldposobj, SEEK_SET); + if (pos2 == NULL) { + Py_DECREF(posobj); + Py_DECREF(oldposobj); + return NULL; + } + } + Py_DECREF(pos2); + Py_DECREF(oldposobj); } #else Py_BEGIN_ALLOW_THREADS