On Wed, Aug 10, 2022 at 07:39:40AM +0200, René Scharfe wrote: > write() on Windows reports ENOSPC when writing to a non-blocking pipe > whose buffer is full and rejects writes bigger than the buffer outright. > Change the error code to EAGAIN and try a buffer-sized partial write to > comply with POSIX and the expections of our Git-internal callers. Bearing in mind that I have no qualifications for reviewing Windows-specific patches, this seems like the right thing to be doing from the behavior you saw. One question: > + if (result < 0 && errno == ENOSPC) { > + /* check if fd is a non-blocking pipe */ > + HANDLE h = (HANDLE) _get_osfhandle(fd); > + DWORD s; > + if (GetFileType(h) == FILE_TYPE_PIPE && > + GetNamedPipeHandleState(h, &s, NULL, NULL, NULL, NULL, 0) && > + (s & PIPE_NOWAIT)) { > + DWORD obuflen; > + if (!GetNamedPipeInfo(h, NULL, &obuflen, NULL, NULL)) > + obuflen = PIPE_BUFFER_SIZE; > + if (len > obuflen) > + return mingw_write(fd, buf, obuflen); > + errno = EAGAIN; > + } OK, so we call GetNamedPipeInfo() to find the size of the pipe buffer. It's unclear to me from Microsoft's docs if that is the _total_ size, or if it's the remaining available size. Hopefully the latter, since none of this works otherwise. ;) But two corner cases: - If we fail to get the size, we guess that it's the maximum. Is this dangerous? I'm not sure why the call would fail, but if for some reason it did fail and we can't make forward progress, would we enter an infinite recursion of mingw_write()? Would it be safer to bail with EAGAIN in such a case (through granted, that probably just puts us into an infinite loop in xwrite())? - According to the docs: If the buffer size is zero, the buffer is allocated as needed. If we see this case, we'd then call mingw_write() with 0 bytes, which I imagine also makes no forward progress (though maybe we eventually return a successful 0-byte write?). -Peff