aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Sixt <j6t@kdbg.org>2012-10-17 09:05:51 +0200
committerJunio C Hamano <gitster@pobox.com>2012-10-17 00:33:42 -0700
commit84adb641545f4b58f9276adf099f840ea2928e44 (patch)
treed254096fe4a3e94ac9f79d88be6dd83cf6c21590
parentbafc478f1618534fcb85bedc0fa224bd2d462441 (diff)
downloadgit-84adb641545f4b58f9276adf099f840ea2928e44.tar.gz
git-84adb641545f4b58f9276adf099f840ea2928e44.tar.xz
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>
-rw-r--r--compat/mingw.c22
-rw-r--r--compat/mingw.h3
-rw-r--r--write_or_die.c7
3 files changed, 26 insertions, 6 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index afc892d6b..4e6383898 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -335,6 +335,28 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream)
return freopen(filename, otype, stream);
}
+#undef fflush
+int mingw_fflush(FILE *stream)
+{
+ int ret = fflush(stream);
+
+ /*
+ * write() is used behind the scenes of stdio output functions.
+ * Since git code does not check for errors after each stdio write
+ * operation, it can happen that write() is called by a later
+ * stdio function even if an earlier write() call failed. In the
+ * case of a pipe whose readable end was closed, only the first
+ * call to write() reports EPIPE on Windows. Subsequent write()
+ * calls report EINVAL. It is impossible to notice whether this
+ * fflush invocation triggered such a case, therefore, we have to
+ * catch all EINVAL errors whole-sale.
+ */
+ if (ret && errno == EINVAL)
+ errno = EPIPE;
+
+ return ret;
+}
+
/*
* The unit of FILETIME is 100-nanoseconds since January 1, 1601, UTC.
* Returns the 100-nanoseconds ("hekto nanoseconds") since the epoch.
diff --git a/compat/mingw.h b/compat/mingw.h
index 61a652138..eeb08d120 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -185,6 +185,9 @@ FILE *mingw_fopen (const char *filename, const char *otype);
FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream);
#define freopen mingw_freopen
+int mingw_fflush(FILE *stream);
+#define fflush mingw_fflush
+
char *mingw_getcwd(char *pointer, int len);
#define getcwd mingw_getcwd
diff --git a/write_or_die.c b/write_or_die.c
index d45b53602..960f448cf 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -34,12 +34,7 @@ void maybe_flush_or_die(FILE *f, const char *desc)
return;
}
if (fflush(f)) {
- /*
- * On Windows, EPIPE is returned only by the first write()
- * after the reading end has closed its handle; subsequent
- * write()s return EINVAL.
- */
- if (errno == EPIPE || errno == EINVAL)
+ if (errno == EPIPE)
exit(0);
die_errno("write failure on '%s'", desc);
}