]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Second part of sf# 1752225: On windows, emulate ftruncate with Win32
authorThomas Heller <theller@ctypes.org>
Thu, 12 Jul 2007 11:21:36 +0000 (11:21 +0000)
committerThomas Heller <theller@ctypes.org>
Thu, 12 Jul 2007 11:21:36 +0000 (11:21 +0000)
api functions. Code from fileobject.c, patch by Amaury Forgeot d'Arc.

This patch also changes:

The return value of the native ftruncate function is checked for '!=
0' instead of '< 0' as before.

fileio_seekable returns bool now instead of an int.

Modules/_fileio.c

index a2c0221dc24b516cc238cb6935bcbc6fa0ede8de..f64708e5e3a86ec7f856839f1fbec42bfcd103ac 100644 (file)
@@ -22,7 +22,7 @@
 
 #ifdef MS_WINDOWS
 /* can simulate truncate with Win32 API functions; see file_truncate */
-/* #define HAVE_FTRUNCATE */
+#define HAVE_FTRUNCATE
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #endif
@@ -337,7 +337,7 @@ fileio_seekable(PyFileIOObject *self)
                else
                        self->seekable = 1;
        }
-       return PyInt_FromLong((long) self->seekable);
+       return PyBool_FromLong((long) self->seekable);
 }
 
 static PyObject *
@@ -590,6 +590,7 @@ fileio_truncate(PyFileIOObject *self, PyObject *args)
 {
        PyObject *posobj = NULL;
        Py_off_t pos;
+       int ret;
        int fd;
 
        fd = self->fd;
@@ -621,14 +622,46 @@ fileio_truncate(PyFileIOObject *self, PyObject *args)
                return NULL;
        }
 
+#ifdef MS_WINDOWS
+       /* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
+          so don't even try using it. */
+       {
+               HANDLE hFile;
+               PyObject *pos2;
+
+               /* Have to move current pos to desired endpoint on Windows. */
+               errno = 0;
+               pos2 = portable_lseek(fd, posobj, SEEK_SET);
+               if (pos2 == NULL)
+               {
+                       Py_DECREF(posobj);
+                       return NULL;
+               }
+               Py_DECREF(pos2);
+
+               /* Truncate.  Note that this may grow the file! */
+               Py_BEGIN_ALLOW_THREADS
+               errno = 0;
+               hFile = (HANDLE)_get_osfhandle(fd);
+               ret = hFile == (HANDLE)-1;
+               if (ret == 0) {
+                       ret = SetEndOfFile(hFile) == 0;
+                       if (ret)
+                               errno = EACCES;
+               }
+               Py_END_ALLOW_THREADS
+       }
+#else
        Py_BEGIN_ALLOW_THREADS
        errno = 0;
-       pos = ftruncate(fd, pos);
+       ret = ftruncate(fd, pos);
        Py_END_ALLOW_THREADS
+#endif /* !MS_WINDOWS */
 
-       if (pos < 0) {
+       if (ret != 0) {
                Py_DECREF(posobj);
                PyErr_SetFromErrno(PyExc_IOError);
+               return NULL;
        }
 
        return posobj;