summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-03-12 03:04:44 (GMT)
committerTim Peters <tim.peters@gmail.com>2002-03-12 03:04:44 (GMT)
commit8f01b680c85853948591c28ceae356760e7c7c33 (patch)
tree5f5010a50ee3f6bacdb34076a5af115fa425b94b /Objects
parent9d142adfce027096a5c80dcaf7193b510cf7f984 (diff)
downloadcpython-8f01b680c85853948591c28ceae356760e7c7c33.zip
cpython-8f01b680c85853948591c28ceae356760e7c7c33.tar.gz
cpython-8f01b680c85853948591c28ceae356760e7c7c33.tar.bz2
Change Windows file.truncate() to (a) restore the original file position,
and (b) stop trying to prevent file growth. Beef up the file.truncate() docs. Change test_largefile.py to stop assuming that f.truncate() moves the file pointer to the truncation point, and to verify instead that it leaves the file position alone. Remove the test for what happens when a specified size exceeds the original file size (it's ill-defined, according to the Single Unix Spec).
Diffstat (limited to 'Objects')
-rw-r--r--Objects/fileobject.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index f2f5dcf..7bcc82a 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -415,46 +415,59 @@ file_truncate(PyFileObject *f, PyObject *args)
#ifdef MS_WIN32
/* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
- so don't even try using it. truncate() should never grow the
- file, but MS SetEndOfFile will grow a file, so we need to
- compare the specified newsize to the actual size. Some
- optimization could be done here when newsizeobj is NULL. */
+ so don't even try using it. */
{
- Py_off_t currentEOF; /* actual size */
+ Py_off_t current; /* current file position */
HANDLE hFile;
int error;
- /* First move to EOF, and set currentEOF to the size. */
- errno = 0;
- if (_portable_fseek(f->f_fp, 0, SEEK_END) != 0)
- goto onioerror;
- errno = 0;
- currentEOF = _portable_ftell(f->f_fp);
- if (currentEOF == -1)
- goto onioerror;
-
- if (newsize > currentEOF)
- newsize = currentEOF; /* never grow the file */
-
- /* Move to newsize, and truncate the file there. */
- if (newsize != currentEOF) {
+ /* current <- current file postion. */
+ if (newsizeobj == NULL)
+ current = newsize;
+ else {
+ Py_BEGIN_ALLOW_THREADS
errno = 0;
- if (_portable_fseek(f->f_fp, newsize, SEEK_SET) != 0)
+ current = _portable_ftell(f->f_fp);
+ Py_END_ALLOW_THREADS
+ if (current == -1)
goto onioerror;
+ }
+
+ /* Move to newsize. */
+ if (current != newsize) {
Py_BEGIN_ALLOW_THREADS
errno = 0;
- hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
- error = hFile == (HANDLE)-1;
- if (!error) {
- error = SetEndOfFile(hFile) == 0;
- if (error)
- errno = EACCES;
- }
+ error = _portable_fseek(f->f_fp, newsize, SEEK_SET)
+ != 0;
Py_END_ALLOW_THREADS
if (error)
goto onioerror;
}
+ /* Truncate. Note that this may grow the file! */
+ Py_BEGIN_ALLOW_THREADS
+ errno = 0;
+ hFile = (HANDLE)_get_osfhandle(fileno(f->f_fp));
+ error = hFile == (HANDLE)-1;
+ if (!error) {
+ error = SetEndOfFile(hFile) == 0;
+ if (error)
+ errno = EACCES;
+ }
+ Py_END_ALLOW_THREADS
+ if (error)
+ goto onioerror;
+
+ /* Restore original file position. */
+ if (current != newsize) {
+ Py_BEGIN_ALLOW_THREADS
+ errno = 0;
+ error = _portable_fseek(f->f_fp, current, SEEK_SET)
+ != 0;
+ Py_END_ALLOW_THREADS
+ if (error)
+ goto onioerror;
+ }
}
#else
Py_BEGIN_ALLOW_THREADS