From 1bfcaf6f47bb2eb06c071e39b6f93c92a15d4de6 Mon Sep 17 00:00:00 2001 From: Christian Heller Date: Wed, 9 Jul 2014 23:27:47 +0200 Subject: [PATCH] Server: Atomify the savefile writing. --- TODO | 4 ++-- src/server/io.c | 9 ++++++--- src/server/io.h | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 8ba4592..7557ab3 100644 --- a/TODO +++ b/TODO @@ -9,6 +9,8 @@ BOTH SERVER/CLIENT: - make server and client communicate by specific world state info requests in server/out, replacing server/worldstate +- on start, alarm about _tmp files (savefile/record) to avoid gameplay data loss + SERVER: - consider @@ -17,8 +19,6 @@ SERVER: - save confserver/world data in record and save file, too; handle them like god commands -- ensure atomic re-writing of savefile - CLIENT: - enable toggling of window borders diff --git a/src/server/io.c b/src/server/io.c index c703f0e..c1cbb3e 100644 --- a/src/server/io.c +++ b/src/server/io.c @@ -331,8 +331,11 @@ extern char * io_round() extern void save_world() { char * f_name = "save_world()"; - char * path = s[S_PATH_SAVE]; - FILE * file = try_fopen(path, "w", f_name); + uint16_t size = strlen(s[S_PATH_SAVE]) + strlen(s[S_PATH_SUFFIX_TMP]) + 1; + char * path_tmp = try_malloc(size, f_name); + int test=sprintf(path_tmp,"%s%s",s[S_PATH_SAVE], s[S_PATH_SUFFIX_TMP]); + exit_trouble(test < 0, f_name, s[S_FCN_SPRINTF]); + FILE * file = try_fopen(path_tmp, "w", f_name); write_key_value(file, s[S_CMD_DO_FOV], 0); try_fputc('\n', file, f_name); write_key_value(file, s[S_CMD_SEED_MAP], world.seed_map); @@ -345,5 +348,5 @@ extern void save_world() write_thing(file, t); } write_key_value(file, s[S_CMD_DO_FOV], 1); - try_fclose(file, f_name); + try_fclose_unlink_rename(file, path_tmp, s[S_PATH_SAVE], f_name); } diff --git a/src/server/io.h b/src/server/io.h index 0e04d80..8211753 100644 --- a/src/server/io.h +++ b/src/server/io.h @@ -26,8 +26,8 @@ */ extern char * io_round(); -/* Write to savefile god commands (one per line) to rebuild the current world - * state. +/* Write to savefile (atomically) god commands (one per line) to rebuild the + * current world state. */ extern void save_world(); -- 2.30.2