From a9cb4f8245c0143ddd963b9eb0cf7226b4369746 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sat, 9 Nov 2019 01:09:54 +0100 Subject: [PATCH] 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. --- src/asm/output.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/asm/output.c b/src/asm/output.c index 1a019682..1c83f8e9 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "asm/asm.h" #include "asm/charmap.h" @@ -532,13 +534,25 @@ static void checksectionoverflow(uint32_t delta_size) */ 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 @@ void out_WriteObject(void) } fclose(f); + close(fd); + + if (rename(tmpFileName, tzObjectname) != 0) + err(1, "Couldn't create object file (temp file kept as %s)", + tmpFileName); } /*