[Python-3000-checkins] r56311 - python/branches/py3k-struni/Modules/_fileio.c

thomas.heller python-3000-checkins at python.org
Thu Jul 12 13:21:37 CEST 2007


Author: thomas.heller
Date: Thu Jul 12 13:21:36 2007
New Revision: 56311

Modified:
   python/branches/py3k-struni/Modules/_fileio.c
Log:
Second part of sf# 1752225: On windows, emulate ftruncate with Win32
api functions. Code from fileobject.c, patch by Amaury Forgeot d'Arc.


Modified: python/branches/py3k-struni/Modules/_fileio.c
==============================================================================
--- python/branches/py3k-struni/Modules/_fileio.c	(original)
+++ python/branches/py3k-struni/Modules/_fileio.c	Thu Jul 12 13:21:36 2007
@@ -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 @@
 		else
 			self->seekable = 1;
 	}
-	return PyInt_FromLong((long) self->seekable);
+	return PyBool_FromLong((long) self->seekable);
 }
 
 static PyObject *
@@ -590,6 +590,7 @@
 {
 	PyObject *posobj = NULL;
 	Py_off_t pos;
+	int ret;
 	int fd;
 
 	fd = self->fd;
@@ -621,14 +622,46 @@
 		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;


More information about the Python-3000-checkins mailing list