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. Helped-by: Jeff King <peff@xxxxxxxx> Signed-off-by: René Scharfe <l.s.r@xxxxxx> --- compat/mingw.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/compat/mingw.c b/compat/mingw.c index b5502997e2..c6f244c0fe 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -689,6 +689,8 @@ int mingw_fflush(FILE *stream) return ret; } +#define PIPE_BUFFER_SIZE (8192) + #undef write ssize_t mingw_write(int fd, const void *buf, size_t len) { @@ -702,6 +704,21 @@ ssize_t mingw_write(int fd, const void *buf, size_t len) else errno = EINVAL; } + 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; + } + } return result; } @@ -1079,7 +1096,7 @@ int pipe(int filedes[2]) HANDLE h[2]; /* this creates non-inheritable handles */ - if (!CreatePipe(&h[0], &h[1], NULL, 8192)) { + if (!CreatePipe(&h[0], &h[1], NULL, PIPE_BUFFER_SIZE)) { errno = err_win_to_posix(GetLastError()); return -1; } -- 2.37.1.windows.1