unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: Austin Clements <amdragon@MIT.EDU>
To: Vladimir.Marek@oracle.com
Cc: notmuch@notmuchmail.org, Vladimir Marek <vlmarek@volny.cz>
Subject: Re: [PATCH 2/4] dirent->d_type not available on Soalris
Date: Wed, 11 Apr 2012 15:36:09 -0400	[thread overview]
Message-ID: <20120411193609.GC13549@mit.edu> (raw)
In-Reply-To: <1333989127-21523-1-git-send-email-Vladimir.Marek@oracle.com>

Correct me if I'm mistaken, but d_name will only be a basename, so
your calls to stat will fail for files that are not in the current
directory.  I think in all of the situations you had to call stat, we
already construct the absolute path of the file (sometimes a little
later in the code, but it can easily be moved), so this should be easy
to fix.

Rather than sprinkling portability code throughout notmuch-new, it
seems like it would be simpler if this logic were wrapped in a
separate function.  For example, something along the (completely
untested) lines of,

static mode_t
dirent_type (const struct *entry, const char *abspath)
{
    struct stat statbuf;
#ifdef _DIRENT_HAVE_D_TYPE
    static const mode_t modes[] = {
	[DT_BLK]  = S_IFBLK,
	[DT_CHR]  = S_IFCHR,
	[DT_DIR]  = S_IFDIR,
	[DT_FIFO] = S_IFIFO,
	[DT_LNK]  = S_IFLNK,
	[DT_REG]  = S_IFREG,
	[DT_SOCK] = S_IFSOCK
    };
    if (entry->d_type >= 0 && entry->d_type < sizeof(modes)/sizeof(modes[0]) &&
	modes[entry->d_type])
	return modes[entry->d_type];
#endif

    if (stat(abspath, &statbuf) == -1)
	return -1;
    return statbuf.st_mode & S_IFMT;
}

This has the added benefit of correctly handling DT_UNKNOWN, which we
currently don't.

Instead of taking the absolute path of the file, this could take the
absolute path of the containing directory and construct the full path
from that and d_name; that would probably be a nicer interface, but it
would be redundant computation.

