path: root/tempfile.c
diff options
authorJeff King <>2017-02-16 21:31:40 (GMT)
committerJunio C Hamano <>2017-02-16 22:15:55 (GMT)
commit0838cbc22fc9567ede7a60e800d876e733820060 (patch)
treea2a90069273587574ef65ae6287b54431f4b0468 /tempfile.c
parentc3808ca6982b0ad7ee9b87eca9b50b9a24ec08b0 (diff)
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 <> Signed-off-by: Jeff King <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'tempfile.c')
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);