* 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

@ -1,3 +1,12 @@
2005-02-02 Corinna Vinschen <corinna@vinschen.de>
* 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.
2005-02-02 Corinna Vinschen <corinna@vinschen.de>
* pipe.cc (fhandler_pipe::dup): Fix conditionals in case of error.

View File

@ -1,6 +1,7 @@
/* fhandler.cc. See console.cc for fhandler_console functions.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005 Red Hat, Inc.
This file is part of Cygwin.
@ -814,8 +815,8 @@ fhandler_base::write (const void *ptr, size_t len)
HANDLE h = get_output_handle ();
BOOL r = DeviceIoControl (h, FSCTL_SET_SPARSE, NULL, 0, NULL,
0, &dw, NULL);
syscall_printf ("%d = DeviceIoControl(%p, FSCTL_SET_SPARSE, "
"NULL, 0, NULL, 0, &dw, NULL)", r, h);
syscall_printf ("%d = DeviceIoControl(%p, FSCTL_SET_SPARSE)",
r, h);
}
else if (wincap.has_lseek_bug ())
{
@ -1595,3 +1596,10 @@ fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
}
return res;
}
int
fhandler_base::ftruncate (_off64_t length)
{
set_errno (EINVAL);
return -1;
}

View File

@ -1,6 +1,7 @@
/* fhandler.h
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2005 Red Hat, Inc.
This file is part of Cygwin.
@ -250,6 +251,7 @@ class fhandler_base
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
virtual int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
virtual int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
virtual int __stdcall ftruncate (_off64_t) __attribute__ ((regparm (2)));
virtual int ioctl (unsigned int cmd, void *);
virtual int fcntl (int cmd, void *);
virtual char const *ttyname () { return get_name (); }
@ -590,6 +592,7 @@ class fhandler_disk_file: public fhandler_base
int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
int __stdcall fchown (__uid32_t uid, __gid32_t gid) __attribute__ ((regparm (2)));
int __stdcall facl (int, int, __acl32 *) __attribute__ ((regparm (3)));
int __stdcall ftruncate (_off64_t) __attribute__ ((regparm (2)));
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_t off);
int munmap (HANDLE h, caddr_t addr, size_t len);

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

View File

@ -1737,37 +1737,12 @@ setmode (int fd, int mode)
extern "C" int
ftruncate64 (int fd, _off64_t length)
{
int res = -1, res_bug = 0;
if (length < 0)
set_errno (EINVAL);
int res = -1;
cygheap_fdget cfd (fd);
if (cfd >= 0)
res = cfd->ftruncate (length);
else
{
cygheap_fdget cfd (fd);
if (cfd >= 0)
{
HANDLE h = cygheap->fdtab[fd]->get_handle ();
if (cfd->get_handle ())
{
/* remember curr file pointer location */
_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);
if (!SetEndOfFile (h))
__seterrno ();
else
res = res_bug;
/* restore original file pointer location */
cfd->lseek (prev_loc, SEEK_SET);
}
}
}
set_errno (EBADF);
syscall_printf ("%d = ftruncate (%d, %D)", res, fd, length);
return res;
}