summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2017-02-16 21:31:40 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-02-16 22:15:55 (GMT)
commit0838cbc22fc9567ede7a60e800d876e733820060 (patch)
treea2a90069273587574ef65ae6287b54431f4b0468
parentc3808ca6982b0ad7ee9b87eca9b50b9a24ec08b0 (diff)
downloadgit-0838cbc22fc9567ede7a60e800d876e733820060.zip
git-0838cbc22fc9567ede7a60e800d876e733820060.tar.gz
git-0838cbc22fc9567ede7a60e800d876e733820060.tar.bz2
tempfile: avoid "ferror | fclose" trick
The current code wants to record an error condition from either ferror() or fclose(), but makes sure that we always call both functions. So it can't use logical-OR "||", which would short-circuit when ferror() is true. Instead, it uses bitwise-OR "|" to evaluate both functions and set one or more bits in the "err" flag if they reported a failure. Unlike logical-OR, though, bitwise-OR does not introduce a sequence point, and the order of evaluation for its operands is unspecified. So a compiler would be free to generate code which calls fclose() first, and then ferror() on the now-freed filehandle. There's no indication that this has happened in practice, but let's write it out in a way that follows the standard. Noticed-by: Andreas Schwab <schwab@linux-m68k.org> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--tempfile.c8
1 files changed, 2 insertions, 6 deletions
diff --git a/tempfile.c b/tempfile.c
index 2990c92..ffcc272 100644
--- a/tempfile.c
+++ b/tempfile.c
@@ -247,12 +247,8 @@ int close_tempfile(struct tempfile *tempfile)
tempfile->fd = -1;
if (fp) {
tempfile->fp = NULL;
-
- /*
- * Note: no short-circuiting here; we want to fclose()
- * in any case!
- */
- err = ferror(fp) | fclose(fp);
+ err = ferror(fp);
+ err |= fclose(fp);
} else {
err = close(fd);
}