home · contact · privacy
Server: Atomify the savefile writing.
authorChristian Heller <c.heller@plomlompom.de>
Wed, 9 Jul 2014 21:27:47 +0000 (23:27 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Wed, 9 Jul 2014 21:27:47 +0000 (23:27 +0200)
TODO
src/server/io.c
src/server/io.h

diff --git a/TODO b/TODO
index 8ba459243520e95c96b518152f2895f08e5469c0..7557ab3f4a7b144bacf3f097af34a212c01e4520 100644 (file)
--- 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
index c703f0e68929a9c879c84bb8ced011875f27874d..c1cbb3e825194f39b56f8d617a1dac401e2df1e5 100644 (file)
@@ -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);
 }
index 0e04d80edc44db702b83a24afcdaaf8b2fe1f1b6..82117538c4bd2a87b877b777fba21db58120eedb 100644 (file)
@@ -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();