Issue #23668: Adds support for os.truncate and os.ftruncate on Windows · pythoncapi/cpython@fe0a41a · GitHub
Skip to content

Commit fe0a41a

Browse files
committed
Issue python#23668: Adds support for os.truncate and os.ftruncate on Windows
1 parent c7d979f commit fe0a41a

5 files changed

Lines changed: 53 additions & 63 deletions

File tree

Doc/library/io.rst

Lines changed: 5 additions & 2 deletions

Doc/library/os.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -805,8 +805,10 @@ as internal buffering of data.
805805
most *length* bytes in size. As of Python 3.3, this is equivalent to
806806
``os.truncate(fd, length)``.
807807

808-
Availability: Unix.
808+
Availability: Unix, Windows.
809809

810+
.. versionchanged:: 3.5
811+
Added support for Windows
810812

811813
.. function:: get_blocking(fd)
812814

@@ -2492,10 +2494,12 @@ features:
24922494

24932495
This function can support :ref:`specifying a file descriptor <path_fd>`.
24942496

2495-
Availability: Unix.
2497+
Availability: Unix, Windows.
24962498

24972499
.. versionadded:: 3.3
24982500

2501+
.. versionchanged:: 3.5
2502+
Added support for Windows
24992503

25002504
.. function:: unlink(path, *, dir_fd=None)
25012505

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ Library
286286

287287
- Issue #2052: Add charset parameter to HtmlDiff.make_file().
288288

289+
- Issue #23668: Support os.truncate and os.ftruncate on Windows.
290+
289291
- Issue #23138: Fixed parsing cookies with absent keys or values in cookiejar.
290292
Patch by Demian Brecht.
291293

Modules/_io/fileio.c

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -839,9 +839,7 @@ static PyObject *
839839
fileio_truncate(fileio *self, PyObject *args)
840840
{
841841
PyObject *posobj = NULL; /* the new size wanted by the user */
842-
#ifndef MS_WINDOWS
843842
Py_off_t pos;
844-
#endif
845843
int ret;
846844
int fd;
847845

@@ -864,52 +862,6 @@ fileio_truncate(fileio *self, PyObject *args)
864862
Py_INCREF(posobj);
865863
}
866864

867-
#ifdef MS_WINDOWS
868-
/* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
869-
so don't even try using it. */
870-
{
871-
PyObject *oldposobj, *tempposobj;
872-
HANDLE hFile;
873-
874-
/* we save the file pointer position */
875-
oldposobj = portable_lseek(fd, NULL, 1);
876-
if (oldposobj == NULL) {
877-
Py_DECREF(posobj);
878-
return NULL;
879-
}
880-
881-
/* we then move to the truncation position */
882-
tempposobj = portable_lseek(fd, posobj, 0);
883-
if (tempposobj == NULL) {
884-
Py_DECREF(oldposobj);
885-
Py_DECREF(posobj);
886-
return NULL;
887-
}
888-
Py_DECREF(tempposobj);
889-
890-
/* Truncate. Note that this may grow the file! */
891-
Py_BEGIN_ALLOW_THREADS
892-
errno = 0;
893-
hFile = (HANDLE)_get_osfhandle(fd);
894-
ret = hFile == (HANDLE)-1; /* testing for INVALID_HANDLE value */
895-
if (ret == 0) {
896-
ret = SetEndOfFile(hFile) == 0;
897-
if (ret)
898-
errno = EACCES;
899-
}
900-
Py_END_ALLOW_THREADS
901-
902-
/* we restore the file pointer position in any case */
903-
tempposobj = portable_lseek(fd, oldposobj, 0);
904-
Py_DECREF(oldposobj);
905-
if (tempposobj == NULL) {
906-
Py_DECREF(posobj);
907-
return NULL;
908-
}
909-
Py_DECREF(tempposobj);
910-
}
911-
#else
912-
913865
#if defined(HAVE_LARGEFILE_SUPPORT)
914866
pos = PyLong_AsLongLong(posobj);
915867
#else
@@ -922,11 +874,13 @@ fileio_truncate(fileio *self, PyObject *args)
922874

923875
Py_BEGIN_ALLOW_THREADS
924876
errno = 0;
877+
#ifdef MS_WINDOWS
878+
ret = _chsize_s(fd, pos);
879+
#else
925880
ret = ftruncate(fd, pos);
881+
#endif
926882
Py_END_ALLOW_THREADS
927883

928-
#endif /* !MS_WINDOWS */
929-
930884
if (ret != 0) {
931885
Py_DECREF(posobj);
932886
PyErr_SetFromErrno(PyExc_IOError);

Modules/posixmodule.c

Lines changed: 36 additions & 9 deletions

0 commit comments

Comments
 (0)