This is the mail archive of the cygwin-patches@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch]: Truncate


At 05:55 PM 8/22/2004 +0200, you wrote:
>Hi Pierre,
>
>Looks good to me.  But wouldn't it be better to fill in the zeros only
>if SetEndOfFile succeeded?  That would avoid a lengthy write operation
>if the application was, say, too optimistic about the space left on disk.

In that case we can't reuse the code already present in ::write
because when ::write calls GetFileSize it will get the length
already updated by SetEndOfFile.

The way ::write is written, it will restore the FilePointer at
the beginning of the 0 filled region if the disk gets full. But
because 0's may have been written, the EOF may have moved and the
file may have been extended.
When ftruncate calls SetEndOfFile, it will succeed and truncate
the file back to its original position. That's OK, but it should
then return an error. See updated patch below. 

As an aside, should ::write also call SetEndOfFile to truncate the
0's it has written? What do Cygwin on NT and Linux do when lseek
has been optimistic (and sparse files are off)?

Pierre

2004-08-23  Pierre Humblet <pierre.humblet@ieee.org>
 
 	* syscalls.cc (ftruncate64): On 9x, call write with a zero length
 	to zero fill when the file is extended.


Index: syscalls.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v
retrieving revision 1.342
diff -u -p -r1.342 syscalls.cc
--- syscalls.cc 3 Aug 2004 14:37:26 -0000       1.342
+++ syscalls.cc 22 Aug 2004 21:00:49 -0000
@@ -1675,7 +1675,7 @@ setmode (int fd, int mode)
 extern "C" int
 ftruncate64 (int fd, _off64_t length)
 {
-  int res = -1;
+  int res = -1, res_bug = 0;
 
   if (length < 0)
     set_errno (EINVAL);
@@ -1692,10 +1692,15 @@ ftruncate64 (int fd, _off64_t length)
              _off64_t prev_loc = cfd->lseek (0, SEEK_CUR);
 
              cfd->lseek (length, SEEK_SET);
+             /* Fill the space with 0, if needed */
+             if (wincap.has_lseek_bug ())
+               res_bug = cfd->write (&res, 0);
+             /* In the lseek_bug case, this may restore the file to
+                its initial length */
              if (!SetEndOfFile (h))
                __seterrno ();
              else
-               res = 0;
+               res = res_bug;
 
              /* restore original file pointer location */
              cfd->lseek (prev_loc, SEEK_SET);



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]