Mail Archives: cygwin-developers/2000/04/02/22:17:17
On Sun, Apr 02, 2000 at 09:20:45PM -0400, Chris Faylor wrote:
>I can't see an easy fix for this behavior other than to detect an
>ERROR_ACCESS_DENIED in _read and then attempt to see if we're at EOF.
>In this case, we'd have to figure out how many bytes are actually left
>in the file and just pass that many to ReadFile. That could still fail,
>of course, but in that case, it would be a UNIX-type failure.
On second thought, this isn't feasible either. We actually have to figure
out how many bytes are actually valid (x) in the buffer and how many bytes
would be read in (y). If y <= x then the read should succeed.
Corinna, do you want to take a shot at fixing this? I think the correct
place to do this is probably in fhandler_disk_file::read since you can't
really determine the number of bytes remaining anywhere else, can you?
Maybe to be safe we need a new fhandler method which can be triggered to
restart a read in the above scenario. So it would be something like:
In fhandler_base::read()
if (!ReadFile (...) && GetLastError == ERROR_ACCESS_DENIED &&
get_device () == FH_DISK)
return read_retry (in_ptr, in_len);
New function:
int
fhandler_base::read_retry (void *in_ptr, size_t in_len)
{
DWORD lowpos, highpos, lowsize, highsize;
long long size, pos;
size_t left;
MEMORY_BASIC_INFORMATION in_ptr_info;
lowsize = GetFileSize (get_io_handle (), &highsize);
if (lowsize == 0xffffffff && GetLastError () != NO_ERROR)
return -1; // need to preserve last GetLastError value
highpos = 0;
lowpos = SetFilePointer (get_io_handle (), 0, &highpos, FILE_CURRENT);
if (lowpos == 0xffffffff && GetLastError () != NO_ERROR)
return -1; // need to preserve last GetLastError value
size = ((long long) highsize) << 32 | lowsize;
pos = ((long long) highpos) << 32 | lowpos;
left = size - pos; // hopefully it fits
(void) VirtualQuery (in_ptr + left - 1, &in_ptr_info, sizeof (in_ptr_info));
if (in_ptr_info.AllocationProtect == PAGE_NOACCESS ||
in_ptr_info.State == MEM_FREE) // not sure these are the correct things to check for
return -1; // need to etc.
return read (in_ptr, left);
}
I think that is at least generally right, althought it is probably
full of typos.
cgf
- Raw text -