diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-02-02 22:42:06 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-02-02 22:42:06 +0000 |
commit | 3fd68a6a044e674d434353d5631aba2743e0bf89 (patch) | |
tree | 9f507acf3ea9c2c357cf233519a2d178dbf3b929 /winsup/cygwin/fhandler_disk_file.cc | |
parent | 7823d9bb14798143e9791303186c7129336356dd (diff) | |
download | cygnal-3fd68a6a044e674d434353d5631aba2743e0bf89.tar.gz cygnal-3fd68a6a044e674d434353d5631aba2743e0bf89.tar.bz2 cygnal-3fd68a6a044e674d434353d5631aba2743e0bf89.zip |
* fhandler.h (fhandler_base::ftruncate): Define new virtual method.
(fhandler_disk_file::ftruncate): Ditto.
* fhandler.cc (fhandler_base::ftruncate): New method.
* fhandler_disk_file.cc (fhandler_disk_file::ftruncate): Ditto.
* syscalls.cc (ftruncate64): Move functionality into fhandlers.
Call fhandler method from here.
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index d8e0c16f7..96d3c0ecf 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -29,6 +29,7 @@ details. */ #include "ntdll.h" #include <assert.h> #include <ctype.h> +#include <winioctl.h> #define _COMPILING_NEWLIB #include <dirent.h> @@ -589,6 +590,53 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp) return res; } +int +fhandler_disk_file::ftruncate (_off64_t length) +{ + int res = -1, res_bug = 0; + + if (length < 0 || !get_output_handle ()) + set_errno (EINVAL); + else if (pc.isdir ()) + set_errno (EISDIR); + else if (!(get_access () & GENERIC_WRITE)) + set_errno (EBADF); + else + { + _off64_t prev_loc = lseek (0, SEEK_CUR); + if (lseek (length, SEEK_SET) > 0) + { + if (get_fs_flags (FILE_SUPPORTS_SPARSE_FILES)) + { + _off64_t actual_length; + DWORD size_high = 0; + actual_length = GetFileSize (get_output_handle (), &size_high); + actual_length += ((_off64_t) size_high) << 32; + if (length >= actual_length + (128 * 1024)) + { + DWORD dw; + BOOL r = DeviceIoControl (get_output_handle (), + FSCTL_SET_SPARSE, NULL, 0, NULL, + 0, &dw, NULL); + syscall_printf ("%d = DeviceIoControl(%p, FSCTL_SET_SPARSE)", + r, get_output_handle ()); + } + } + else if (wincap.has_lseek_bug ()) + res_bug = write (&res, 0); + if (!SetEndOfFile (get_output_handle ())) + __seterrno (); + else + res = res_bug; + /* restore original file pointer location */ + lseek (prev_loc, SEEK_SET); + if (!res) + touch_ctime (); + } + } + return res; +} + fhandler_disk_file::fhandler_disk_file () : fhandler_base () { |