This is the mail archive of the
mailing list for the Cygwin project.
1.7.8: write fails with EAGAIN
- From: Robert Wruck <wruck at tweerlei dot de>
- To: cygwin at cygwin dot com
- Date: Sat, 05 Mar 2011 21:12:29 +0100
- Subject: 1.7.8: write fails with EAGAIN
recently, I found that cygwin-git was not able to 'cat-file' files that
exceeded some size (in my case about 80MB).
I tracked this down to the cygwin implementation of write() that behaves
quite odd in some cases.
I wrote a small program (source attached) that mmaps a given file and
tries to write it to another file or stdout.
The results vary:
If the destination is a file (`writetest infile outfile` or `writetest
infile > outfile`), the write succeeds in a single call.
If the destination is a pipe (`writetest infile | cat > outfile`), the
write succeeds in most cases. BUT:
Under WinXP (XP Service Pack 2, 32bit), the call returns -1 and
errno=EAGAIN. Nevertheless, SOME data is written to the pipe (in my case
4096 byte for each call).
This breaks git since it does an infinite loop while errno=EAGAIN.
It happens only for big files. On one machine, 87MB failed, on another
one all went well up to ~200MB. It's not a disk space issue. It
shouldn't be a memory issue - the test machine has 4GB.
I wasn't able to reproduce this on Win2k (32bit) nor Win7 (64bit) but
maybe I didn't try enough file sizes...
cygwin version is cygwin-1_7_8-release, actually a fresh install made today.
Any ideas where to investigate further? EAGAIN is set for example in
fhandler.cc, fhandler_base_overlapped::has_ongoing_io but I don't know
whether that function is involved in my case.
Please Cc me, I'm not subscribed.
int main(int argc, char** argv)
if (argc < 2)
fprintf(stderr, "wrong usage\n");
if ((fd = open(argv, O_RDONLY)) < 0)
struct stat st;
if (fstat(fd, &st) < 0)
size_t len = st.st_size;
if ((buf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
if (argc > 2)
if ((fd2 = open(argv, O_WRONLY | O_CREAT | O_EXCL, 0644)) < 0)
fd2 = 1;
void* writebuf = buf;
size_t to_write = len;
fprintf(stderr, "writing %u bytes...\n", to_write);
ssize_t written = write(fd2, writebuf, to_write);
int err = errno;
fprintf(stderr, "result is %i, errno is %i\n", written, err);
if (written > 0)
to_write -= written;
writebuf += written;
Problem reports: http://cygwin.com/problems.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple