diff options
author | Steve Dower <steve.dower@microsoft.com> | 2015-03-21 02:50:46 (GMT) |
---|---|---|
committer | Steve Dower <steve.dower@microsoft.com> | 2015-03-21 02:50:46 (GMT) |
commit | fe0a41aae425c61364b79c18ca8321dffed3ac40 (patch) | |
tree | bf19237ec3d8058d4b22bbc02177435ac1a1ce43 /Modules | |
parent | c7d979f0221b4426fb2160f0960a61c1e7bc59df (diff) | |
download | cpython-fe0a41aae425c61364b79c18ca8321dffed3ac40.zip cpython-fe0a41aae425c61364b79c18ca8321dffed3ac40.tar.gz cpython-fe0a41aae425c61364b79c18ca8321dffed3ac40.tar.bz2 |
Issue #23668: Adds support for os.truncate and os.ftruncate on Windows
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_io/fileio.c | 54 | ||||
-rw-r--r-- | Modules/posixmodule.c | 45 |
2 files changed, 40 insertions, 59 deletions
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 5108fc7..bb3e9b9 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -839,9 +839,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; @@ -864,52 +862,6 @@ fileio_truncate(fileio *self, PyObject *args) 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 @@ -922,11 +874,13 @@ fileio_truncate(fileio *self, PyObject *args) 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 --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7da1ab0..724acc6 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -2315,6 +2315,10 @@ FTRUNCATE #endif /*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/ +#ifdef MS_WINDOWS + #undef PATH_HAVE_FTRUNCATE + #define PATH_HAVE_FTRUNCATE 1 +#endif /*[python input] @@ -8753,7 +8757,7 @@ os_makedev_impl(PyModuleDef *module, int major, int minor) #endif /* HAVE_DEVICE_MACROS */ -#ifdef HAVE_FTRUNCATE +#if defined HAVE_FTRUNCATE || defined MS_WINDOWS /*[clinic input] os.ftruncate @@ -8771,9 +8775,16 @@ os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length) int result; int async_err = 0; + if (!_PyVerify_fd(fd)) + return posix_error(); + 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())); @@ -8781,10 +8792,10 @@ os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length) return (!async_err) ? posix_error() : NULL; Py_RETURN_NONE; } -#endif /* HAVE_FTRUNCATE */ +#endif /* HAVE_FTRUNCATE || MS_WINDOWS */ -#ifdef HAVE_TRUNCATE +#if defined HAVE_TRUNCATE || defined MS_WINDOWS /*[clinic input] os.truncate path: path_t(allow_fd='PATH_HAVE_FTRUNCATE') @@ -8801,21 +8812,37 @@ os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length) /*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/ { int result; +#ifdef MS_WINDOWS + int fd; +#endif - Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FTRUNCATE if (path->fd != -1) - result = ftruncate(path->fd, length); + return os_ftruncate_impl(module, path->fd, length); + + Py_BEGIN_ALLOW_THREADS +#ifdef MS_WINDOWS + if (path->wide) + fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT); else + fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT); + if (fd < 0) + result = -1; + else { + result = _chsize_s(fd, length); + close(fd); + if (result < 0) + errno = result; + } +#else + result = truncate(path->narrow, length); #endif - result = truncate(path->narrow, length); Py_END_ALLOW_THREADS if (result < 0) return path_error(path); Py_RETURN_NONE; } -#endif /* HAVE_TRUNCATE */ +#endif /* HAVE_TRUNCATE || MS_WINDOWS */ /* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() @@ -12771,7 +12798,7 @@ static char *have_functions[] = { "HAVE_FSTATVFS", #endif -#ifdef HAVE_FTRUNCATE +#if defined HAVE_FTRUNCATE || defined MS_WINDOWS "HAVE_FTRUNCATE", #endif |