KevEdit patch to avoid eating files on crash

Discuss how totally awesome Bang! is here.

Moderator: Terryn

Post Reply
User avatar
premchai21
draco somniculosus
Posts: 20
Joined: Thu Oct 01, 2009 1:00 am

KevEdit patch to avoid eating files on crash

Post by premchai21 »

So when KevEdit is saving a ZZT file, it naïvely does a fopen(…, "wb") on the file directly, which implicitly truncates the file before writing out the new data. This is a losing approach except in cases of severely limited disk space, since it means that any application crash in the middle of writing the file will result in the file being overwritten with garbage, and both the old data and the new data are gone. Hope you kept backups!

Of course, you should keep backups anyway, but KevEdit suffering a rectocranial inversion while saving has eaten parts of my work multiple times now, so I minimally patched it to write out the new file before erasing the old file, which is more sensible on a modern machine.

I sent the patch upstream but didn't get any response, so I figure I'll post it here in case you folks find it useful for local installations. It's small enough that I'll just include the context diff inline. The patch itself is in the public domain insofar as I can place it there; KevEdit retains its standard upstream copyright and GNU GPL license.

Share and enjoy!

Code: Select all

--- kevedit-cvs/src/libzzt2/world.c	2005-06-28 22:20:34.000000000 -0500
+++ kevedit-new/src/libzzt2/world.c	2010-06-28 00:10:41.000000000 -0500
@@ -114,11 +114,19 @@
 {
 	int result;
 	FILE *fp;
+	char const *const filename = world->filename;
+	size_t const tmp_size = strlen(filename) + 5;
+	char *tmp_filename = malloc(tmp_size);
+	if (tmp_filename == NULL)
+		return 0;
+	snprintf(tmp_filename, tmp_size, "%s.new", filename);
 	
 	/* Open file */
-	fp = fopen(world->filename, "wb");
-	if(fp == NULL)
+	fp = fopen(tmp_filename, "wb");
+	if(fp == NULL) {
+		free(tmp_filename);
 		return 0;
+	}
 	
 	/* Commit current board */
 	zztBoardCommit(world);
@@ -126,6 +134,10 @@
 	result = zztWorldWrite(world, fp);
 	fclose(fp);
 
+	if (result)
+		rename(tmp_filename, filename);
+	free(tmp_filename);
+
 	/* Decompress the current board */
 	zztBoardDecompress(&(world->boards[zztBoardGetCurrent(world)]));
User avatar
Commodore
fgsdfs
Posts: 2471
Joined: Wed Mar 12, 2003 5:44 pm
Location: :noitacoL
Contact:

Post by Commodore »

make a build and upload it. not all of us have c compilers.
*POW* *CLANK* *PING*
User avatar
Quantum P.
Level 17 Accordion Thief
Posts: 1433
Joined: Fri Sep 12, 2003 1:41 am
Location: Edmonds, WA
Contact:

Post by Quantum P. »

Just out of curiosity, what kind of stuff have you been doing in KevEdit? Except for the DOS version, it's been pretty stable for me.
User avatar
premchai21
draco somniculosus
Posts: 20
Joined: Thu Oct 01, 2009 1:00 am

Post by premchai21 »

Quantum P. wrote:Just out of curiosity, what kind of stuff have you been doing in KevEdit? Except for the DOS version, it's been pretty stable for me.
Commodore wrote:make a build and upload it. not all of us have c compilers.
I'd wager that most of you who don't have C compilers also don't use AMD64 GNU/Linux as a primary platform, and that the unusual-for-the-task word size may be the trigger for whatever bugs are causing it to crash in the first place. I don't normally upload binaries for that by themselves because people get horribly confused when the executables don't run on their machines, but if that's actually going to be useful, then so be it. If you're asking for some other platform, I don't presently have the resources to allocate to compiling and testing for that, so you may have to get someone else to do it or else wait a long time.
User avatar
Commodore
fgsdfs
Posts: 2471
Joined: Wed Mar 12, 2003 5:44 pm
Location: :noitacoL
Contact:

Post by Commodore »

you would wager correctly
*POW* *CLANK* *PING*
User avatar
Surlent
Oh man not him again
Posts: 129
Joined: Fri Jan 12, 2007 5:16 pm
Location: Western US

Post by Surlent »

I'll have to keep this in mind. Perhaps I can do something within the next few months. Assuming I do manage to keep this in mind, of course.
JESUS CHRIST- You start the New Testament
with this Jesus. He is so superpowered and awesome, you feel converted. You place your hope in this Jesus.
Post Reply