* 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.
This commit is contained in:
Corinna Vinschen
2005-02-02 22:42:06 +00:00
parent 7823d9bb14
commit 3fd68a6a04
5 changed files with 77 additions and 34 deletions

View File

@ -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 ()
{