X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Message-ID: <4D72992D.4090007@tweerlei.de> Date: Sat, 05 Mar 2011 21:12:29 +0100 From: Robert Wruck User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100423 Thunderbird/3.0.4 MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: 1.7.8: write fails with EAGAIN Content-Type: multipart/mixed; boundary="------------080705090405030306070509" Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --------------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 #include #include #include #include #include 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--