summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--src/chmod.c13
-rw-r--r--src/chown-core.c13
3 files changed, 32 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 75405e18c..7d62c4d51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2006-09-20 Jim Meyering <jim@meyering.net>
+ Fix the 2006-09-18 bug differently.
+ * src/chmod.c: (process_file): Upon FTS_NS for a top-level file,
+ tell fts_read to stat the file again, in case it has become
+ accessible since the initial fts_open call.
+ * src/chown-core.c (change_file_owner): Likewise.
+
* src/chmod.c: Revert last change. There is a better way.
* src/chown-core.c: Likewise.
diff --git a/src/chmod.c b/src/chmod.c
index 29611366c..7858c0a66 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -193,6 +193,19 @@ process_file (FTS *fts, FTSENT *ent)
return true;
case FTS_NS:
+ /* For a top-level file or directory, this FTS_NS (stat failed)
+ indicator is determined at the time of the initial fts_open call.
+ With programs like chmod, chown, and chgrp, that modify
+ permissions, it is possible that the file in question is
+ accessible when control reaches this point. So, if this is
+ the first time we've seen the FTS_NS for this file, tell
+ fts_read to stat it "again". */
+ if (ent->fts_level == 0 && ent->fts_number == 0)
+ {
+ ent->fts_number = 1;
+ fts_set (fts, ent, FTS_AGAIN);
+ return true;
+ }
error (0, ent->fts_errno, _("cannot access %s"), quote (file_full_name));
ok = false;
break;
diff --git a/src/chown-core.c b/src/chown-core.c
index 39cb34d8b..dbd3e52d8 100644
--- a/src/chown-core.c
+++ b/src/chown-core.c
@@ -267,6 +267,19 @@ change_file_owner (FTS *fts, FTSENT *ent,
break;
case FTS_NS:
+ /* For a top-level file or directory, this FTS_NS (stat failed)
+ indicator is determined at the time of the initial fts_open call.
+ With programs like chmod, chown, and chgrp, that modify
+ permissions, it is possible that the file in question is
+ accessible when control reaches this point. So, if this is
+ the first time we've seen the FTS_NS for this file, tell
+ fts_read to stat it "again". */
+ if (ent->fts_level == 0 && ent->fts_number == 0)
+ {
+ ent->fts_number = 1;
+ fts_set (fts, ent, FTS_AGAIN);
+ return true;
+ }
error (0, ent->fts_errno, _("cannot access %s"), quote (file_full_name));
ok = false;
break;