aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-10-22 12:42:16 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-10-22 12:42:16 +0100
commit4e04812da209203a10fbb7197502dd5b8a00459c (patch)
tree918bd00e2ea5664a78f8c0c01380db76dcf2c198 /libstdc++-v3/src
parent2e721daadf386fce372229a407784ec21cf80e8a (diff)
downloadgcc-4e04812da209203a10fbb7197502dd5b8a00459c.zip
gcc-4e04812da209203a10fbb7197502dd5b8a00459c.tar.gz
gcc-4e04812da209203a10fbb7197502dd5b8a00459c.tar.bz2
Ignore perms::symlink_nofollow on non-symlinks
* src/filesystem/ops.cc (permissions(const path&, perms, error_code&)): Ignore symlink_nofollow flag if file is not a symlink. * testsuite/experimental/filesystem/operations/permissions.cc: Test symlink_nofollow on non-symlinks. From-SVN: r241438
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc21
1 files changed, 14 insertions, 7 deletions
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 68343a9..2286e22 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -1097,7 +1097,8 @@ fs::permissions(const path& p, perms prms)
_GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot set permissions", p, ec));
}
-void fs::permissions(const path& p, perms prms, error_code& ec) noexcept
+void
+fs::permissions(const path& p, perms prms, error_code& ec) noexcept
{
const bool add = is_set(prms, perms::add_perms);
const bool remove = is_set(prms, perms::remove_perms);
@@ -1110,27 +1111,33 @@ void fs::permissions(const path& p, perms prms, error_code& ec) noexcept
prms &= perms::mask;
- if (add || remove)
+ file_status st;
+ if (add || remove || nofollow)
{
- auto st = nofollow ? symlink_status(p, ec) : status(p, ec);
+ st = nofollow ? symlink_status(p, ec) : status(p, ec);
if (ec)
return;
auto curr = st.permissions();
if (add)
prms |= curr;
- else
+ else if (remove)
prms = curr & ~prms;
}
+ int err = 0;
#if _GLIBCXX_USE_FCHMODAT
- const int flag = nofollow ? AT_SYMLINK_NOFOLLOW : 0;
+ const int flag = (nofollow && is_symlink(st)) ? AT_SYMLINK_NOFOLLOW : 0;
if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), flag))
+ err = errno;
#else
- if (nofollow)
+ if (nofollow && is_symlink(st))
ec = std::make_error_code(std::errc::operation_not_supported);
else if (::chmod(p.c_str(), static_cast<mode_t>(prms)))
+ err = errno;
#endif
- ec.assign(errno, std::generic_category());
+
+ if (err)
+ ec.assign(err, std::generic_category());
else
ec.clear();
}