summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-06 15:50:01 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-06-06 15:50:01 +0000
commitbab71865ec13fff8dc212e6e538abe3cde7de6e8 (patch)
treeb15bf139bf144af8c5e2d5e8f92998649060292b /libstdc++-v3/src
parent5d4123dccd2a24383e09a0d08bb9ea11e849b14b (diff)
downloadgcc-bab71865ec13fff8dc212e6e538abe3cde7de6e8.tar.gz
libstdc++/71320 Add or remove file permissions correctly
PR libstdc++/71320 * src/filesystem/ops.cc (permissions(const path&, perms, error_code&)): Add or remove permissions according to perms argument. * testsuite/experimental/filesystem/operations/permissions.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237136 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc22
1 files changed, 22 insertions, 0 deletions
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 5b82088891e..67ed8e6e564 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -1084,6 +1084,28 @@ fs::permissions(const path& p, perms prms)
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);
+ if (add && remove)
+ {
+ ec = std::make_error_code(std::errc::invalid_argument);
+ return;
+ }
+
+ prms &= perms::mask;
+
+ if (add || remove)
+ {
+ auto st = status(p, ec);
+ if (ec)
+ return;
+ auto curr = st.permissions();
+ if (add)
+ prms |= curr;
+ else
+ prms = curr & ~prms;
+ }
+
#if _GLIBCXX_USE_FCHMODAT
if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), 0))
#else