* 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.
This commit is contained in:
Corinna Vinschen 2006-08-07 19:29:14 +00:00
parent 76ddec15ab
commit 7636b58590
11 changed files with 213 additions and 33 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 (length < 0 || !get_output_handle ())
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_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;

View File

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

View File

@ -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 */

View File

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

View File

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

View File

@ -1752,13 +1752,45 @@ cygwin_setmode (int fd, int mode)
return res;
}
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);