* 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:
parent
76ddec15ab
commit
7636b58590
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user