Skip to content

Commit

Permalink
* autoload.cc (NtSetInformationFile): Define.
Browse files Browse the repository at this point in the history
	* 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.
  • Loading branch information
github-cygwin committed Aug 7, 2006
1 parent 76ddec1 commit 7636b58
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 33 deletions.
26 changes: 26 additions & 0 deletions winsup/cygwin/ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
1 change: 1 addition & 0 deletions winsup/cygwin/autoload.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions winsup/cygwin/cygwin.din
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion winsup/cygwin/fhandler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions winsup/cygwin/fhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down Expand Up @@ -536,6 +537,8 @@ class fhandler_pipe: public fhandler_base
}
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 ();
Expand Down Expand Up @@ -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)));

Expand Down
125 changes: 98 additions & 27 deletions winsup/cygwin/fhandler_disk_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -762,45 +762,116 @@ 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);
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_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;
Expand Down
3 changes: 2 additions & 1 deletion winsup/cygwin/include/cygwin/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 17 additions & 1 deletion winsup/cygwin/include/fcntl.h
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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 */
6 changes: 6 additions & 0 deletions winsup/cygwin/ntdll.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
14 changes: 14 additions & 0 deletions winsup/cygwin/pipe.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
34 changes: 33 additions & 1 deletion winsup/cygwin/syscalls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 7636b58

Please sign in to comment.