diff -r 889023da7454 Doc/library/io.rst --- a/Doc/library/io.rst Mon Mar 16 08:31:38 2015 +0200 +++ b/Doc/library/io.rst Mon Mar 16 10:09:52 2015 +0200 @@ -339,8 +339,8 @@ I/O Base Classes if *size* is not specified). The current stream position isn't changed. This resizing can extend or reduce the current file size. In case of extension, the contents of the new file area depend on the platform - (on most systems, additional bytes are zero-filled, on Windows they're - undetermined). The new file size is returned. + (on most systems, additional bytes are zero-filled). The new file size + is returned. .. method:: writable() diff -r 889023da7454 Doc/library/os.rst --- a/Doc/library/os.rst Mon Mar 16 08:31:38 2015 +0200 +++ b/Doc/library/os.rst Mon Mar 16 10:09:52 2015 +0200 @@ -805,8 +805,10 @@ as internal buffering of data. most *length* bytes in size. As of Python 3.3, this is equivalent to ``os.truncate(fd, length)``. - Availability: Unix. - + Availability: Unix, Windows. + + .. versionchanged:: 3.5 + Added support for Windows .. function:: get_blocking(fd) @@ -2477,10 +2479,12 @@ features: This function can support :ref:`specifying a file descriptor `. - Availability: Unix. + Availability: Unix, Windows. .. versionadded:: 3.3 + .. versionchanged:: 3.5 + Added support for Windows .. function:: unlink(path, *, dir_fd=None) diff -r 889023da7454 Misc/NEWS --- a/Misc/NEWS Mon Mar 16 08:31:38 2015 +0200 +++ b/Misc/NEWS Mon Mar 16 10:09:52 2015 +0200 @@ -18,6 +18,8 @@ Core and Builtins Library ------- +- Issue #23668: Support os.truncate and os.ftruncate on Windows. + - Issue #23631: Fix traceback.format_list when a traceback has been mutated. - Issue #23568: Add rdivmod support to MagicMock() objects. diff -r 889023da7454 Modules/_io/fileio.c --- a/Modules/_io/fileio.c Mon Mar 16 08:31:38 2015 +0200 +++ b/Modules/_io/fileio.c Mon Mar 16 10:09:52 2015 +0200 @@ -28,13 +28,6 @@ * - autoconfify header file inclusion */ -#ifdef MS_WINDOWS -/* can simulate truncate with Win32 API functions; see file_truncate */ -#define HAVE_FTRUNCATE -#define WIN32_LEAN_AND_MEAN -#include -#endif - #if BUFSIZ < (8*1024) #define SMALLCHUNK (8*1024) #elif (BUFSIZ >= (2 << 25)) @@ -965,9 +958,7 @@ static PyObject * fileio_truncate(fileio *self, PyObject *args) { PyObject *posobj = NULL; /* the new size wanted by the user */ -#ifndef MS_WINDOWS Py_off_t pos; -#endif int ret; int fd; @@ -990,52 +981,6 @@ fileio_truncate(fileio *self, PyObject * Py_INCREF(posobj); } -#ifdef MS_WINDOWS - /* MS _chsize doesn't work if newsize doesn't fit in 32 bits, - so don't even try using it. */ - { - PyObject *oldposobj, *tempposobj; - HANDLE hFile; - - /* we save the file pointer position */ - oldposobj = portable_lseek(fd, NULL, 1); - if (oldposobj == NULL) { - Py_DECREF(posobj); - return NULL; - } - - /* we then move to the truncation position */ - tempposobj = portable_lseek(fd, posobj, 0); - if (tempposobj == NULL) { - Py_DECREF(oldposobj); - Py_DECREF(posobj); - return NULL; - } - Py_DECREF(tempposobj); - - /* Truncate. Note that this may grow the file! */ - Py_BEGIN_ALLOW_THREADS - errno = 0; - hFile = (HANDLE)_get_osfhandle(fd); - ret = hFile == (HANDLE)-1; /* testing for INVALID_HANDLE value */ - if (ret == 0) { - ret = SetEndOfFile(hFile) == 0; - if (ret) - errno = EACCES; - } - Py_END_ALLOW_THREADS - - /* we restore the file pointer position in any case */ - tempposobj = portable_lseek(fd, oldposobj, 0); - Py_DECREF(oldposobj); - if (tempposobj == NULL) { - Py_DECREF(posobj); - return NULL; - } - Py_DECREF(tempposobj); - } -#else - #if defined(HAVE_LARGEFILE_SUPPORT) pos = PyLong_AsLongLong(posobj); #else @@ -1048,11 +993,13 @@ fileio_truncate(fileio *self, PyObject * Py_BEGIN_ALLOW_THREADS errno = 0; +#ifdef MS_WINDOWS + ret = _chsize_s(fd, pos); +#else ret = ftruncate(fd, pos); +#endif Py_END_ALLOW_THREADS -#endif /* !MS_WINDOWS */ - if (ret != 0) { Py_DECREF(posobj); PyErr_SetFromErrno(PyExc_IOError); diff -r 889023da7454 Modules/posixmodule.c --- a/Modules/posixmodule.c Mon Mar 16 08:31:38 2015 +0200 +++ b/Modules/posixmodule.c Mon Mar 16 10:09:52 2015 +0200 @@ -12561,7 +12561,11 @@ os_ftruncate_impl(PyModuleDef *module, i do { Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + result = _chsize_s(fd, length); +#else result = ftruncate(fd, length); +#endif Py_END_ALLOW_THREADS } while (result != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); @@ -12625,14 +12629,29 @@ os_truncate_impl(PyModuleDef *module, pa /*[clinic end generated code: output=6bd76262d2e027c6 input=77229cf0b50a9b77]*/ { int result; +#ifdef MS_WINDOWS + int fd; +#endif + + if (path->fd != -1) + return os_ftruncate_impl(module, path->fd, length); Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FTRUNCATE - if (path->fd != -1) - result = ftruncate(path->fd, length); - else -#endif - result = truncate(path->narrow, length); +#ifdef MS_WINDOWS + if (path->wide) + fd = _wopen(path->wide, _O_WRONLY | _O_BINARY); + else + fd = _open(path->narrow, _O_WRONLY | _O_BINARY); + if (fd < 0) + result = -1; + else { + if (_chsize_s(fd, length)) + result = -1; + close(fd); + } +#else + result = truncate(path->narrow, length); +#endif Py_END_ALLOW_THREADS if (result < 0) return path_error(path); diff -r 889023da7454 PC/pyconfig.h --- a/PC/pyconfig.h Mon Mar 16 08:31:38 2015 +0200 +++ b/PC/pyconfig.h Mon Mar 16 10:09:52 2015 +0200 @@ -554,6 +554,9 @@ Py_NO_ENABLE_SHARED to find out. Also s #define HAVE_FTIME #endif +/* Define if you have ftruncate (_chsize_s). */ +#define HAVE_FTRUNCATE + /* Define if you have getpeername. */ #define HAVE_GETPEERNAME @@ -613,6 +616,9 @@ Py_NO_ENABLE_SHARED to find out. Also s /* Define if you have times. */ /* #undef HAVE_TIMES */ +/* Define if you have truncate (_chsize_s). */ +#define HAVE_TRUNCATE + /* Define if you have uname. */ /* #undef HAVE_UNAME */