diff options
Diffstat (limited to 'src/hwdb/hwdb.c')
-rw-r--r-- | src/hwdb/hwdb.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/src/hwdb/hwdb.c b/src/hwdb/hwdb.c index 793398ca68..ead4e1770b 100644 --- a/src/hwdb/hwdb.c +++ b/src/hwdb/hwdb.c @@ -403,14 +403,14 @@ static int trie_store(struct trie *trie, const char *filename) { t.strings_off = sizeof(struct trie_header_f); trie_store_nodes_size(&t, trie->root); - r = fopen_temporary(filename , &t.f, &filename_tmp); + r = fopen_temporary(filename, &t.f, &filename_tmp); if (r < 0) return r; fchmod(fileno(t.f), 0444); /* write nodes */ if (fseeko(t.f, sizeof(struct trie_header_f), SEEK_SET) < 0) - goto error; + goto error_fclose; root_off = trie_store_nodes(&t, trie->root); h.nodes_root_off = htole64(root_off); @@ -425,13 +425,20 @@ static int trie_store(struct trie *trie, const char *filename) { size = ftello(t.f); h.file_size = htole64(size); if (fseeko(t.f, 0, SEEK_SET) < 0) - goto error; - + goto error_fclose; fwrite(&h, sizeof(struct trie_header_f), 1, t.f); - if (fclose(t.f) < 0 || rename(filename_tmp, filename) < 0) { - unlink_noerrno(filename_tmp); - return -errno; - } + + if (ferror(t.f)) + goto error_fclose; + if (fflush(t.f) < 0) + goto error_fclose; + if (fsync(fileno(t.f)) < 0) + goto error_fclose; + if (rename(filename_tmp, filename) < 0) + goto error_fclose; + + /* write succeeded */ + fclose(t.f); log_debug("=== trie on-disk ==="); log_debug("size: %8"PRIi64" bytes", size); @@ -446,7 +453,7 @@ static int trie_store(struct trie *trie, const char *filename) { log_debug("strings start: %8"PRIu64, t.strings_off); return 0; - error: + error_fclose: r = -errno; fclose(t.f); unlink(filename_tmp); |