ref: 06fe27c51601e1822b9b3212f350c21609bdf9e9
parent: 187f88aa50f253eb670cdc415e9bc315ca289bb6
author: ISSOtm <[email protected]>
date: Fri Mar 27 07:19:02 EDT 2020
Prevent RGBASM from outputting corrupted files Properly fixes #451
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -408,13 +408,12 @@
*/
void out_WriteObject(void)
{
- FILE *f;
struct Section *pSect;
struct Assertion *assert = assertions;
+ FILE *f = tmpfile(); /* Avoids producing a corrupted file on error */
- f = fopen(tzObjectname, "wb");
if (!f)
- err(1, "Couldn't write file '%s'", tzObjectname);
+ err(1, "Couldn't create temporary file");
/* Also write exported symbols that weren't written above */
sym_ForEach(registerExportedSymbol, NULL);
@@ -441,6 +440,31 @@
assert = assert->next;
}
+ /* We're finished writing the file; now, copy it to the final one */
+ FILE *objFile = fopen(tzObjectname, "wb");
+ long size = ftell(f);
+ char buf[1024];
+
+ rewind(f);
+ while (size) {
+ long blockSize = size < sizeof(buf) ? size : sizeof(buf);
+
+ if (fread(buf, blockSize, 1, f) < 1
+ || fwrite(buf, blockSize, 1, objFile) < 1) {
+ char const *errmsg =
+ ferror(f) || ferror(objFile) ? strerror(errno)
+ : "end of file";
+
+ fclose(objFile);
+ fclose(f);
+ remove(tzObjectname);
+ errx(1, "Failed to write file \"%s\": %s", tzObjectname,
+ errmsg);
+ }
+ size -= blockSize;
+ }
+
+ fclose(objFile);
fclose(f);
}