From da5d7650b28ab76b08d7e41584201cd7b8670e57 Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Mon, 3 Mar 2003 15:47:47 +0000 Subject: Ensure that all changes to generated files happen atomically. --- update-mime-database.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'update-mime-database.c') diff --git a/update-mime-database.c b/update-mime-database.c index 8fc1380..d64e716 100644 --- a/update-mime-database.c +++ b/update-mime-database.c @@ -433,11 +433,29 @@ static void write_out_glob(gpointer key, gpointer value, gpointer data) fprintf(stream, "%s/%s:%s\n", type->media, type->subtype, pattern); } +/* Renames pathname by removing the .new extension */ +static void atomic_update(const guchar *pathname) +{ + guchar *new_name; + int len; + + len = strlen(pathname); + + g_return_if_fail(strcmp(pathname + len - 4, ".new") == 0); + + new_name = g_strndup(pathname, len - 4); + + if (rename(pathname, new_name)) + g_warning("Failed to rename %s as %s\n", pathname, new_name); + + g_free(new_name); +} + static void write_out_type(gpointer key, gpointer value, gpointer data) { Type *type = (Type *) value; const char *mime_dir = (char *) data; - char *media, *filename, *new_name; + char *media, *filename; media = g_strconcat(mime_dir, "/", type->media, NULL); mkdir(media, 0755); @@ -449,13 +467,9 @@ static void write_out_type(gpointer key, gpointer value, gpointer data) if (save_xml_file(type->output, filename) != 0) g_warning("Failed to write out '%s'\n", filename); - new_name = g_strndup(filename, strlen(filename) - 4); - if (rename(filename, new_name)) - g_warning("Failed to rename %s as %s\n", - filename, new_name); + atomic_update(filename); g_free(filename); - g_free(new_name); } static int get_priority(xmlNode *node) @@ -968,27 +982,29 @@ int main(int argc, char **argv) { FILE *globs; char *globs_path; - globs_path = g_strconcat(mime_dir, "/globs", NULL); + globs_path = g_strconcat(mime_dir, "/globs.new", NULL); globs = fopen(globs_path, "wb"); if (!globs) g_error("Failed to open '%s' for writing\n", globs_path); - g_free(globs_path); fprintf(globs, "# This file was automatically generated by the\n" "# update-mime-database command. DO NOT EDIT!\n"); g_hash_table_foreach(globs_hash, write_out_glob, globs); fclose(globs); + + atomic_update(globs_path); + g_free(globs_path); } { FILE *stream; char *magic_path; int i; - magic_path = g_strconcat(mime_dir, "/magic", NULL); + magic_path = g_strconcat(mime_dir, "/magic.new", NULL); stream = fopen(magic_path, "wb"); if (!stream) - g_error("Failed to open '%s' for writing\n", magic_path); - g_free(magic_path); + g_error("Failed to open '%s' for writing\n", + magic_path); fwrite("MIME-Magic\0\n", 1, 12, stream); if (magic->len) @@ -1000,6 +1016,9 @@ int main(int argc, char **argv) write_magic(stream, node); } fclose(stream); + + atomic_update(magic_path); + g_free(magic_path); } { -- cgit v1.2.3