summaryrefslogtreecommitdiff
path: root/update-mime-database.c
diff options
context:
space:
mode:
authorThomas Leonard <tal@ecs.soton.ac.uk>2003-03-03 15:47:47 +0000
committerThomas Leonard <tal@ecs.soton.ac.uk>2003-03-03 15:47:47 +0000
commitda5d7650b28ab76b08d7e41584201cd7b8670e57 (patch)
tree53e7d7600cca88e65b30a1edb1512d536835b360 /update-mime-database.c
parent6534fb957543d327fcb56dfad1746aa6e01cb327 (diff)
Ensure that all changes to generated files happen atomically.
Diffstat (limited to 'update-mime-database.c')
-rw-r--r--update-mime-database.c41
1 files changed, 30 insertions, 11 deletions
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);
}
{