I replaced the cygwin1.dll with cygwin1-20110309.dll and now a single
write() with 78 MB never returns but seems to write repeatedly to the
pipe (file was 5GB when I hit Ctrl-C).
Just terminating the loop after write_overlapped_fallback is not enough.
When the size to write exceeds MAX_OVERLAPPED_WRITE_LEN and WriteFile
fails for MAX_OVERLAPPED_WRITE_LEN, write() will always return 0.
In case of overlapped_error, nbytes should be set to -1.
I'd suggest to remove write_overlapped_fallback and instead decrement
'len' on each failure. Since write is not guaranteed to write the whole
data, this should be OK.
do
{
bool res = WriteFile (get_output_handle (), ptr, len, &nbytes,
get_overlapped ());
switch (wait_overlapped (res, true, &nbytes, is_nonblocking (),
(size_t) len))
{
case overlapped_fallback:
len /= 4; /* feel free to tune */
if (!len) {
set_errno (ENOSPC); /* Can't write anything */
nbytes = (DWORD) -1; /* Don't forget */
keep_looping = false;
break;
}
/* fall through intentionally */;
case overlapped_signal:
keep_looping = true;
break;
default: /* Added to quiet gcc */
case overlapped_error:
nbytes = (DWORD) -1; /* Don't forget */
/* fall through intentionally */;
case overlapped_success:
keep_looping = false;
break;
}
}
while (keep_looping);
Result (from the application's perspective) is:
writing 78954543 bytes...
result is 19738635, errno is 0
writing 59215908 bytes...
result is 14803977, errno is 0
writing 44411931 bytes...
result is 11102982, errno is 0
writing 33308949 bytes...
result is 8327237, errno is 0
writing 24981712 bytes...
result is 24981712, errno is 0
-Robert
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple