diff options
author | Tim Peters <tim.peters@gmail.com> | 2002-03-12 03:04:44 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2002-03-12 03:04:44 (GMT) |
commit | 8f01b680c85853948591c28ceae356760e7c7c33 (patch) | |
tree | 5f5010a50ee3f6bacdb34076a5af115fa425b94b /Objects/fileobject.c | |
parent | 9d142adfce027096a5c80dcaf7193b510cf7f984 (diff) | |
download | cpython-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/fileobject.c')
-rw-r--r-- | Objects/fileobject.c | 67 |
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 |