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
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2007-10-15 12:25:38 +0400
committerCorinna Vinschen <corinna@vinschen.de>2007-10-15 12:25:38 +0400
commit6ce2c24121b8d6bcf7d67ed7b44bb2bee99c9646 (patch)
treec0e1e3c4b9c555518fa52d0496756f227309996b
parentc99e78b85cd8820616cc25e8d45a68b7686e4113 (diff)
* fhandler.cc (is_at_eof): Rewrite using NT functions.
(off_current): New static variable. (off_append): Ditto. (fhandler_base::raw_write): Use NtWriteFile. Accommodate O_APPEND here. (fhandler_base::write): Drop O_APPEND hack. Use NT functions. (fhandler_base::lseek): Rewrite using NT functions. * fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Add space in debug output. (fhandler_disk_file::ftruncate): Ditto. * ntdll.h (STATUS_DISK_FULL): Define. (FILE_USE_FILE_POINTER_POSITION): Define. (FILE_WRITE_TO_END_OF_FILE): Define.
-rw-r--r--winsup/cygwin/ChangeLog17
-rw-r--r--winsup/cygwin/fhandler.cc157
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc4
-rw-r--r--winsup/cygwin/ntdll.h4
4 files changed, 108 insertions, 74 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index aed46e6cd..256ae5d89 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,4 +1,19 @@
-2007-10-12 Corinna Vinschen <corinna@vinschen.de>
+2007-10-14 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (is_at_eof): Rewrite using NT functions.
+ (off_current): New static variable.
+ (off_append): Ditto.
+ (fhandler_base::raw_write): Use NtWriteFile. Accommodate O_APPEND here.
+ (fhandler_base::write): Drop O_APPEND hack. Use NT functions.
+ (fhandler_base::lseek): Rewrite using NT functions.
+ * fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Add space in
+ debug output.
+ (fhandler_disk_file::ftruncate): Ditto.
+ * ntdll.h (STATUS_DISK_FULL): Define.
+ (FILE_USE_FILE_POINTER_POSITION): Define.
+ (FILE_WRITE_TO_END_OF_FILE): Define.
+
+2007-10-13 Corinna Vinschen <corinna@vinschen.de>
* ntdll.h (STATUS_END_OF_FILE): Define.
* path.cc (symlink_info::check_shortcut): Use NT function to get file
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index c7ba078e1..ac29256e4 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -171,17 +171,16 @@ char *fhandler_base::get_proc_fd_name (char *buf)
static int __stdcall
is_at_eof (HANDLE h, DWORD err)
{
- DWORD size, upper1, curr;
-
- size = GetFileSize (h, &upper1);
- if (size != INVALID_FILE_SIZE || GetLastError () == NO_ERROR)
- {
- LONG upper2 = 0;
- curr = SetFilePointer (h, 0, &upper2, FILE_CURRENT);
- if (curr == size && upper1 == (DWORD) upper2)
- return 1;
- }
-
+ IO_STATUS_BLOCK io;
+ FILE_POSITION_INFORMATION fpi;
+ FILE_STANDARD_INFORMATION fsi;
+
+ if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
+ FileStandardInformation))
+ && NT_SUCCESS (NtQueryInformationFile (h, &io, &fpi, sizeof fpi,
+ FilePositionInformation))
+ && fsi.EndOfFile.QuadPart == fpi.CurrentByteOffset.QuadPart)
+ return 1;
SetLastError (err);
return 0;
}
@@ -284,22 +283,30 @@ retry:
/* Cover function to WriteFile to provide Posix interface and semantics
(as much as possible). */
+static LARGE_INTEGER off_current = { QuadPart:FILE_USE_FILE_POINTER_POSITION };
+static LARGE_INTEGER off_append = { QuadPart:FILE_WRITE_TO_END_OF_FILE };
+
int
fhandler_base::raw_write (const void *ptr, size_t len)
{
- DWORD bytes_written;
+ NTSTATUS status;
+ IO_STATUS_BLOCK io;
- if (!WriteFile (get_output_handle (), ptr, len, &bytes_written, 0))
+ status = NtWriteFile (get_output_handle (), NULL, NULL, NULL, &io,
+ (PVOID) ptr, len,
+ (get_flags () & O_APPEND) ? &off_append : &off_current,
+ NULL);
+ if (!NT_SUCCESS (status))
{
- if (GetLastError () == ERROR_DISK_FULL && bytes_written > 0)
+ if (status == STATUS_DISK_FULL && io.Information > 0)
goto written;
- __seterrno ();
+ __seterrno_from_nt_status (status);
if (get_errno () == EPIPE)
raise (SIGPIPE);
return -1;
}
written:
- return bytes_written;
+ return io.Information;
}
int
@@ -697,45 +704,33 @@ int
fhandler_base::write (const void *ptr, size_t len)
{
int res;
+ IO_STATUS_BLOCK io;
+ FILE_POSITION_INFORMATION fpi;
+ FILE_STANDARD_INFORMATION fsi;
- if (get_flags () & O_APPEND)
+ if (did_lseek ())
{
- LONG off_high = 0;
- DWORD ret = SetFilePointer (get_output_handle (), 0, &off_high, FILE_END);
- if (ret == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR)
- {
- debug_printf ("Seeking to EOF in append mode failed");
- __seterrno ();
- return -1;
- }
- }
- else if (did_lseek ())
- {
- _off64_t actual_length, current_position;
- DWORD size_high = 0;
- LONG pos_high = 0;
-
did_lseek (false); /* don't do it again */
- actual_length = GetFileSize (get_output_handle (), &size_high);
- actual_length += ((_off64_t) size_high) << 32;
-
- current_position = SetFilePointer (get_output_handle (), 0, &pos_high,
- FILE_CURRENT);
- current_position += ((_off64_t) pos_high) << 32;
-
- if (current_position >= actual_length + (128 * 1024)
+ if (!(get_flags () & O_APPEND)
+ && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
+ &io, &fsi, sizeof fsi,
+ FileStandardInformation))
+ && NT_SUCCESS (NtQueryInformationFile (get_output_handle (),
+ &io, &fpi, sizeof fpi,
+ FilePositionInformation))
+ && fpi.CurrentByteOffset.QuadPart
+ >= fsi.EndOfFile.QuadPart + (128 * 1024)
&& get_fs_flags (FILE_SUPPORTS_SPARSE_FILES))
{
/* If the file system supports sparse files and the application
is writing after a long seek beyond EOF, convert the file to
a sparse file. */
- DWORD dw;
- 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)",
- r, h);
+ NTSTATUS status;
+ status = NtFsControlFile (get_output_handle (), NULL, NULL, NULL,
+ &io, FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
+ syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
+ status, pc.get_nt_native_path ());
}
}
@@ -912,7 +907,10 @@ fhandler_base::writev (const struct iovec *const iov, const int iovcnt,
_off64_t
fhandler_base::lseek (_off64_t offset, int whence)
{
- _off64_t res;
+ NTSTATUS status;
+ IO_STATUS_BLOCK io;
+ FILE_POSITION_INFORMATION fpi;
+ FILE_STANDARD_INFORMATION fsi;
/* Seeks on text files is tough, we rewind and read till we get to the
right place. */
@@ -924,35 +922,52 @@ fhandler_base::lseek (_off64_t offset, int whence)
set_readahead_valid (0);
}
- debug_printf ("lseek (%s, %D, %d)", get_name (), offset, whence);
-
- DWORD win32_whence = whence == SEEK_SET ? FILE_BEGIN
- : (whence == SEEK_CUR ? FILE_CURRENT : FILE_END);
-
- LONG off_low = ((__uint64_t) offset) & UINT32_MAX;
- LONG off_high = ((__uint64_t) offset) >> 32LL;
-
- debug_printf ("setting file pointer to %u (high), %u (low)", off_high, off_low);
- res = SetFilePointer (get_handle (), off_low, &off_high, win32_whence);
- if (res == INVALID_SET_FILE_POINTER && GetLastError ())
+ switch (whence)
{
- __seterrno ();
- res = -1;
+ case SEEK_SET:
+ fpi.CurrentByteOffset.QuadPart = offset;
+ break;
+ case SEEK_CUR:
+ status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
+ FilePositionInformation);
+ if (!NT_SUCCESS (status))
+ {
+ __seterrno_from_nt_status (status);
+ return -1;
+ }
+ fpi.CurrentByteOffset.QuadPart += offset;
+ break;
+ default: /* SEEK_END */
+ status = NtQueryInformationFile (get_handle (), &io, &fsi, sizeof fsi,
+ FileStandardInformation);
+ if (!NT_SUCCESS (status))
+ {
+ __seterrno_from_nt_status (status);
+ return -1;
+ }
+ fpi.CurrentByteOffset.QuadPart = fsi.EndOfFile.QuadPart + offset;
+ break;
}
- else
+
+ debug_printf ("setting file pointer to %U", fpi.CurrentByteOffset.QuadPart);
+ status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
+ FilePositionInformation);
+ if (!NT_SUCCESS (status))
{
- res += (_off64_t) off_high << 32;
+ __seterrno_from_nt_status (status);
+ return -1;
+ }
+ _off64_t res = fpi.CurrentByteOffset.QuadPart;
- /* When next we write(), we will check to see if *this* seek went beyond
- the end of the file and if so, potentially sparsify the file. */
- did_lseek (true);
+ /* When next we write(), we will check to see if *this* seek went beyond
+ the end of the file and if so, potentially sparsify the file. */
+ did_lseek (true);
- /* If this was a SEEK_CUR with offset 0, we still might have
- readahead that we have to take into account when calculating
- the actual position for the application. */
- if (whence == SEEK_CUR)
- res -= ralen - raixget;
- }
+ /* If this was a SEEK_CUR with offset 0, we still might have
+ readahead that we have to take into account when calculating
+ the actual position for the application. */
+ if (whence == SEEK_CUR)
+ res -= ralen - raixget;
return res;
}
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 095c779e8..051ad77aa 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -698,7 +698,7 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
FSCTL_GET_NTFS_VOLUME_DATA,
NULL, 0, &nvdb, sizeof nvdb);
if (!NT_SUCCESS (status))
- debug_printf ("%p = NtFsControlFile(%S,FSCTL_GET_NTFS_VOLUME_DATA)",
+ debug_printf ("%p = NtFsControlFile(%S, FSCTL_GET_NTFS_VOLUME_DATA)",
status, pc.get_nt_native_path ());
else
sfs->f_blocks = nvdb.TotalClusters.QuadPart;
@@ -1030,7 +1030,7 @@ fhandler_disk_file::ftruncate (_off64_t length, bool allow_truncate)
{
status = NtFsControlFile (get_handle (), NULL, NULL, NULL, &io,
FSCTL_SET_SPARSE, NULL, 0, NULL, 0);
- syscall_printf ("%p = NtFsControlFile(%S,FSCTL_SET_SPARSE)",
+ syscall_printf ("%p = NtFsControlFile(%S, FSCTL_SET_SPARSE)",
status, pc.get_nt_native_path ());
}
status = NtSetInformationFile (get_handle (), &io,
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 57bbfbb0f..d74095a57 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -26,6 +26,7 @@
#define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xc000003A)
#define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xc0000043)
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xc0000056)
+#define STATUS_DISK_FULL ((NTSTATUS) 0xc000007f)
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
#define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xc00000bb)
#define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xc0000101)
@@ -53,6 +54,9 @@
#define FILE_EXISTS 4
#define FILE_DOES_NOT_EXIST 5
+#define FILE_WRITE_TO_END_OF_FILE (-1LL)
+#define FILE_USE_FILE_POINTER_POSITION (-2LL)
+
/* Device Characteristics. */
#define FILE_REMOVABLE_MEDIA 0x00000001
#define FILE_READ_ONLY_DEVICE 0x00000002