summaryrefslogtreecommitdiffstats
path: root/Modules/_fileio.c
diff options
context:
space:
mode:
authorThomas Heller <theller@ctypes.org>2007-07-12 11:21:36 (GMT)
committerThomas Heller <theller@ctypes.org>2007-07-12 11:21:36 (GMT)
commitfdeee3a6cdadee0e32dcec9783b1aaa5e231bdf6 (patch)
tree21d39a6c3faf3c285cf9f80cc7afe4c29a1bebe6 /Modules/_fileio.c
parentaf2be262af836eb1d8cb1a555d1640d5e0bfef86 (diff)
downloadcpython-fdeee3a6cdadee0e32dcec9783b1aaa5e231bdf6.zip
cpython-fdeee3a6cdadee0e32dcec9783b1aaa5e231bdf6.tar.gz
cpython-fdeee3a6cdadee0e32dcec9783b1aaa5e231bdf6.tar.bz2
Second part of sf# 1752225: On windows, emulate ftruncate with Win32
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.
Diffstat (limited to 'Modules/_fileio.c')
-rw-r--r--Modules/_fileio.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/Modules/_fileio.c b/Modules/_fileio.c
index a2c0221..f64708e 100644
--- a/Modules/_fileio.c
+++ b/Modules/_fileio.c
@@ -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;