aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-10-21 18:01:05 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-10-21 18:01:05 +0100
commitd17f7088fbe9b7d159021d0442d174925df7b20d (patch)
tree8368472a50257c8a6a58991fb43b970d547507cc /libstdc++-v3/src
parent2be921271333c81ec9fcf71ba49110bf23971d09 (diff)
downloadgcc-d17f7088fbe9b7d159021d0442d174925df7b20d.zip
gcc-d17f7088fbe9b7d159021d0442d174925df7b20d.tar.gz
gcc-d17f7088fbe9b7d159021d0442d174925df7b20d.tar.bz2
LWG2720 implement filesystem::perms::symlink_nofollow
* include/experimental/bits/fs_fwd.h (perms::resolve_symlinks): Replace with symlink_nofollow (LWG 2720). * src/filesystem/ops.cc (permissions(const path&, perms, error_code&)): Handle symlink_nofollow. * testsuite/experimental/filesystem/operations/create_symlink.cc: New test. * testsuite/experimental/filesystem/operations/permissions.cc: Test overload taking error_code. From-SVN: r241418
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc10
1 files changed, 7 insertions, 3 deletions
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 6b38584..68343a9 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -1101,6 +1101,7 @@ 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);
+ const bool nofollow = is_set(prms, perms::symlink_nofollow);
if (add && remove)
{
ec = std::make_error_code(std::errc::invalid_argument);
@@ -1111,7 +1112,7 @@ void fs::permissions(const path& p, perms prms, error_code& ec) noexcept
if (add || remove)
{
- auto st = status(p, ec);
+ auto st = nofollow ? symlink_status(p, ec) : status(p, ec);
if (ec)
return;
auto curr = st.permissions();
@@ -1122,9 +1123,12 @@ void fs::permissions(const path& p, perms prms, error_code& ec) noexcept
}
#if _GLIBCXX_USE_FCHMODAT
- if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), 0))
+ const int flag = nofollow ? AT_SYMLINK_NOFOLLOW : 0;
+ if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), flag))
#else
- if (::chmod(p.c_str(), static_cast<mode_t>(prms)))
+ if (nofollow)
+ ec = std::make_error_code(std::errc::operation_not_supported);
+ else if (::chmod(p.c_str(), static_cast<mode_t>(prms)))
#endif
ec.assign(errno, std::generic_category());
else