Commit 4e04812d by Jonathan Wakely Committed by Jonathan Wakely

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
parent 2e721daa
2016-10-22 Jonathan Wakely <jwakely@redhat.com>
* 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.
2016-10-21 Jonathan Wakely <jwakely@redhat.com> 2016-10-21 Jonathan Wakely <jwakely@redhat.com>
* include/experimental/bits/fs_fwd.h (perms::resolve_symlinks): * include/experimental/bits/fs_fwd.h (perms::resolve_symlinks):
......
...@@ -1097,7 +1097,8 @@ fs::permissions(const path& p, perms prms) ...@@ -1097,7 +1097,8 @@ fs::permissions(const path& p, perms prms)
_GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot set permissions", p, ec)); _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 add = is_set(prms, perms::add_perms);
const bool remove = is_set(prms, perms::remove_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 ...@@ -1110,27 +1111,33 @@ void fs::permissions(const path& p, perms prms, error_code& ec) noexcept
prms &= perms::mask; 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) if (ec)
return; return;
auto curr = st.permissions(); auto curr = st.permissions();
if (add) if (add)
prms |= curr; prms |= curr;
else else if (remove)
prms = curr & ~prms; prms = curr & ~prms;
} }
int err = 0;
#if _GLIBCXX_USE_FCHMODAT #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)) if (::fchmodat(AT_FDCWD, p.c_str(), static_cast<mode_t>(prms), flag))
err = errno;
#else #else
if (nofollow) if (nofollow && is_symlink(st))
ec = std::make_error_code(std::errc::operation_not_supported); ec = std::make_error_code(std::errc::operation_not_supported);
else if (::chmod(p.c_str(), static_cast<mode_t>(prms))) else if (::chmod(p.c_str(), static_cast<mode_t>(prms)))
err = errno;
#endif #endif
ec.assign(errno, std::generic_category());
if (err)
ec.assign(err, std::generic_category());
else else
ec.clear(); ec.clear();
} }
......
...@@ -121,6 +121,26 @@ test04() ...@@ -121,6 +121,26 @@ test04()
remove(p); remove(p);
} }
void
test05()
{
using perms = std::experimental::filesystem::perms;
std::error_code ec;
__gnu_test::scoped_file f;
auto p = perms::owner_write;
// symlink_nofollow should not give an error for non-symlinks
permissions(f.path, p|perms::symlink_nofollow, ec);
VERIFY( !ec );
auto st = status(f.path);
VERIFY( st.permissions() == p );
p |= perms::owner_read;
permissions(f.path, p|perms::symlink_nofollow, ec);
st = status(f.path);
VERIFY( st.permissions() == p );
}
int int
main() main()
{ {
...@@ -128,4 +148,5 @@ main() ...@@ -128,4 +148,5 @@ main()
test02(); test02();
test03(); test03();
test04(); test04();
test05();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment