summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@microsoft.com>2015-03-21 02:50:46 (GMT)
committerSteve Dower <steve.dower@microsoft.com>2015-03-21 02:50:46 (GMT)
commitfe0a41aae425c61364b79c18ca8321dffed3ac40 (patch)
treebf19237ec3d8058d4b22bbc02177435ac1a1ce43 /Modules
parentc7d979f0221b4426fb2160f0960a61c1e7bc59df (diff)
downloadcpython-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.c54
-rw-r--r--Modules/posixmodule.c45
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