From: Christian Heller Date: Wed, 9 Jul 2014 22:13:23 +0000 (+0200) Subject: Refactor atomic writing to atomic_write_start() + atomic_write_finish(). X-Git-Tag: tce~719 X-Git-Url: https://plomlompom.com/repos/?a=commitdiff_plain;h=27f8cdc988b4bbd92d9d0daee7019461c690008e;p=plomrogue Refactor atomic writing to atomic_write_start() + atomic_write_finish(). --- diff --git a/src/client/interface_conf.c b/src/client/interface_conf.c index e3bfd02..8fc234b 100644 --- a/src/client/interface_conf.c +++ b/src/client/interface_conf.c @@ -16,7 +16,7 @@ * parsetest_too_many_values(), * parse_id_uniq(), parse_init_entry() */ -#include "../common/readwrite.h" /* try_fopen(), try_fclose_unlink_rename(), +#include "../common/readwrite.h" /* atomic_write_start(), atomic_write_finish() * try_fwrite() */ #include "../common/rexit.h" /* exit_err(), exit_trouble() */ @@ -401,13 +401,8 @@ extern void obey_argv(int argc, char * argv[]) extern void save_interface_conf() { - char * f_name = "save_interface_conf()"; - char * path = world.path_interface; - size_t size = strlen(path) + 4 + 1; - char * path_tmp = try_malloc(size, f_name); - int test = snprintf(path_tmp, size, "%s_tmp", path); - exit_trouble(test < 0, f_name, "snprintf()"); - FILE * file = try_fopen(path_tmp, "w", f_name); + char * path_tmp; + FILE * file = atomic_write_start(world.path_interface, &path_tmp); char * str_keybs = "\nKEYBINDINGS "; write_def(file, str_keybs, 1, "global", 's'); write_keybindings(file, &world.kb_global); @@ -431,8 +426,7 @@ extern void save_interface_conf() write_def(file, "HEIGHT ", 0, (char *) &win->target_height, 'i'); write_keybindings(file, &win->kb); } - try_fclose_unlink_rename(file, path_tmp, path, f_name); - free(path_tmp); + atomic_write_finish(file, world.path_interface, path_tmp); } diff --git a/src/common/readwrite.c b/src/common/readwrite.c index c27e861..912e70d 100644 --- a/src/common/readwrite.c +++ b/src/common/readwrite.c @@ -75,33 +75,48 @@ extern char * try_fgets(char * line, int linemax, FILE * file, char * f) -extern void try_fclose_unlink_rename(FILE * file, char * p1, char * p2, - char * f) +extern FILE * atomic_write_start(char * path, char ** path_tmp) { - char * f_name = "try_fclose_unlink_rename()"; - try_fclose(file, f); + char * f_name = "atomic_write_start()"; + char * suffix_tmp = "_tmp"; + uint16_t size = strlen(path) + strlen(suffix_tmp) + 1; + *path_tmp = try_malloc(size, f_name); + int test = sprintf(*path_tmp, "%s%s", path, suffix_tmp); + exit_trouble(test < 0, f_name, "sprintf()"); + return try_fopen(*path_tmp, "w", f_name); +} + + + +extern void atomic_write_finish(FILE * file, char * path, char * path_tmp) +{ + char * f_name = "atomic_write_finish()"; + try_fclose(file, f_name); char * msg1 = "Trouble in "; char * msg4 = "'."; - if (!access(p2, F_OK)) + if (!access(path, F_OK)) { char * msg2 = " with unlink() on path '"; uint16_t size = strlen(msg1) + strlen(msg2) + strlen(msg4) - + strlen(f) + strlen(p2) + 1; + + strlen(f_name) + strlen(path) + 1; char * msg = try_malloc(size, f_name); - int test = sprintf(msg, "%s%s%s%s%s", msg1, f, msg2, p2, msg4); + int test = sprintf(msg, "%s%s%s%s%s", msg1, f_name, msg2, path, msg4); exit_trouble(test < 0, f_name, "sprintf()"); - exit_err(unlink(p2), msg); + exit_err(unlink(path), msg); free(msg); } char * msg2 = " with rename() from '"; char * msg3 = "' to '"; - uint16_t size = strlen(msg1) + strlen(f) + strlen(msg2) + strlen(p1) - + strlen(msg3) + strlen(p2) + strlen(msg4) + 1; + uint16_t size = strlen(msg1) + strlen(f_name) + strlen(msg2) + + + strlen(path_tmp) + strlen(msg3) + strlen(path) + + strlen(msg4) + 1; char * msg = try_malloc(size, f_name); - int test = sprintf(msg, "%s%s%s%s%s%s%s", msg1,f,msg2,p1,msg3,p2,msg4); + int test = sprintf(msg, "%s%s%s%s%s%s%s", + msg1, f_name, msg2, path_tmp, msg3, path, msg4); exit_trouble(test < 0, f_name, "sprintf()"); - exit_err(rename(p1, p2), msg); + exit_err(rename(path_tmp, path), msg); free(msg); + free(path_tmp); } diff --git a/src/common/readwrite.h b/src/common/readwrite.h index b61230f..d03aeac 100644 --- a/src/common/readwrite.h +++ b/src/common/readwrite.h @@ -29,12 +29,16 @@ extern void try_fputc(uint8_t c, FILE * file, char * f); extern int try_fgetc(FILE * file, char * f); extern char * try_fgets(char * line, int size, FILE * file, char * f); -/* Wrapper to successive call of fclose() from function called "f" on "file", - * then unlink() on file at path "p2" if it exists, then rename() from path "p1" - * to "p2". Used for handling atomic saving of files via temp files. +/* Write to "path_tmp" "path" + "_tmp" and return a new file at that "path_tmp" + * open for writing. "path_tmp" is malloc()'d, must be freed externally. +*/ +extern FILE * atomic_write_start(char * path, char ** path_tmp); + +/* Finish atomic writing started in atomic_write_start(). Wraps successive calls + * of fclose() on "file", then unlink() on file at path "path" if it exists, + * then rename() from "path_tmp" to "path", then free() on "path_tmp". */ -extern void try_fclose_unlink_rename(FILE * file, char * p1, char * p2, - char * f); +extern void atomic_write_finish(FILE * file, char * path, char * path_tmp); /* Return largest line length from "file" (including newline chars). */ extern uint32_t textfile_width(FILE * file); diff --git a/src/server/hardcoded_strings.c b/src/server/hardcoded_strings.c index 652527a..e26264a 100644 --- a/src/server/hardcoded_strings.c +++ b/src/server/hardcoded_strings.c @@ -4,7 +4,7 @@ -char * s[27]; +char * s[26]; @@ -15,7 +15,6 @@ extern void init_strings() s[S_PATH_OUT] = "server/out"; s[S_PATH_IN] = "server/in"; s[S_PATH_RECORD] = "record"; - s[S_PATH_SUFFIX_TMP] = "_tmp"; s[S_PATH_SAVE] = "savefile"; s[S_CMD_MAKE_WORLD] = "MAKE_WORLD"; s[S_CMD_DO_FOV] = "BUILD_FOVS"; diff --git a/src/server/hardcoded_strings.h b/src/server/hardcoded_strings.h index a14e85f..db4be5a 100644 --- a/src/server/hardcoded_strings.h +++ b/src/server/hardcoded_strings.h @@ -15,7 +15,6 @@ enum string_num S_PATH_OUT, S_PATH_IN, S_PATH_RECORD, - S_PATH_SUFFIX_TMP, S_PATH_SAVE, S_CMD_MAKE_WORLD, S_CMD_DO_FOV, @@ -41,7 +40,7 @@ enum string_num extern void init_strings(); -extern char * s[27]; +extern char * s[26]; diff --git a/src/server/io.c b/src/server/io.c index 761655c..c8f5167 100644 --- a/src/server/io.c +++ b/src/server/io.c @@ -11,7 +11,7 @@ #include /* strlen(), memcpy(), memset() */ #include /* time_t */ #include /* time(), nanosleep() */ -#include "../common/readwrite.h" /* try_fopen(), try_fclose_unlink_rename(), +#include "../common/readwrite.h" /* atomic_write_start(), atomic_write_finish(), * try_fwrite(), try_fputc(), try_fgetc() */ #include "../common/rexit.h" /* exit_trouble() */ @@ -180,11 +180,8 @@ static void read_file_into_queue() static void update_worldstate_file() { char * f_name = "update_worldstate_file()"; - uint16_t size = strlen(s[S_PATH_WORLDSTATE])+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_WORLDSTATE],s[S_PATH_SUFFIX_TMP]); - exit_trouble(test < 0, f_name, s[S_FCN_SPRINTF]); - FILE * file = try_fopen(path_tmp, "w", f_name); + char * path_tmp; + FILE * file = atomic_write_start(s[S_PATH_WORLDSTATE], &path_tmp); struct Thing * player = get_player(); write_value_as_line(world.turn, file); write_value_as_line(player->lifepoints, file); @@ -197,8 +194,7 @@ static void update_worldstate_file() { try_fwrite(world.log, strlen(world.log), 1, file, f_name); } - try_fclose_unlink_rename(file, path_tmp, s[S_PATH_WORLDSTATE], f_name); - free(path_tmp); + atomic_write_finish(file, s[S_PATH_WORLDSTATE], path_tmp); set_cleanup_flag(CLEANUP_WORLDSTATE); char * dot = ".\n";; try_fwrite(dot, strlen(dot), 1, world.file_out, f_name); @@ -331,11 +327,8 @@ extern char * io_round() extern void save_world() { char * f_name = "save_world()"; - 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); + char * path_tmp; + FILE * file = atomic_write_start(s[S_PATH_SAVE], &path_tmp); 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); @@ -348,6 +341,5 @@ extern void save_world() write_thing(file, t); } write_key_value(file, s[S_CMD_DO_FOV], 1); - try_fclose_unlink_rename(file, path_tmp, s[S_PATH_SAVE], f_name); - free(path_tmp); + atomic_write_finish(file, s[S_PATH_SAVE], path_tmp); } diff --git a/src/server/run.c b/src/server/run.c index 452c10b..3f1b1e3 100644 --- a/src/server/run.c +++ b/src/server/run.c @@ -4,7 +4,7 @@ #include "run.h" #include /* NULL */ #include /* uint8_t, uint16_t, uint32_t */ -#include /* FILE, printf(), sprintf(), fflush() */ +#include /* FILE, printf(), fflush() */ #include /* free(), atoi() */ #include /* strlen(), strcmp() strncmp(), strdup() */ #include /* access() */ @@ -12,8 +12,7 @@ * err_line() */ #include "../common/readwrite.h" /* try_fopen(), try_fcose(), try_fwrite(), - * try_fgets(), try_fclose_unlink_rename(), - * textfile_width(), try_fputc() + * try_fgets(), textfile_width(), try_fputc() */ #include "../common/rexit.h" /* exit_trouble(), exit_err() */ #include "../common/try_malloc.h" /* try_malloc() */ @@ -309,11 +308,8 @@ static void turn_over() static void record_msg(char * msg) { char * f_name = "record_msg()"; - uint16_t size = strlen(s[S_PATH_RECORD]) + 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_RECORD],s[S_PATH_SUFFIX_TMP]); - exit_trouble(test < 0, f_name, s[S_FCN_SPRINTF]); - FILE * file_tmp = try_fopen(path_tmp, "w", f_name); + char * path_tmp; + FILE * file_tmp = atomic_write_start(s[S_PATH_RECORD], &path_tmp); if (!access(s[S_PATH_RECORD], F_OK)) { FILE * file_read = try_fopen(s[S_PATH_RECORD], "r", f_name); @@ -328,8 +324,7 @@ static void record_msg(char * msg) } try_fwrite(msg, strlen(msg), 1, file_tmp, f_name); try_fputc('\n', file_tmp, f_name); - try_fclose_unlink_rename(file_tmp, path_tmp, s[S_PATH_RECORD], f_name); - free(path_tmp); + atomic_write_finish(file_tmp, s[S_PATH_RECORD], path_tmp); }