[Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.145,2.146

Tim Peters tim_one@users.sourceforge.net
Mon, 11 Mar 2002 19:04:46 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv17165/python/Objects

Modified Files:
	fileobject.c 
Log Message:
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).


Index: fileobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v
retrieving revision 2.145
retrieving revision 2.146
diff -C2 -d -r2.145 -r2.146
*** fileobject.c	11 Mar 2002 00:24:00 -0000	2.145
--- fileobject.c	12 Mar 2002 03:04:44 -0000	2.146
***************
*** 416,454 ****
  #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. */
  	{
! 		Py_off_t currentEOF;	/* actual size */
  		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) {
  			errno = 0;
! 			if (_portable_fseek(f->f_fp, newsize, SEEK_SET) != 0)
  				goto onioerror;
  			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)
--- 416,443 ----
  #ifdef MS_WIN32
  	/* MS _chsize doesn't work if newsize doesn't fit in 32 bits,
! 	   so don't even try using it. */
  	{
! 		Py_off_t current;	/* current file position */
  		HANDLE hFile;
  		int error;
  
! 		/* current <- current file postion. */
! 		if (newsizeobj == NULL)
! 			current = newsize;
! 		else {
! 			Py_BEGIN_ALLOW_THREADS
  			errno = 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;
! 			error = _portable_fseek(f->f_fp, newsize, SEEK_SET)
! 				!= 0;
  			Py_END_ALLOW_THREADS
  			if (error)
***************
*** 456,459 ****
--- 445,472 ----
  		}
  
+ 		/* 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