aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-02-02 22:42:06 +0000
committerCorinna Vinschen <corinna@vinschen.de>2005-02-02 22:42:06 +0000
commit3fd68a6a044e674d434353d5631aba2743e0bf89 (patch)
tree9f507acf3ea9c2c357cf233519a2d178dbf3b929
parent7823d9bb14798143e9791303186c7129336356dd (diff)
downloadnewlib-3fd68a6a044e674d434353d5631aba2743e0bf89.zip
newlib-3fd68a6a044e674d434353d5631aba2743e0bf89.tar.gz
newlib-3fd68a6a044e674d434353d5631aba2743e0bf89.tar.bz2
* 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.
-rw-r--r--winsup/cygwin/ChangeLog9
-rw-r--r--winsup/cygwin/fhandler.cc14
-rw-r--r--winsup/cygwin/fhandler.h5
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc48
-rw-r--r--winsup/cygwin/syscalls.cc35
5 files changed, 77 insertions, 34 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 282b8c6..99bcc93 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,14 @@
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.
2005-02-02 Corinna Vinschen <corinna@vinschen.de>
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 5f60d0e..aa996ea 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/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;
+}
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 4aaafe8..f710356 100644
--- a/winsup/cygwin/fhandler.h
+++ b/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);
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index d8e0c16..96d3c0e 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 ()
{
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 8548f5e..d4f4972 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/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;
}