It is useful to able to tell whether a dump completed successfully in situtions where we don't have access to the return code. --- notmuch-dump.c | 61 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 13 deletions(-)
diff --git a/notmuch-dump.c b/notmuch-dump.c index 28342b7..05ed6b4 100644 --- a/notmuch-dump.c +++ b/notmuch-dump.c @@ -129,30 +129,65 @@ notmuch_database_dump (notmuch_database_t *notmuch, { gzFile output; const char *mode = gzip_output ? "w9" : "wT"; + const char *name_for_error = output_file_name ? output_file_name : "stdout"; - int ret; + char *tempname = NULL; + int outfd = -1; + + int ret = -1; + + if (output_file_name) { + tempname = talloc_asprintf (notmuch, "%s.XXXXXX", output_file_name); + outfd = mkstemp (tempname); + } else { + outfd = fileno (stdout); + } - if (output_file_name) - output = gzopen (output_file_name, mode); - else - output = gzdopen (fileno (stdout), mode); + if (outfd < 0) { + fprintf (stderr, "Bad output file %s\n", name_for_error); + goto DONE; + } + + output = gzdopen (outfd, mode); if (output == NULL) { fprintf (stderr, "Error opening %s for (gzip) writing: %s\n", - output_file_name ? output_file_name : "stdout", strerror (errno)); - return EXIT_FAILURE; + name_for_error, strerror (errno)); + goto DONE; } ret = database_dump_file (notmuch, output, query_str, output_format); + if (ret) goto DONE; - if (gzflush (output, Z_FINISH)) { - fprintf (stderr, "Error flushing output: %s\n", - gzerror (output, NULL)); - return EXIT_FAILURE; + ret = gzflush (output, Z_FINISH); + if (ret) { + fprintf (stderr, "Error flushing output: %s\n", gzerror (output, NULL)); + goto DONE; } - if (output_file_name) - gzclose_w (output); + ret = fdatasync (outfd); + if (ret) { + perror ("fdatasync"); + goto DONE; + } + + if (output_file_name) { + ret = gzclose_w (output); + if (ret != Z_OK) { + ret = EXIT_FAILURE; + goto DONE; + } + + ret = rename (tempname, output_file_name); + if (ret) { + perror ("rename"); + goto DONE; + } + + } + DONE: + if (ret != EXIT_SUCCESS && output_file_name) + (void) unlink (tempname); return ret; } -- 1.9.0