Browse Source

* 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.
binutils-2_16-branch
Corinna Vinschen 21 years ago
parent
commit
3fd68a6a04
  1. 9
      winsup/cygwin/ChangeLog
  2. 14
      winsup/cygwin/fhandler.cc
  3. 5
      winsup/cygwin/fhandler.h
  4. 48
      winsup/cygwin/fhandler_disk_file.cc
  5. 35
      winsup/cygwin/syscalls.cc

9
winsup/cygwin/ChangeLog

@ -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.

14
winsup/cygwin/fhandler.cc

@ -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;
}

5
winsup/cygwin/fhandler.h

@ -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);

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

35
winsup/cygwin/syscalls.cc

@ -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…
Cancel
Save