Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-08-07 23:29:14 +0400
committerCorinna Vinschen <corinna@vinschen.de>2006-08-07 23:29:14 +0400
commit7636b58590621af3c341c3eb37a017e0e6598d3f (patch)
tree7105f91a629f9f9d14224b6405442cf841cf875f /winsup
parent76ddec15abf7557374341c96f999b4965bc10d8d (diff)
* autoload.cc (NtSetInformationFile): Define.
* cygwin.din: Export posix_fadvise and posix_fallocate. * fhandler.cc (fhandler_base::fadvise): New method. (fhandler_base::ftruncate): Add allow_truncate parameter. * fhandler.h (class fhandler_base): Add fadvise method. Accomodate new parameter to ftruncate. (class fhandler_pipe): Add fadvise and ftruncate methods. (class fhandler_disk_file): Add fadvise method. Accomodate new parameter to ftruncate. * fhandler_disk_file.cc (fhandler_disk_file::fadvise): New method. (fhandler_disk_file::ftruncate): Accomodate new allow_truncate parameter. Set EOF using NtSetInformationFile on NT. * ntdll.h (struct _FILE_END_OF_FILE_INFORMATION): Define. (NtSetInformationFile): Declare. * pipe.cc (fhandler_pipe::fadvise): New method. (fhandler_pipe::ftruncate): Ditto. * syscalls.cc (posix_fadvise): New function. (posix_fallocate): Ditto. (ftruncate64): Accomodate second parameter to fhandler's ftruncate method. * include/fcntl.h: Add POSIX_FADV_* flags. Add declarations of posix_fadvise and posix_fallocate. * include/cygwin/version.h: Bump API minor number.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog26
-rw-r--r--winsup/cygwin/autoload.cc1
-rw-r--r--winsup/cygwin/cygwin.din2
-rw-r--r--winsup/cygwin/fhandler.cc9
-rw-r--r--winsup/cygwin/fhandler.h8
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc125
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/include/fcntl.h18
-rw-r--r--winsup/cygwin/ntdll.h6
-rw-r--r--winsup/cygwin/pipe.cc14
-rw-r--r--winsup/cygwin/syscalls.cc34
11 files changed, 213 insertions, 33 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index f9b288c06..2b97b08f6 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,29 @@
+2006-08-07 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc (NtSetInformationFile): Define.
+ * cygwin.din: Export posix_fadvise and posix_fallocate.
+ * fhandler.cc (fhandler_base::fadvise): New method.
+ (fhandler_base::ftruncate): Add allow_truncate parameter.
+ * fhandler.h (class fhandler_base): Add fadvise method. Accomodate
+ new parameter to ftruncate.
+ (class fhandler_pipe): Add fadvise and ftruncate methods.
+ (class fhandler_disk_file): Add fadvise method. Accomodate new
+ parameter to ftruncate.
+ * fhandler_disk_file.cc (fhandler_disk_file::fadvise): New method.
+ (fhandler_disk_file::ftruncate): Accomodate new allow_truncate
+ parameter. Set EOF using NtSetInformationFile on NT.
+ * ntdll.h (struct _FILE_END_OF_FILE_INFORMATION): Define.
+ (NtSetInformationFile): Declare.
+ * pipe.cc (fhandler_pipe::fadvise): New method.
+ (fhandler_pipe::ftruncate): Ditto.
+ * syscalls.cc (posix_fadvise): New function.
+ (posix_fallocate): Ditto.
+ (ftruncate64): Accomodate second parameter to fhandler's ftruncate
+ method.
+ * include/fcntl.h: Add POSIX_FADV_* flags. Add declarations of
+ posix_fadvise and posix_fallocate.
+ * include/cygwin/version.h: Bump API minor number.
+
2006-08-02 Christopher Faylor <cgf@timesys.com>
* environ.cc (env_win32_to_posix_path_list): Declare.
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index fc73e8bf4..d1d234dee 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -403,6 +403,7 @@ LoadDLLfuncNt (NtQuerySecurityObject, 20, ntdll)
LoadDLLfuncNt (NtQueryVirtualMemory, 24, ntdll)
LoadDLLfuncNt (NtQueryVolumeInformationFile, 20, ntdll)
LoadDLLfuncNt (NtSetEaFile, 16, ntdll)
+LoadDLLfuncNt (NtSetInformationFile, 20, ntdll)
LoadDLLfuncNt (NtSetSecurityObject, 12, ntdll)
LoadDLLfuncNt (NtUnlockVirtualMemory, 16, ntdll)
LoadDLLfuncNt (NtUnmapViewOfSection, 8, ntdll)
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index a80ea388f..e8a40ede2 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -976,6 +976,8 @@ poll SIGFE
_poll = poll SIGFE
popen SIGFE
_popen = popen SIGFE
+posix_fadvise SIGFE
+posix_fallocate SIGFE
posix_openpt SIGFE
posix_regcomp SIGFE
posix_regerror SIGFE
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index 06bed1b46..00e987587 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -1652,7 +1652,14 @@ fhandler_base::facl (int cmd, int nentries, __aclent32_t *aclbufp)
}
int
-fhandler_base::ftruncate (_off64_t length)
+fhandler_base::fadvise (_off64_t offset, _off64_t length, int advice)
+{
+ set_errno (EINVAL);
+ return -1;
+}
+
+int
+fhandler_base::ftruncate (_off64_t length, bool allow_truncate)
{
set_errno (EINVAL);
return -1;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index dee16aaea..6103b432c 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -279,7 +279,8 @@ 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 __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
+ virtual int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
virtual int __stdcall link (const char *) __attribute__ ((regparm (2)));
virtual int __stdcall utimes (const struct timeval *) __attribute__ ((regparm (2)));
virtual int __stdcall fsync () __attribute__ ((regparm (1)));
@@ -536,6 +537,8 @@ public:
}
int dup (fhandler_base *child);
int ioctl (unsigned int cmd, void *);
+ int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
+ int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
void fixup_in_child ();
virtual void fixup_after_fork (HANDLE);
void fixup_after_exec ();
@@ -684,7 +687,8 @@ 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)));
+ int __stdcall fadvise (_off64_t, _off64_t, int) __attribute__ ((regparm (3)));
+ int __stdcall ftruncate (_off64_t, bool) __attribute__ ((regparm (3)));
int __stdcall link (const char *) __attribute__ ((regparm (2)));
int __stdcall utimes (const struct timeval *) __attribute__ ((regparm (2)));
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 6190e45d2..a8b6dc31f 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -762,11 +762,57 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
}
int
-fhandler_disk_file::ftruncate (_off64_t length)
+fhandler_disk_file::fadvise (_off64_t offset, _off64_t length, int advice)
{
- int res = -1, res_bug = 0;
+ if (advice < POSIX_FADV_NORMAL || advice > POSIX_FADV_NOREUSE)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ if (!wincap.is_winnt ())
+ return 0;
+
+ /* Windows only supports advice flags for the whole file. We're using
+ a simplified test here so that we don't have to ask for the actual
+ file size. Length == 0 means all bytes starting at offset anyway.
+ So we only actually follow the advice, if it's given for offset == 0. */
+ if (offset != 0)
+ return 0;
+
+ /* We only support normal and sequential mode for now. Everything which
+ is not POSIX_FADV_SEQUENTIAL is treated like POSIX_FADV_NORMAL. */
+ if (advice != POSIX_FADV_SEQUENTIAL)
+ advice = POSIX_FADV_NORMAL;
+
+ IO_STATUS_BLOCK io;
+ FILE_MODE_INFORMATION fmi;
+ NTSTATUS status = NtQueryInformationFile (get_handle (), &io,
+ &fmi, sizeof fmi,
+ FileModeInformation);
+ if (!NT_SUCCESS (status))
+ __seterrno_from_nt_status (status);
+ else
+ {
+ fmi.Mode &= ~FILE_SEQUENTIAL_ONLY;
+ if (advice == POSIX_FADV_SEQUENTIAL)
+ fmi.Mode |= FILE_SEQUENTIAL_ONLY;
+ status = NtSetInformationFile (get_handle (), &io, &fmi, sizeof fmi,
+ FileModeInformation);
+ if (NT_SUCCESS (status))
+ return 0;
+ __seterrno_from_nt_status (status);
+ }
+
+ return -1;
+}
+
+int
+fhandler_disk_file::ftruncate (_off64_t length, bool allow_truncate)
+{
+ int res = -1;
- if (length < 0 || !get_output_handle ())
+ if (length < 0 || !get_handle ())
set_errno (EINVAL);
else if (pc.isdir ())
set_errno (EISDIR);
@@ -774,33 +820,58 @@ fhandler_disk_file::ftruncate (_off64_t length)
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_handle (), &size_high);
+ actual_length += ((_off64_t) size_high) << 32;
+
+ /* If called through posix_fallocate, silently succeed if length
+ is less than the file's actual length. */
+ if (!allow_truncate && length < actual_length)
+ return 0;
+
+ if (wincap.is_winnt ())
+ {
+ NTSTATUS status;
+ IO_STATUS_BLOCK io;
+ FILE_END_OF_FILE_INFORMATION feofi;
+
+ feofi.EndOfFile.QuadPart = length;
+ /* Create sparse files only when called through ftruncate, not when
+ called through posix_fallocate. */
+ if (allow_truncate
+ && get_fs_flags (FILE_SUPPORTS_SPARSE_FILES)
+ && length >= actual_length + (128 * 1024))
{
- _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 ());
- }
+ DWORD dw;
+ BOOL r = DeviceIoControl (get_handle (),
+ FSCTL_SET_SPARSE, NULL, 0, NULL,
+ 0, &dw, NULL);
+ syscall_printf ("%d = DeviceIoControl(%p, FSCTL_SET_SPARSE)",
+ r, get_handle ());
}
- else if (wincap.has_lseek_bug ())
- res_bug = write (&res, 0);
- if (!SetEndOfFile (get_output_handle ()))
- __seterrno ();
+ status = NtSetInformationFile (get_handle (), &io,
+ &feofi, sizeof feofi,
+ FileEndOfFileInformation);
+ if (!NT_SUCCESS (status))
+ __seterrno_from_nt_status (status);
else
- res = res_bug;
- /* restore original file pointer location */
- lseek (prev_loc, SEEK_SET);
+ res = 0;
+ }
+ else
+ {
+ _off64_t prev_loc = lseek (0, SEEK_CUR);
+ if (lseek (length, SEEK_SET) >= 0)
+ {
+ int res_bug = write (&res, 0);
+ if (!SetEndOfFile (get_handle ()))
+ __seterrno ();
+ else
+ res = res_bug;
+ /* restore original file pointer location */
+ lseek (prev_loc, SEEK_SET);
+ }
+
}
}
return res;
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index be660c61a..30ae75800 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -294,12 +294,13 @@ details. */
158: Export bindresvport, bindresvport_sa, iruserok_sa, rcmd_af,
rresvport_af.
159: Export posix_openpt.
+ 160: Export posix_fadvice, posix_fallocate.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 159
+#define CYGWIN_VERSION_API_MINOR 160
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/fcntl.h b/winsup/cygwin/include/fcntl.h
index 6e50b3304..3e88f35f4 100644
--- a/winsup/cygwin/include/fcntl.h
+++ b/winsup/cygwin/include/fcntl.h
@@ -1,6 +1,6 @@
/* fcntl.h
- Copyright 1996, 1998, 2001, 2005 Red Hat, Inc.
+ Copyright 1996, 1998, 2001, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -23,4 +23,20 @@ details. */
#define O_DSYNC _FSYNC
#define O_RSYNC _FSYNC
+#define POSIX_FADV_NORMAL 0
+#define POSIX_FADV_SEQUENTIAL 1
+#define POSIX_FADV_RANDOM 2
+#define POSIX_FADV_WILLNEED 3
+#define POSIX_FADV_DONTNEED 4
+#define POSIX_FADV_NOREUSE 5
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int posix_fadvise _PARAMS ((int, off_t, off_t, int));
+extern int posix_fallocate _PARAMS ((int, off_t, off_t));
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _FCNTL_H */
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 2a71cd8f6..0855a878e 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -484,6 +484,10 @@ typedef struct _FILE_POSITION_INFORMATION {
LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
+typedef struct _FILE_END_OF_FILE_INFORMATION {
+ LARGE_INTEGER EndOfFile;
+} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
+
typedef struct _FILE_MODE_INFORMATION {
ULONG Mode;
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
@@ -646,6 +650,8 @@ extern "C"
VOID *, ULONG,
FS_INFORMATION_CLASS);
NTSTATUS NTAPI NtSetEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG);
+ NTSTATUS NTAPI NtSetInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
+ FILE_INFORMATION_CLASS);
NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION,
PSECURITY_DESCRIPTOR);
NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, ULONG *, ULONG);
diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc
index a6171f2f9..d56b32aff 100644
--- a/winsup/cygwin/pipe.cc
+++ b/winsup/cygwin/pipe.cc
@@ -151,6 +151,20 @@ fhandler_pipe::lseek (_off64_t offset, int whence)
return -1;
}
+int
+fhandler_pipe::fadvise (_off64_t offset, _off64_t length, int advice)
+{
+ set_errno (ESPIPE);
+ return -1;
+}
+
+int
+fhandler_pipe::ftruncate (_off64_t length, bool allow_truncate)
+{
+ set_errno (allow_truncate ? EINVAL : ESPIPE);
+ return -1;
+}
+
void
fhandler_pipe::set_close_on_exec (bool val)
{
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index a8b7aa815..c56cb58f0 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1753,12 +1753,44 @@ cygwin_setmode (int fd, int mode)
}
extern "C" int
+posix_fadvise (int fd, _off64_t offset, _off64_t len, int advice)
+{
+ int res = -1;
+ cygheap_fdget cfd (fd);
+ if (cfd >= 0)
+ res = cfd->fadvise (offset, len, advice);
+ else
+ set_errno (EBADF);
+ syscall_printf ("%d = posix_fadvice (%d, %D, %D, %d)",
+ res, fd, offset, len, advice);
+ return res;
+}
+
+extern "C" int
+posix_fallocate (int fd, _off64_t offset, _off64_t len)
+{
+ int res = -1;
+ if (offset < 0 || len == 0)
+ set_errno (EINVAL);
+ else
+ {
+ cygheap_fdget cfd (fd);
+ if (cfd >= 0)
+ res = cfd->ftruncate (offset + len, false);
+ else
+ set_errno (EBADF);
+ }
+ syscall_printf ("%d = posix_fallocate (%d, %D, %D)", res, fd, offset, len);
+ return res;
+}
+
+extern "C" int
ftruncate64 (int fd, _off64_t length)
{
int res = -1;
cygheap_fdget cfd (fd);
if (cfd >= 0)
- res = cfd->ftruncate (length);
+ res = cfd->ftruncate (length, true);
else
set_errno (EBADF);
syscall_printf ("%d = ftruncate (%d, %D)", res, fd, length);