summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2006-12-14 11:09:44 +0100
committerJim Meyering <jim@meyering.net>2006-12-14 11:14:25 +0100
commit24852bf5b5e7fd954f2e4d1d08d58575453b48b0 (patch)
tree84eb0a48a2ec2d2b9637fa4d1890f941e4d5e647 /src
parent56007809c35dc4c3d139662578741281e11d0e3b (diff)
downloadcoreutils-24852bf5b5e7fd954f2e4d1d08d58575453b48b0.tar.xz
* NEWS: --preserve-root now works with chgrp, chmod, and chown.
* src/chmod.c (process_file): Do honor the --preserve-root option. * src/chown-core.c (change_file_owner): Likewise, but here, also handle the case in which a traversal would go "through" a symlink to root. Reported by Matthew M. Boedicker * tests/chown/preserve-root: Test for the above. * tests/chown/Makefile.am (TESTS): Add preserve-root.
Diffstat (limited to 'src')
-rw-r--r--src/chmod.c4
-rw-r--r--src/chown-core.c24
2 files changed, 20 insertions, 8 deletions
diff --git a/src/chmod.c b/src/chmod.c
index 7858c0a66..028c882d0 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -228,6 +228,10 @@ process_file (FTS *fts, FTSENT *ent)
if (ok && ROOT_DEV_INO_CHECK (root_dev_ino, file_stats))
{
ROOT_DEV_INO_WARN (file_full_name);
+ /* Tell fts not to traverse into this hierarchy. */
+ fts_set (fts, ent, FTS_SKIP);
+ /* Ensure that we do not process "/" on the second visit. */
+ ent = fts_read (fts);
ok = false;
}
diff --git a/src/chown-core.c b/src/chown-core.c
index 69345ccf8..606db39ea 100644
--- a/src/chown-core.c
+++ b/src/chown-core.c
@@ -258,7 +258,19 @@ change_file_owner (FTS *fts, FTSENT *ent,
{
case FTS_D:
if (chopt->recurse)
- return true;
+ {
+ if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, ent->fts_statp))
+ {
+ /* This happens e.g., with "chown -R --preserve-root /". */
+ ROOT_DEV_INO_WARN (file_full_name);
+ /* Tell fts not to traverse into this hierarchy. */
+ fts_set (fts, ent, FTS_SKIP);
+ /* Ensure that we do not process "/" on the second visit. */
+ ent = fts_read (fts);
+ return false;
+ }
+ return true;
+ }
break;
case FTS_DP:
@@ -337,15 +349,11 @@ change_file_owner (FTS *fts, FTSENT *ent,
|| required_gid == file_stats->st_gid));
}
- if (do_chown
- /* With FTS_NOSTAT, file_stats is valid only for directories.
- Don't need to check for FTS_D, since it is handled above,
- and same for FTS_DNR, since then do_chown is false. */
- && (ent->fts_info == FTS_DP || ent->fts_info == FTS_DC)
- && ROOT_DEV_INO_CHECK (chopt->root_dev_ino, file_stats))
+ /* This happens when chown -LR --preserve-root encounters a symlink-to-/. */
+ if (ROOT_DEV_INO_CHECK (chopt->root_dev_ino, file_stats))
{
ROOT_DEV_INO_WARN (file_full_name);
- ok = do_chown = false;
+ return false;
}
if (do_chown)