]> granicus.if.org Git - python/commitdiff
Patch 1330 by Christian Heimes (with some TLC applied by myself).
authorGuido van Rossum <guido@python.org>
Fri, 26 Oct 2007 17:19:33 +0000 (17:19 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 26 Oct 2007 17:19:33 +0000 (17:19 +0000)
Move most of the messiness with truncate() on Windows into _fileio.c.
Still keep the flush() call in io.py though.

Lib/io.py
Modules/_fileio.c

index b201cb2bb2b6645ad8eeccdf63e9e9368258022c..c2d803ccfedee3cfa897b22b027fb569b1e7e1c3 100644 (file)
--- 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 ###
 
index 7757af97892f67e3ed1ac521b0b69008a0af1dfb..bc707e85968c23ab326767f961176d1c91a6b000 100644 (file)
@@ -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