shithub: rgbds

Download patch

ref: a9cb4f8245c0143ddd963b9eb0cf7226b4369746
parent: 1bd41bf79ae9af867e473f13ca23d036f6f27174
author: ISSOtm <[email protected]>
date: Fri Nov 8 20:09:54 EST 2019

Make RGBASM overwrite output files atomically
Fixes rednex/#446.
I am not sure this is the best (in cases where the target directory
is not writable but the target file is), but maybe this can be
toggled via a flag, for example.

--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -16,6 +16,8 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <libgen.h>
 
 #include "asm/asm.h"
 #include "asm/charmap.h"
@@ -532,13 +534,25 @@
  */
 void out_WriteObject(void)
 {
+	/* Write to a temporary file in the target's folder */
+	char *objectNameCopy = strdup(tzObjectname);
+	char const *dirPath = dirname(objectNameCopy);
+	char tmpFileName[strlen(dirPath) + 1 + 16 + 1];
+
+	sprintf(tmpFileName, "%s/rgbasm_tmpXXXXXX", dirPath);
+	free(objectNameCopy);
+	int fd = mkstemp(tmpFileName);
+
 	FILE *f;
 	struct PatchSymbol *pSym;
 	struct Section *pSect;
 
+	if (fd == -1)
+		err(1, "Couldn't create temporary file");
+
 	addexports();
 
-	f = fopen(tzObjectname, "wb");
+	f = fdopen(fd, "wb");
 	if (f == NULL)
 		fatalerror("Couldn't write file '%s'\n", tzObjectname);
 
@@ -560,6 +574,11 @@
 	}
 
 	fclose(f);
+	close(fd);
+
+	if (rename(tmpFileName, tzObjectname) != 0)
+		err(1, "Couldn't create object file (temp file kept as %s)",
+		    tmpFileName);
 }
 
 /*