Supercedes 

  id:1396554083-3892-2-git-send-email-da...@tethera.net

- adds new analogues of strerror
  - util_error_string
  - gz_error_string

Interdiff:

diff --git a/configure b/configure
index 1d624f7..83b4af7 100755
--- a/configure
+++ b/configure
@@ -509,7 +509,7 @@ EOF
        echo "  http://xapian.org/";
     fi
     if [ $have_zlib -eq 0 ]; then
-       echo "  zlib library (including development files such as headers)"
+       echo "  zlib library (>= version 1.2.5.2, including development files 
such as headers)"
        echo "  http://zlib.net/";
        echo
     fi
diff --git a/notmuch-dump.c b/notmuch-dump.c
index 2a7252a..2849eab 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -127,7 +127,7 @@ notmuch_database_dump (notmuch_database_t *notmuch,
                       dump_format_t output_format,
                       notmuch_bool_t gzip_output)
 {
-    gzFile output;
+    gzFile output = NULL;
     const char *mode = gzip_output ? "w9" : "wT";
     const char *name_for_error = output_file_name ? output_file_name : 
"stdout";
 
@@ -178,7 +178,10 @@ notmuch_database_dump (notmuch_database_t *notmuch,
     }
 
     if (gzclose_w (output) != Z_OK) {
+       fprintf (stderr, "Error closing %s: %s\n", name_for_error,
+                gzerror (output, NULL));
        ret = EXIT_FAILURE;
+       output = NULL;
        goto DONE;
     }
 
@@ -192,6 +195,9 @@ notmuch_database_dump (notmuch_database_t *notmuch,
 
     }
  DONE:
+    if (ret != EXIT_SUCCESS && output)
+       (void) gzclose_w (output);
+
     if (ret != EXIT_SUCCESS && output_file_name)
        (void) unlink (tempname);
 
diff --git a/notmuch-restore.c b/notmuch-restore.c
index eb5b7b2..7abee0a 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -129,7 +129,8 @@ notmuch_restore_command (notmuch_config_t *config, int 
argc, char *argv[])
     tag_op_list_t *tag_ops;
 
     char *input_file_name = NULL;
-    gzFile input;
+    const char *name_for_error = NULL;
+    gzFile input = NULL;
     char *line = NULL;
     void *line_ctx = NULL;
     ssize_t line_len;
@@ -157,19 +158,26 @@ notmuch_restore_command (notmuch_config_t *config, int 
argc, char *argv[])
     };
 
     opt_index = parse_arguments (argc, argv, options, 1);
-    if (opt_index < 0)
-       return EXIT_FAILURE;
+    if (opt_index < 0) {
+       ret = EXIT_FAILURE;
+       goto DONE;
+    }
+
+    name_for_error = input_file_name ? input_file_name : "stdin";
 
     if (! accumulate)
        flags |= TAG_FLAG_REMOVE_ALL;
 
+    errno = 0;
     if (input_file_name)
        input = gzopen (input_file_name, "r");
     else {
        int infd = dup (STDIN_FILENO);
        if (infd < 0) {
-           fprintf (stderr, "Error duping stdin\n");
-           return EXIT_FAILURE;
+           fprintf (stderr, "Error duping stdin: %s\n",
+                    strerror (errno));
+           ret = EXIT_FAILURE;
+           goto DONE;
        }
        input = gzdopen (infd, "r");
        if (! input)
@@ -178,19 +186,22 @@ notmuch_restore_command (notmuch_config_t *config, int 
argc, char *argv[])
 
     if (input == NULL) {
        fprintf (stderr, "Error opening %s for (gzip) reading: %s\n",
-                input_file_name ? input_file_name : "stdin", strerror (errno));
-       return EXIT_FAILURE;
+                name_for_error, strerror (errno));
+       ret = EXIT_FAILURE;
+       goto DONE;
     }
 
     if (opt_index < argc) {
        fprintf (stderr, "Unused positional parameter: %s\n", argv[opt_index]);
-       return EXIT_FAILURE;
+       ret = EXIT_FAILURE;
+       goto DONE;
     }
 
     tag_ops = tag_op_list_create (config);
     if (tag_ops == NULL) {
        fprintf (stderr, "Out of memory.\n");
-       return EXIT_FAILURE;
+       ret = EXIT_FAILURE;
+       goto DONE;
     }
 
     do {
@@ -199,12 +210,17 @@ notmuch_restore_command (notmuch_config_t *config, int 
argc, char *argv[])
        status = gz_getline (line_ctx, &line, &line_len, input);
 
        /* empty input file not considered an error */
-       if (status == UTIL_EOF)
-           return EXIT_SUCCESS;
-
-       if (status)
-           return EXIT_FAILURE;
+       if (status == UTIL_EOF) {
+           ret = EXIT_SUCCESS;
+           goto DONE;
+       }
 
+       if (status) {
+           fprintf (stderr, "Error reading (gzipped) input: %s\n",
+                    gz_error_string(status, input));
+           ret = EXIT_FAILURE;
+           goto DONE;
+       }
     } while ((line_len == 0) ||
             (line[0] == '#') ||
             /* the cast is safe because we checked about for line_len < 0 */
@@ -269,17 +285,37 @@ notmuch_restore_command (notmuch_config_t *config, int 
argc, char *argv[])
        if (ret)
            break;
 
-    }  while (gz_getline (line_ctx, &line, &line_len, input) == UTIL_SUCCESS);
+    }  while (! (ret = gz_getline (line_ctx, &line, &line_len, input)));
+    
 
-    if (line_ctx != NULL)
-       talloc_free (line_ctx);
+    /* EOF is normal loop termination condition, UTIL_SUCCESS is
+     * impossible here */
+    if (ret == UTIL_EOF) {
+       ret = UTIL_SUCCESS;
+    } else {
+       fprintf (stderr, "Error reading (gzipped) input: %s\n",
+                gz_error_string (ret, input));
+    }
+
+    /* currently this should not be after DONE: since we don't 
+     * know if the xregcomp was reached
+     */
 
     if (input_format == DUMP_FORMAT_SUP)
        regfree (&regex);
 
-    notmuch_database_destroy (notmuch);
+ DONE:
+    if (line_ctx != NULL)
+       talloc_free (line_ctx);
 
-    gzclose_r (input);
+    if (notmuch)
+       notmuch_database_destroy (notmuch);
+
+    if (input && gzclose_r (input)) {
+       fprintf (stderr, "Error closing %s: %s\n",
+                name_for_error, gzerror (input, NULL));
+       ret = EXIT_FAILURE;
+    }
 
     return ret ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff --git a/util/Makefile.local b/util/Makefile.local
index e2a5b65..905f237 100644
--- a/util/Makefile.local
+++ b/util/Makefile.local
@@ -4,7 +4,8 @@ dir := util
 extra_cflags += -I$(srcdir)/$(dir)
 
 libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \
-                 $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c
+                 $(dir)/string-util.c $(dir)/talloc-extra.c 
$(dir)/zlib-extra.c \
+               $(dir)/util.c
 
 libutil_modules := $(libutil_c_srcs:.c=.o)
 
diff --git a/util/util.c b/util/util.c
new file mode 100644
index 0000000..3bd305d
--- /dev/null
+++ b/util/util.c
@@ -0,0 +1,24 @@
+#include "util.h"
+#include "error_util.h"
+#include <string.h>
+#include <errno.h>
+
+const char *
+util_error_string (util_status_t errnum)
+{
+    switch (errnum) {
+    case UTIL_SUCCESS:
+       return "none";
+    case UTIL_OUT_OF_MEMORY:
+       return "out of memory";
+    case UTIL_EOF:
+       return "end of file";
+    case UTIL_ERRNO:
+       return strerror (errno);
+    case UTIL_GZERROR:
+       /* we lack context to be more informative here */
+       return "zlib error";
+    default:
+       INTERNAL_ERROR("unexpected error status %d", errnum);
+    }
+}
diff --git a/util/util.h b/util/util.h
index 8663cfc..d12fadb 100644
--- a/util/util.h
+++ b/util/util.h
@@ -2,11 +2,28 @@
 #define _UTIL_H
 
 typedef enum util_status {
+    /**
+     * No error occurred.
+     */
     UTIL_SUCCESS = 0,
-    UTIL_ERROR = 1,
+    /**
+     * Out of memory.
+     */
     UTIL_OUT_OF_MEMORY,
+    /**
+     * End of stream reached while attempting to read.
+     */
     UTIL_EOF,
-    UTIL_FILE,
+    /**
+     * Low level error occured, consult errno.
+     */
+    UTIL_ERRNO,
+    /**
+     * Zlib error occured, call gzerror for details.
+     */
+    UTIL_GZERROR
 } util_status_t;
 
+const char *
+util_error_string (util_status_t status);
 #endif
diff --git a/util/zlib-extra.c b/util/zlib-extra.c
index 922ab52..cb34845 100644
--- a/util/zlib-extra.c
+++ b/util/zlib-extra.c
@@ -54,9 +54,9 @@ gz_getline (void *talloc_ctx, char **bufptr, ssize_t 
*bytes_read, gzFile stream)
                else
                    goto SUCCESS;
            case Z_ERRNO:
-               return UTIL_FILE;
+               return UTIL_ERRNO;
            default:
-               return UTIL_ERROR;
+               return UTIL_GZERROR;
            }
        }
 
@@ -75,3 +75,11 @@ gz_getline (void *talloc_ctx, char **bufptr, ssize_t 
*bytes_read, gzFile stream)
     *bytes_read = offset;
     return UTIL_SUCCESS;
 }
+
+const char *gz_error_string (util_status_t status, gzFile file) 
+{
+    if (status == UTIL_GZERROR)
+       return gzerror (file, NULL);
+    else
+       return util_error_string (status);
+}
diff --git a/util/zlib-extra.h b/util/zlib-extra.h
index ed67115..dbaa0b9 100644
--- a/util/zlib-extra.h
+++ b/util/zlib-extra.h
@@ -4,8 +4,22 @@
 #include "util.h"
 #include <zlib.h>
 
-/* Like getline, but read from a gzFile. Allocation is with talloc */
+/* Like getline, but read from a gzFile. Allocation is with talloc.
+ * Returns:
+ *
+ *   UTIL_SUCCESS, UTIL_OUT_OF_MEMORY, UTIL_ERRNO, UTIL_GZERROR
+ *                     Consult util.h for description
+ *
+ *   UTIL_EOF          End of file encountered before 
+ *                     any characters read
+ */
 util_status_t
 gz_getline (void *ctx, char **lineptr, ssize_t *bytes_read, gzFile stream);
 
+/* return a suitable error string based on the return status
+ *  from gz_readline
+ */
+
+const char *
+gz_error_string (util_status_t status, gzFile stream);
 #endif
_______________________________________________
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch

Reply via email to