Change:
When using the Permissions module on MacOS it doesn't behave as expected. Readonly returns if the file lacks any write bits, rather than returning if the current calling uid/gid can write to the file. This can be seen in the code: This is a bit misleading because the framing of seems to say "an unwritable file" without context which to me I interpretted as "unwritable file - by the current user" not unwriteable by all permission bits. I'd be happy with a disclaimer on the documentation of readonly to indicate this only checks that no write bits exist on unix so that it's clearer what it's checking for, but I'd also be happy if this function was altered to check 'is it readonly in the current calling context' but I understand that's a really challenging problem in-itself given posix acls etc. I expected to see this happen: A file as should be readonly == true when called from "william:william" Instead, this happened: The file is listed as "not" readonly even though the current user can not write the file OR the documentation about what readonly() does clearly explains what it is looking for on each operating system. Thanks!
does not (and cannot) perform any I/O operation to determine if the file is actually readable. It can only peek into the platform-specific permission representation (which is the "777" format on Unix). It also does not encode any information about owner user or group, so it couldn't even check if you are the current user/group. I think the usage of name "read-only" is pretty clear that it implies nobody could write to it, not that the current user cannot write to it (as in read-only file system), but we could possibly improve the documentation to make it clearer. modify labels: +T-doc +C-enhancement -C-bug
Yep that's fine, it's pretty complex to work out if something really is readonly especially with ACLs having deny rules etc.... I think it's currently not clear because I interpreted this as "read-only to the calling users context" so making the documentation explicit in what occurs behind the scenes would be good.
But the doc does not mention about user at all? is retrieved from , which describes the nature about a file itself rather than how it can be interacted with.
I ran into this issue too. It's definitely not clear that will be if any user/group/other write bit is set. As said that's just wrong, so it should at least be documented. Even accounting for the fact that it can't easily check if you are in the relevant group, sometimes having group membership and group write permission is not enough. E.g. to delete a file you need user write permission. It's actually a bit worse than that - the implementation is weird too: If you a file you actually make it world-writable! Probably not what was intended. It may be too late to change these and honestly it's not clear how you would even fix them (I would say probably ignore the group/other bits). But either way we should definitely add a note saying that these functions almost certainly do not do what you want on Unix, and you should use instead. I would go so far as to say they should be deprecated on Unix.
Just hit this issue. Needed to check if a file was writeable (equivalent of in shell) and assumed readonly would do what I wanted. Fortunately Google put this issue as the second result. Would also be nice for the readonly docs to include an example of how to actually check "can I write to this file?"
The issue on unix systems is posix acls, so you can't actually check very easily :(
Yeah I have now run into that. I ended up with this, no idea if it's correct:
If you are only targeting POSIX, then you should be using the function from libc.
I would also like this documented, because I (naively) expected this to work for determining whether the current user can write to the file.
Jinx!
I'm happy to merge our PR's or close mine in favour of yours, what do you prefer :)
I'll merge some of yours into mine if that's ok? I think your change is clearer that a) it's Unix-like that it applies to so it includes Mac, and b) the only applies to the in-memory setting.
Sounds great to me :)

Discussion:
impl Permissions { /// Returns `true` if these permissions describe a readonly (unwritable) file. /// <ins> /// # Note /// /// This function does not take Access Control Lists (ACLs) or Unix group /// membership into account. /// /// # Windows /// /// On Windows this returns [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants). /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail /// but the user may still have permission to change this flag. If /// `FILE_ATTRIBUTE_READONLY` is *not* set then writes may still fail due /// to lack of write permission. /// The behavior of this attribute for directories depends on the Windows /// version. /// /// # Unix (including macOS) /// /// On Unix-based platforms this checks if *any* of the owner, group or others /// write permission bits are set. It does not check if the current /// user is in the file's assigned group. It also does not check ACLs. /// Therefore even if this returns true you may not be able to write to the /// file, and vice versa. The [`PermissionsExt`] trait gives direct access /// to the permission bits but also does not read ACLs. If you need to /// accurately know whether or not a file is writable use the `access()` /// function from libc. /// /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt /// </ins> /// # Examples /// /// ```no_run

/// using the resulting `Permission` will update file permissions to allow /// writing. /// <del> /// This operation does **not** modify the filesystem. To modify the /// filesystem use the [`set_permissions`] function. </del> <ins> /// This operation does **not** modify the files attributes. This only /// changes the in-memory value of these attributes for this `Permissions` /// instance. To modify the files attributes use the [`set_permissions`] /// function which commits these attribute changes to the file. /// /// # Note /// /// `set_readonly(false)` makes the file *world-writable* on Unix. /// You can use the [`PermissionsExt`] trait on Unix to avoid this issue. /// /// It also does not take Access Control Lists (ACLs) or Unix group /// membership into account. /// /// # Windows /// /// On Windows this sets or clears [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants). /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail /// but the user may still have permission to change this flag. If /// `FILE_ATTRIBUTE_READONLY` is *not* set then the write may still fail if /// the user does not have permission to write to the file. /// /// In Windows 7 and earlier this attribute prevents deleting empty /// directories. It does not prevent modifying the directory contents. /// On later versions of Windows this attribute is ignored for directories. /// /// # Unix (including macOS) /// /// On Unix-based platforms this sets or clears the write access bit for /// the owner, group *and* others, equivalent to `chmod a+w <file>` /// or `chmod a-w <file>` respectively. The latter will grant write access /// to all users! You can use the [`PermissionsExt`] trait on Unix /// to avoid this issue. /// /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt </ins> /// /// # Examples ///

/// ///     permissions.set_readonly(true); /// <del> ///     // filesystem doesn't change </del> <ins> ///     // filesystem doesn't change, only the in memory state of the ///     // readonly permission </ins> ///     assert_eq!(false, metadata.permissions().readonly()); /// ///     // just this particular `permissions`.