diff options
author | Dylan Simon <dylan@dylex.net> | 2014-03-18 11:50:29 -0400 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2014-03-19 02:33:44 +0000 |
commit | 09eda9ed9d386f3aa84bfff1699cc4cfcec8647e (patch) | |
tree | 5909449e495d5080b7999c2c6dd65ff7e6033271 /src | |
parent | 5b790fda0e3781746451031284ce9730d79c9a89 (diff) | |
download | coreutils-09eda9ed9d386f3aa84bfff1699cc4cfcec8647e.tar.xz |
chmod: fix erroneous warnings with -R --changes
For files with "special" bits set, we would stat the relative
file name in the wrong directory, giving an erroneous ENOENT diagnostic.
This issue was introduced with commit v5.92-653-gc1994c1
which changed fts to not change directory on traversal.
* src/chmod.c (mode_changed): Use fts->fts_cwd_fd with fstatat rather
than stat. All callers changed.
* tests/chmod/c-option.sh: Add a test case.
* NEWS: Mention the fix.
Fixes http://bugs.gnu.org/17035
Diffstat (limited to 'src')
-rw-r--r-- | src/chmod.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/src/chmod.c b/src/chmod.c index 81bf4b227..756ec5a46 100644 --- a/src/chmod.c +++ b/src/chmod.c @@ -111,7 +111,8 @@ static struct option const long_options[] = The old mode was OLD_MODE, but it was changed to NEW_MODE. */ static bool -mode_changed (char const *file, mode_t old_mode, mode_t new_mode) +mode_changed (int dir_fd, char const *file, char const *file_full_name, + mode_t old_mode, mode_t new_mode) { if (new_mode & (S_ISUID | S_ISGID | S_ISVTX)) { @@ -120,10 +121,11 @@ mode_changed (char const *file, mode_t old_mode, mode_t new_mode) struct stat new_stats; - if (stat (file, &new_stats) != 0) + if (fstatat (dir_fd, file, &new_stats, 0) != 0) { if (! force_silent) - error (0, errno, _("getting new attributes of %s"), quote (file)); + error (0, errno, _("getting new attributes of %s"), + quote (file_full_name)); return false; } @@ -283,7 +285,8 @@ process_file (FTS *fts, FTSENT *ent) if (verbosity != V_off) { bool changed = (chmod_succeeded - && mode_changed (file, old_mode, new_mode)); + && mode_changed (fts->fts_cwd_fd, file, file_full_name, + old_mode, new_mode)); if (changed || verbosity == V_high) { |