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.
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 @@
 		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;