From ac2e29156d8aa91d12b5801d4da80b72f1a00a7a Mon Sep 17 00:00:00 2001 From: Martin von Gagern Date: Wed, 26 Aug 2009 11:20:02 +0200 Subject: [PATCH] Bug #27213: avoid failed assertions for non-executable directories. Addresses Savannah bug #27213 - https://savannah.gnu.org/bugs/?27213 This used to fail in recent releases: 1. mkdir -p foo/bar 2. chmod a-x foo 3. find foo 4. find foo -ls Now it will print error messages for the denied permission on foo, but will not abort completely, and in 3. will even print the name foo/bar, while it won't do so in 4., as the -ls predicate requires stat information. For now, 4. will print two identical error message. This should get fixed some day. --- find/ftsfind.c | 36 ++++++++++++++---------------------- find/util.c | 11 +++++++---- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/find/ftsfind.c b/find/ftsfind.c index 61f1079..a8efdda 100644 --- a/find/ftsfind.c +++ b/find/ftsfind.c @@ -446,27 +446,19 @@ consider_visiting(FTS *p, FTSENT *ent) } else if (ent->fts_info == FTS_NS) { - if (ent->fts_level == 0) - { - /* e.g., nonexistent starting point */ - error(0, ent->fts_errno, "%s", - safely_quote_err_filename(0, ent->fts_path)); - error_severity(1); /* remember problem */ - return; - } - else - { - /* The following if statement fixes Savannah bug #19605 - * (failure to diagnose a symbolic link loop) - */ - if (symlink_loop(ent->fts_accpath)) - { - error(0, ELOOP, "%s", - safely_quote_err_filename(0, ent->fts_path)); - error_severity(1); - return; - } - } + error(0, ent->fts_errno, "%s", + safely_quote_err_filename(0, ent->fts_path)); + error_severity(1); + /* Continue despite the error, as file name without stat info + * might be better than not even processing the file name. This + * can lead to repeated error messages later on, though, if a + * predicate requires stat information. + * + * Not printing an error message here would be even more wrong, + * though, as this could cause the contents of a directory to be + * silently ignored, as the directory wouldn't be identified as + * such. + */ } /* Cope with the usual cases. */ @@ -474,7 +466,7 @@ consider_visiting(FTS *p, FTSENT *ent) || ent->fts_info == FTS_NS /* e.g. symlink loop */) { assert (!state.have_stat); - assert (ent->fts_info == FTS_NSOK || state.type != 0); + assert (ent->fts_info == FTS_NSOK || state.type == 0); mode = state.type; } else diff --git a/find/util.c b/find/util.c index 4a0bb9b..0e5988f 100644 --- a/find/util.c +++ b/find/util.c @@ -214,6 +214,9 @@ get_statinfo (const char *pathname, const char *name, struct stat *p) { if (!options.ignore_readdir_race || (errno != ENOENT) ) { + /* FIXME: this error message might repeat the one from + * the FTS_NS case in consider_visiting. How to avoid this? + */ error (0, errno, "%s", safely_quote_err_filename(0, pathname)); state.exit_status = 1; @@ -270,6 +273,10 @@ get_info (const char *pathname, int result = get_statinfo(pathname, state.rel_pathname, p); if (result != 0) { + return -1; /* failure. */ + } + else + { /* Verify some postconditions. We can't check st_mode for non-zero-ness because of Savannah bug #16378 (which is that broken NFS servers can return st_mode==0). */ @@ -281,10 +288,6 @@ get_info (const char *pathname, { assert (p->st_ino); } - return -1; /* failure. */ - } - else - { return 0; /* success. */ } } -- 1.6.4