Mail Archives: cygwin/2011/03/05/15:12:59
--------------080705090405030306070509
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit
Hi,
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.
-Robert
--------------080705090405030306070509
Content-Type: text/x-csrc;
name="writetest.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="writetest.c"
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
int main(int argc, char** argv)
{
if (argc < 2)
{
fprintf(stderr, "wrong usage\n");
return (1);
}
int fd;
if ((fd = open(argv[1], O_RDONLY)) < 0)
{
perror("open");
return (1);
}
struct stat st;
if (fstat(fd, &st) < 0)
{
perror("fstat");
close(fd);
return (1);
}
size_t len = st.st_size;
void* buf;
if ((buf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
{
perror("mmap");
close(fd);
return (1);
}
int fd2;
if (argc > 2)
{
if ((fd2 = open(argv[2], O_WRONLY | O_CREAT | O_EXCL, 0644)) < 0)
{
perror("open");
munmap(buf, len);
close(fd);
return (1);
}
}
else
fd2 = 1;
void* writebuf = buf;
size_t to_write = len;
while (to_write)
{
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;
}
}
close(fd2);
munmap(buf, len);
close(fd);
return (0);
}
--------------080705090405030306070509
Content-Type: text/plain; charset=us-ascii
--
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
--------------080705090405030306070509--
- Raw text -