[PATCH] mingw: handle writes to non-blocking pipe
From: René Scharfe <hidden>
Date: 2022-08-10 05:48:11
Subsystem:
the rest · Maintainer:
Linus Torvalds
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 [off-list ref] Signed-off-by: René Scharfe <redacted> --- 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