maybe_flush_or_die: move a too-loose Windows specific error
check to compat Commit b2f5e268 (Windows: Work around an oddity when a pipe with no reader is written to) introduced a check for EINVAL after fflush() to fight spurious "Invalid argument" errors on Windows when a pipe was broken. But this check may hide real errors on systems that do not have the this odd behavior. Introduce an fflush wrapper in compat/mingw.* so that the treatment is only applied on Windows. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Sixt committed
Oct 17, 2012 at 09:05 UTC
84adb641545f4b58f9276adf099f840ea2928e44
3 files changed
+26
-6
compat/mingw.c
+22
@@ -335,6 +335,28 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
335
return freopen(filename, otype, stream);
336
}
337
338
+#undef fflush
339
+int mingw_fflush(FILE *stream)
340
+{
341
+ int ret = fflush(stream);
342
+
343
+ /*
344
+ * write() is used behind the scenes of stdio output functions.
345
+ * Since git code does not check for errors after each stdio write
346
+ * operation, it can happen that write() is called by a later
347
+ * stdio function even if an earlier write() call failed. In the
348
+ * case of a pipe whose readable end was closed, only the first
349
+ * call to write() reports EPIPE on Windows. Subsequent write()
350
+ * calls report EINVAL. It is impossible to notice whether this
351
+ * fflush invocation triggered such a case, therefore, we have to
352
+ * catch all EINVAL errors whole-sale.
353
+ */
354
+ if (ret && errno == EINVAL)
355
+ errno = EPIPE;
356
+
357
+ return ret;
358
+}
359
+
360
/*
361
* The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
362
* Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
compat/mingw.h
+3
@@ -185,6 +185,9 @@ FILE *mingw_fopen (const char *filename, const char *otype);
185
FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream);
186
#define freopen mingw_freopen
187
188
+int mingw_fflush(FILE *stream);
189
+#define fflush mingw_fflush
190
+
191
char *mingw_getcwd(char *pointer, int len);
192
#define getcwd mingw_getcwd
193
write_or_die.c
+1
-6
@@ -34,12 +34,7 @@ void maybe_flush_or_die(FILE *f, const char *desc)
34
return;
35
}
36
if (fflush(f)) {
37
- /*
38
- * On Windows, EPIPE is returned only by the first write()
39
- * after the reading end has closed its handle; subsequent
40
- * write()s return EINVAL.
41
- */
42
- if (errno == EPIPE || errno == EINVAL)
37
+ if (errno == EPIPE)
38
exit(0);
39
die_errno("write failure on '%s'", desc);
40
}