Skip to content

Commit 2b86292

Browse files
dschogitster
authored andcommitted
mingw: emulate write(2) that fails with a EPIPE
On Windows, when writing to a pipe fails, errno is always EINVAL. However, Git expects it to be EPIPE. According to the documentation, there are two cases in which write() triggers EINVAL: the buffer is NULL, or the length is odd but the mode is 16-bit Unicode (the broken pipe is not mentioned as possible cause). Git never sets the file mode to anything but binary, therefore we know that errno should actually be EPIPE if it is EINVAL and the buffer is not NULL. See https://msdn.microsoft.com/en-us/library/1570wh78.aspx for more details. This works around t5571.11 failing with v2.6.4 on Windows. Signed-off-by: Johannes Schindelin <[email protected]> Acked-by: Johannes Sixt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1ff8856 commit 2b86292

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

compat/mingw.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,23 @@ int mingw_fflush(FILE *stream)
394394
return ret;
395395
}
396396

397+
#undef write
398+
ssize_t mingw_write(int fd, const void *buf, size_t len)
399+
{
400+
ssize_t result = write(fd, buf, len);
401+
402+
if (result < 0 && errno == EINVAL && buf) {
403+
/* check if fd is a pipe */
404+
HANDLE h = (HANDLE) _get_osfhandle(fd);
405+
if (GetFileType(h) == FILE_TYPE_PIPE)
406+
errno = EPIPE;
407+
else
408+
errno = EINVAL;
409+
}
410+
411+
return result;
412+
}
413+
397414
int mingw_access(const char *filename, int mode)
398415
{
399416
wchar_t wfilename[MAX_PATH];

compat/mingw.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream);
210210
int mingw_fflush(FILE *stream);
211211
#define fflush mingw_fflush
212212

213+
ssize_t mingw_write(int fd, const void *buf, size_t len);
214+
#define write mingw_write
215+
213216
int mingw_access(const char *filename, int mode);
214217
#undef access
215218
#define access mingw_access

0 commit comments

Comments
 (0)