Quoth Vladimir.Marek@oracle.com on Apr 09 at  6:32 pm:
> From: Vladimir Marek <vlmarek@volny.cz>
> 
> The inspiration was taken from similar issue in mutt:
> http://does-not-exist.org/mail-archives/mutt-dev/msg11290.html
> 
> Signed-off-by: Vladimir Marek <vlmarek@volny.cz>
> ---
>  notmuch-new.c |   28 ++++++++++++++++++++++++++++
>  1 files changed, 28 insertions(+), 0 deletions(-)
> 
> diff --git a/notmuch-new.c b/notmuch-new.c
> index 4f13535..3d265bd 100644
> --- a/notmuch-new.c
> +++ b/notmuch-new.c
> @@ -21,6 +21,9 @@
>  #include "notmuch-client.h"
>  
>  #include <unistd.h>
> +#ifndef _DIRENT_HAVE_D_TYPE
> +#include <sys/types.h>
> +#endif
>  
>  typedef struct _filename_node {
>      char *filename;
> @@ -167,7 +170,14 @@ _entries_resemble_maildir (struct dirent **entries, int count)
>      int i, found = 0;
>  
>      for (i = 0; i < count; i++) {
> +#ifdef _DIRENT_HAVE_D_TYPE
>  	if (entries[i]->d_type != DT_DIR && entries[i]->d_type != DT_UNKNOWN)
> +#else
> +	struct stat statbuf;
> +	if (stat(entries[i]->d_name, &statbuf) == -1)
> +		continue;
> +	if (! S_ISDIR(statbuf.st_mode))
> +#endif
>  	    continue;
>  
>  	if (strcmp(entries[i]->d_name, "new") == 0 ||
> @@ -258,6 +268,9 @@ add_files_recursive (notmuch_database_t *notmuch,
>      struct stat st;
>      notmuch_bool_t is_maildir, new_directory;
>      const char **tag;
> +#ifndef _DIRENT_HAVE_D_TYPE
> +    struct stat statbuf;
> +#endif
>  
>      if (stat (path, &st)) {
>  	fprintf (stderr, "Error reading directory %s: %s\n",
> @@ -328,9 +341,16 @@ add_files_recursive (notmuch_database_t *notmuch,
>  	 * scandir results, then it might be a directory (and if not,
>  	 * then we'll stat and return immediately in the next level of
>  	 * recursion). */
> +#ifdef _DIRENT_HAVE_D_TYPE
>  	if (entry->d_type != DT_DIR &&
>  	    entry->d_type != DT_LNK &&
>  	    entry->d_type != DT_UNKNOWN)
> +#else
> +	if (stat(entry->d_name, &statbuf) == -1)
> +		continue;
> +	if (!(statbuf.st_mode & S_IFDIR) &&
> +	    !(statbuf.st_mode & S_IFLNK))
> +#endif
>  	{
>  	    continue;
>  	}
> @@ -427,7 +447,11 @@ add_files_recursive (notmuch_database_t *notmuch,
>  	 *
>  	 * In either case, a stat does the trick.
>  	 */
> +#ifdef _DIRENT_HAVE_D_TYPE
>  	if (entry->d_type == DT_LNK || entry->d_type == DT_UNKNOWN) {
> +#else
> +	if (stat(entry->d_name, &statbuf) == -1 || statbuf.st_mode & S_IFLNK) {
> +#endif
>  	    int err;
>  
>  	    next = talloc_asprintf (notmuch, "%s/%s", path, entry->d_name);
> @@ -443,7 +467,11 @@ add_files_recursive (notmuch_database_t *notmuch,
>  
>  	    if (! S_ISREG (st.st_mode))
>  		continue;
> +#ifdef _DIRENT_HAVE_D_TYPE
>  	} else if (entry->d_type != DT_REG) {
> +#else
> +	} else if (statbuf.st_mode & S_IFREG) {
> +#endif
>  	    continue;
>  	}
>  

  parent reply	other threads:[~2012-04-11 19:36 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-09 10:17 notmuch on Solaris Vladimir.Marek
2012-04-09 10:17 ` [PATCH 1/4] Make configure use /bin/bash instead of /bin/sh Vladimir.Marek
2012-04-09 11:10   ` Jani Nikula
2012-04-09 12:19     ` Vladimir Marek
2012-04-10 17:26       ` Tomi Ollila
2012-04-11  8:43         ` Vladimir Marek
2012-04-11 18:47           ` Tomi Ollila
2012-04-30 11:58   ` David Bremner
2012-04-30 12:09     ` Tomi Ollila
2012-04-09 10:17 ` [PATCH 2/4] dirent->d_type not available on Soalris Vladimir.Marek
2012-04-09 11:17   ` Jani Nikula
2012-04-09 15:12     ` Vladimir Marek
2012-04-09 15:46       ` Adam Wolfe Gordon
2012-04-09 16:32         ` Vladimir.Marek
2012-04-11 18:57           ` Tomi Ollila
2012-04-11 19:36           ` Austin Clements [this message]
2012-04-09 10:17 ` [PATCH 3/4] Private strsep implementation Vladimir.Marek
2012-10-15  5:05   ` Ethan Glasser-Camp
2012-04-09 10:17 ` [PATCH 4/4] Explicitly type void* pointers Vladimir.Marek
2012-04-09 11:04   ` Jani Nikula
2012-04-09 18:15     ` Vladimir Marek
2012-04-09 21:31       ` Jani Nikula
2012-04-10  6:53         ` Vladimir Marek
2012-04-11 21:11         ` Austin Clements
2012-04-12  8:02           ` Jani Nikula
2012-04-12 17:57             ` Austin Clements
2012-04-15 21:05   ` Jani Nikula

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://notmuchmail.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120411193609.GC13549@mit.edu \
    --to=amdragon@mit.edu \
    --cc=Vladimir.Marek@oracle.com \
    --cc=notmuch@notmuchmail.org \
    --cc=vlmarek@volny.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).