Section: 22.214.171.124 [fs.op.permissions] Status: C++17 Submitter: Eric Fiselier Opened: 2016-05-28 Last modified: 2017-07-30
View all other issues in [fs.op.permissions].
View all issues with C++17 status.
Currently when adding or removing permissions the permissions(p, prms, [...]) function always determines the current permissions for a file p using status(p).permissions(). This means that it resolves symlinks even when perms::resolve_symlinks was not specified.I believe this is the incorrect behavior. Instead symlink_status(p).permissions() should be used unless perms::resolve_symlinks is specified.
Previous resolution [SUPERSEDED]:
This wording is relative to N4582.
In 126.96.36.199 [fs.op.permissions] change Table 150 — "Effects of permission bits" as indicated:
Table 150 — Effects of permission bits Bits present in prms Effective bits applied Neither add_perms nor remove_perms prms & perms::mask add_perms status(p).permissions() | (prms & perms::mask) remove_perms status(p).permissions() & (prms & perms::mask)
[2016-06, Oulu — Jonathan comments and provides alternative wording]
We agree there is an issue here, but I don't like the proposed resolution. If Eric's P/R is accepted then it changes the default behaviour (when users do not set the perms::resolve_symlinks bit) to modify the permissions of the symlink itself.I claim that modifying the permissions of a symlink (rather than what it points to) is not a sensible default. It is not supported by the POSIX chmod system call. To change permissions of a symlink with POSIX you must use the newer fchmodat function and the AT_SYMLINK_NOFOLLOW flag, see here. Changing permissions of a symlink is not possible using the GNU chmod util, see here:
"chmod never changes the permissions of symbolic links, since the chmod system call cannot change their permissions. This is not a problem since the permissions of symbolic links are never used."
BSD chmod does provide a switch to change a symlink's permissions, but it's not the default.I suggest that we should replace the filesystem::perms::resolve_symlinks enumerator with filesystem::perms::symlink_nofollow (paint the bikeshed!), so that the default is sensible, and the uncommon, useless alternative of changing the symlink itself requires setting a bit in the flags explicitly. resolve_symlinks is unused in the spec today, the only mention is its definition in Table 147.
There exists a slightly related issue, 2728.
Tuesday: Move to Ready. JW and Eric to implement and report back if problems found.
Friday: status to Immediate
This wording is relative to N4594.
Change Table 147 — "Enum class perms" as indicated:
Table 147 — Enum class perms Name Value
Definition or notes resolve_symlinks 0x40000 permissions() shall resolve symlinks
Edit 188.8.131.52 [fs.op.permissions]:
void permissions(const path& p, perms prms); void permissions(const path& p, perms prms, error_code& ec) noexcept;
-1- Requires: !((prms & perms::add_perms) != perms::none && (prms & perms::remove_perms) != perms::none).-2- Effects: Applies the effective permissions bits from prms to the file p resolves to, as if by POSIX fchmodat(). The effective permission bits are determined as specified in Table 150.
Change Table 150 — "Effects of permission bits" as indicated:
[Drafting note: Very recently the project editor had already fixed a typo in Table 150 editorially, the applied change effectively was:status(p).permissions() & (prms & perms::mask)
Table 150 — Effects of permission bits Bits present in prms Effective bits applied Neither add_perms nor remove_perms prms & perms::mask add_perms s tatus(p).permissions() | (prms & perms::mask) remove_perms s tatus(p).permissions() & (prms & perms::mask)