b07e93afdea4fe0dca0c86cc59e00f882ae5d998 markd Mon Jan 12 22:15:42 2015 -0800 fixed output file corruption caused by by using setvbuf when mustOpen has been called with magic file name "stdout" diff --git src/lib/common.c src/lib/common.c index a84f414..b884f49 100644 --- src/lib/common.c +++ src/lib/common.c @@ -2736,30 +2736,41 @@ * Return FALSE and print a warning message if there * is a problem.*/ { FILE *f; boolean ok = TRUE; if ((pFile != NULL) && ((f = *pFile) != NULL)) { if (f != stdin && f != stdout) { if (fclose(f) != 0) { errnoWarn("fclose failed"); ok = FALSE; } } + else + { + // One expects close() to actually flush the file and close it. If + // the file was opened using the magic name "stdout" and then does a + // setvbuf(), writes to file, calls carefulClose, then frees the + // buffer, the FILE object points to invalid memory. Then the exit() + // I/O cleanup causes the invalid memory to be written to the file, + // possible outputting corruption data. If would be consistent with + // stdio behavior to have "stdout" magic name open "/dev/stdout". + fflush(f); + } *pFile = NULL; } return ok; } void carefulClose(FILE **pFile) /* Close file if open and null out handle to it. * Warn and abort if there's a problem. */ { if (!carefulCloseWarn(pFile)) noWarnAbort(); } char *firstWordInFile(char *fileName, char *wordBuf, int wordBufSize) /* Read the first word in file into wordBuf. */