pngfix: ensure fclose happens last on file close
This reverts the code to a variant of my old style of doing an 'fclose'
correctly and adds comments explaining why it is so difficult. Thanks
to @ihsinme for pointing out the error on github.com
Signed-off-by: John Bowler <jbowler@acm.org>
diff --git a/contrib/tools/pngfix.c b/contrib/tools/pngfix.c
index cdf3f1c..0dd0dbb 100644
--- a/contrib/tools/pngfix.c
+++ b/contrib/tools/pngfix.c
@@ -1005,10 +1005,18 @@
if (file->out != NULL)
{
- /* NOTE: this is bitwise |, all the following functions must execute and
- * must succeed.
+ /* On some systems 'fclose' deletes the FILE struct (making it
+ * inaccessbile). There is no guarantee that fclose returns an error
+ * code from fflush or, indeed, from the FILE error indicator. There is
+ * also no explicit (or clear) guarantee in the standard that anything
+ * other than a read or write operation sets the error indicator; fflush
+ * is not a read or write operation, so both conditions must be checked
+ * to ensure the close succeeded and in ANSI-C conformant code they must
+ * be checked before the fclose call.
*/
- if (ferror(file->out) | fflush(file->out) | fclose(file->out))
+ const int err = fflush(file->out) || ferror(file->out);
+
+ if (fclose(file->out) || err)
{
perror(file->out_name);
emit_error(file, READ_ERROR_CODE, "output write error");
@@ -4054,3 +4062,4 @@
return 77;
}
#endif /* PNG_SETJMP_SUPPORTED */
+/* vi: set textwidth=80 shiftwidth=3 softtabstop=-1 expandtab: */