[notmuch] [PATCH] Solaris doesn't have 'struct dirent::d_type'

James Westby jw+debian at jameswestby.net
Sun Dec 20 10:02:47 PST 2009


From: Tomas Carnecky <tom at dbservice.com>

Use stat(2) instead.

Signed-off-by: Tomas Carnecky <tom at dbservice.com>
Signed-off-by: James Westby <jw+debian at jameswestby.net>
---

  The original patch duplicated asprintf and stat calls, rearraging
  the code means we don't need to.

  I have a concern about the duplicated stats in is_maildir, but they
  are not so easy to save. I ran a quick timing test (3931 files), dropping
  caches before each set:

    master:
      real  2m3.545s
      real  1m34.571s
      real  1m36.005s

    original patch:
      real  2m18.114s
      real  1m34.843s
      real  1m36.317s

    revised patch:
      real  2m5.890s
      real  1m36.387s
      real  1m36.453s

  This shoes there is little impact of the code, but given that it is
  around one percent we may want to make it conditional on platform
  and save the extra stat calls.

  Thanks,

  James

 notmuch-new.c |   46 ++++++++++++++++++++++++++--------------------
 1 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/notmuch-new.c b/notmuch-new.c
index 9d20616..c6f4963 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -90,12 +90,18 @@ static int ino_cmp(const struct dirent **a, const struct dirent **b)
  * Return 1 if the directory looks like a Maildir and 0 otherwise.
  */
 static int
-is_maildir (struct dirent **entries, int count)
+is_maildir (const char *path, struct dirent **entries, int count)
 {
     int i, found = 0;
 
     for (i = 0; i < count; i++) {
-	if (entries[i]->d_type != DT_DIR) continue;
+	char pbuf[PATH_MAX];
+        snprintf(pbuf, PATH_MAX, "%s/%s", path, entries[i]->d_name);
+
+	struct stat buf;
+	if (stat(pbuf, &buf) == -1 || !S_ISDIR(buf.st_mode))
+	    continue;
+
 	if (strcmp(entries[i]->d_name, "new") == 0 ||
 	    strcmp(entries[i]->d_name, "cur") == 0 ||
 	    strcmp(entries[i]->d_name, "tmp") == 0)
@@ -178,24 +184,6 @@ add_files_recursive (notmuch_database_t *notmuch,
 	/* If this directory hasn't been modified since the last
 	 * add_files, then we only need to look further for
 	 * sub-directories. */
-	if (path_mtime <= path_dbtime && entry->d_type == DT_REG)
-	    continue;
-
-	/* Ignore special directories to avoid infinite recursion.
-	 * Also ignore the .notmuch directory.
-	 */
-	/* XXX: Eventually we'll want more sophistication to let the
-	 * user specify files to be ignored. */
-	if (strcmp (entry->d_name, ".") == 0 ||
-	    strcmp (entry->d_name, "..") == 0 ||
-	    (entry->d_type == DT_DIR &&
-	     (strcmp (entry->d_name, "tmp") == 0) &&
-	     is_maildir (namelist, num_entries)) ||
-	    strcmp (entry->d_name, ".notmuch") ==0)
-	{
-	    continue;
-	}
-
 	next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
 
 	if (stat (next, st)) {
@@ -216,6 +204,24 @@ add_files_recursive (notmuch_database_t *notmuch,
 	    goto DONE;
 	}
 
+	if (path_mtime <= path_dbtime && S_ISREG(st->st_mode))
+	    continue;
+
+	/* Ignore special directories to avoid infinite recursion.
+	 * Also ignore the .notmuch directory.
+	 */
+	/* XXX: Eventually we'll want more sophistication to let the
+	 * user specify files to be ignored. */
+	if (strcmp (entry->d_name, ".") == 0 ||
+	    strcmp (entry->d_name, "..") == 0 ||
+	    (S_ISDIR(st->st_mode) &&
+	     (strcmp (entry->d_name, "tmp") == 0) &&
+	     is_maildir (path, namelist, num_entries)) ||
+	    strcmp (entry->d_name, ".notmuch") ==0)
+	{
+	    continue;
+	}
+
 	if (S_ISREG (st->st_mode)) {
 	    /* If the file hasn't been modified since the last
 	     * add_files, then we need not look at it. */
-- 
1.6.3.3



More information about the notmuch mailing list