* 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:
parent
7823d9bb14
commit
3fd68a6a04
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue