]> git.notmuchmail.org Git - notmuch/blobdiff - notmuch-new.c
cli: clean up exit status code returned by the cli commands
[notmuch] / notmuch-new.c
index faa33f1fc505f13f06bfe0a0d69b711136ac8597..6a8b1b22bf067305f7c05c2eac4f1a232424db38 100644 (file)
@@ -323,6 +323,35 @@ add_files (notmuch_database_t *notmuch,
     }
     db_mtime = directory ? notmuch_directory_get_mtime (directory) : 0;
 
+    /* If the directory is unchanged from our last scan and has no
+     * sub-directories, then return without scanning it at all.  In
+     * some situations, skipping the scan can substantially reduce the
+     * cost of notmuch new, especially since the huge numbers of files
+     * in Maildirs make scans expensive, but all files live in leaf
+     * directories.
+     *
+     * To check for sub-directories, we borrow a trick from find,
+     * kpathsea, and many other UNIX tools: since a directory's link
+     * count is the number of sub-directories (specifically, their
+     * '..' entries) plus 2 (the link from the parent and the link for
+     * '.').  This check is safe even on weird file systems, since
+     * file systems that can't compute this will return 0 or 1.  This
+     * is safe even on *really* weird file systems like HFS+ that
+     * mistakenly return the total number of directory entries, since
+     * that only inflates the count beyond 2.
+     */
+    if (directory && fs_mtime == db_mtime && st.st_nlink == 2) {
+       /* There's one catch: pass 1 below considers symlinks to
+        * directories to be directories, but these don't increase the
+        * file system link count.  So, only bail early if the
+        * database agrees that there are no sub-directories. */
+       db_subdirs = notmuch_directory_get_child_directories (directory);
+       if (!notmuch_filenames_valid (db_subdirs))
+           goto DONE;
+       notmuch_filenames_destroy (db_subdirs);
+       db_subdirs = NULL;
+    }
+
     /* If the database knows about this directory, then we sort based
      * on strcmp to match the database sorting. Otherwise, we can do
      * inode-based sorting for faster filesystem operation. */
@@ -869,10 +898,8 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
     };
 
     opt_index = parse_arguments (argc, argv, options, 1);
-    if (opt_index < 0) {
-       /* diagnostics already printed */
-       return 1;
-    }
+    if (opt_index < 0)
+       return EXIT_FAILURE;
 
     add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);
     add_files_state.new_ignore = notmuch_config_get_new_ignore (config, &add_files_state.new_ignore_length);
@@ -882,7 +909,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
     if (!no_hooks) {
        ret = notmuch_run_hook (db_path, "pre-new");
        if (ret)
-           return ret;
+           return EXIT_FAILURE;
     }
 
     dot_notmuch_path = talloc_asprintf (config, "%s/%s", db_path, ".notmuch");
@@ -893,16 +920,16 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
        count = 0;
        count_files (db_path, &count, &add_files_state);
        if (interrupted)
-           return 1;
+           return EXIT_FAILURE;
 
        printf ("Found %d total files (that's not much mail).\n", count);
        if (notmuch_database_create (db_path, &notmuch))
-           return 1;
+           return EXIT_FAILURE;
        add_files_state.total_files = count;
     } else {
        if (notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE,
                                   &notmuch))
-           return 1;
+           return EXIT_FAILURE;
 
        if (notmuch_database_needs_upgrade (notmuch)) {
            printf ("Welcome to a new version of notmuch! Your database will now be upgraded.\n");
@@ -917,7 +944,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
     }
 
     if (notmuch == NULL)
-       return 1;
+       return EXIT_FAILURE;
 
     /* Setup our handler for SIGINT. We do this after having
      * potentially done a database upgrade we this interrupt handler
@@ -1043,5 +1070,5 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
     if (!no_hooks && !ret && !interrupted)
        ret = notmuch_run_hook (db_path, "post-new");
 
-    return ret || interrupted;
+    return ret || interrupted ? EXIT_FAILURE : EXIT_SUCCESS;
 }