diff options
author | Jim Meyering <jim@meyering.net> | 2006-12-14 11:09:44 +0100 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2006-12-14 11:14:25 +0100 |
commit | 24852bf5b5e7fd954f2e4d1d08d58575453b48b0 (patch) | |
tree | 84eb0a48a2ec2d2b9637fa4d1890f941e4d5e647 /src | |
parent | 56007809c35dc4c3d139662578741281e11d0e3b (diff) | |
download | coreutils-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.c | 4 | ||||
-rw-r--r-- | src/chown-core.c | 24 |
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) |