SetEndOfFile fix
Rein Klazes
rklazes at xs4all.nl
Sun Jan 20 13:13:53 CST 2002
hi,
This fixes office 97 MSword error (disk full or write protected) when
saving files on a vfat partition. MSword calls SetEndOfFile() which
uses ftruncate() that, in Linux, cannot grow files in this filesystem.
BTW. A google search shows that the ftruncate problem has been
mentioned at least 3 times on c.e.m.w. in the last 6 months Since
nobody entered a fix, I could be overlooking something...
Changelog
server : file.c
On the server side of SetEndOfFile, use an alternate method
to grow a file when ftruncate refuses to do so.
(eg with vfat filesystem under Linux)
Rein.
--
Rein Klazes
rklazes at xs4all.nl
-------------- next part --------------
--- wine/server/file.c Tue Jan 15 13:24:26 2002
+++ mywine/server/file.c Sun Jan 20 19:33:08 2002
@@ -456,6 +456,32 @@
return 1;
}
+/* wrapper around ftruncate:
+ * ftruncate may fail to grow the size of a file with some OS and filesystem
+ * combinations. Linux and vfat/fat is one example. If this is the case do
+ * a write to grow the file to the desired length.
+ */
+static int _ftruncate ( int fd, off_t length)
+{
+ struct stat st;
+ int ret, ret_errno;
+ char buf[1]={'\0'};
+ /* first try with ftruncate */
+ ret = ftruncate( fd, length);
+ if(ret != -1) return ret;
+ ret_errno = errno;
+ if( fstat( fd, &st ) == -1) return -1;
+ if( st.st_size == length ) return 0;
+ errno = ret_errno;
+ /* ftruncate() shouldn't fail when requested to shrink the file */
+ if( st.st_size > length ) return -1;
+ /* file pointer is at the requested size */
+ if( lseek( fd, -1, SEEK_CUR) == -1) return -1;
+ /* write one byte, filepointer is back at the orig. position. */
+ if( write( fd, &buf, 1) == -1) return -1;
+ return 0;
+}
+
static int truncate_file( handle_t handle )
{
struct file *file;
@@ -464,7 +490,7 @@
if (!(file = get_file_obj( current->process, handle, GENERIC_WRITE )))
return 0;
if (((result = lseek( file->obj.fd, 0, SEEK_CUR )) == -1) ||
- (ftruncate( file->obj.fd, result ) == -1))
+ (_ftruncate( file->obj.fd, result ) == -1))
{
file_set_error();
release_object( file );
More information about the wine-patches
mailing list