Rollup merge of #152995 - asder8215:windows_permissions_ext, r=Mark-Simulacrum

ACP Implementation of PermissionsExt for Windows

This PR implements the `PermissionsExt` for Windows ACP and adds file attribute methods in `FilePermissions` struct (to be decided whether we use them or not). See this [tracking issue](https://github.com/rust-lang/rust/issues/152956#event-22976637690) for further detail and links.

I also added some comments in the code for clarifications about the ACP (e.g. whether we should have a `set_file_attributes()` + `from_file_attributes()` method to mirror what unix's `PermissionsExt` is doing).

Also, some relevant links on this:
* [File Attribute Constants](https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants)
* [`attrib` command](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/attrib)
* [SetFileAttributesA](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileattributesa)
* [GetFileAttributesA](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfileattributesa)
* [Window's File Attributes Column Values](https://superuser.com/questions/44812/windows-explorers-file-attribute-column-values)
* [What is the 'M' attribute in Windows file system for?](https://superuser.com/questions/1621649/what-is-the-m-attribute-in-windows-file-system-for)

Note: Apologies for the multiple forced push. I haven't set up my Windows VM up yet to compile and check the code, so I've been using the CI to help me with that.

r? @ChrisDenton
This commit is contained in:
Jonathan Brouwer
2026-04-26 19:06:23 +02:00
committed by GitHub
2 changed files with 74 additions and 2 deletions
+64 -2
View File
@@ -4,11 +4,11 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::fs::{self, Metadata, OpenOptions};
use crate::fs::{self, Metadata, OpenOptions, Permissions};
use crate::io::BorrowedCursor;
use crate::path::Path;
use crate::sealed::Sealed;
use crate::sys::{AsInner, AsInnerMut, IntoInner};
use crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner};
use crate::time::SystemTime;
use crate::{io, sys};
@@ -368,6 +368,68 @@ fn freeze_last_write_time(&mut self, freeze: bool) -> &mut Self {
}
}
/// Windows-specific extensions to [`fs::Permissions`]. This extension trait
/// provides extra utilities to shows what Windows file attributes are enabled
/// in [`Permissions`] and to manually set file attributes on [`Permissions`].
///
/// See Microsoft's [`File Attribute Constants`] page to know what file
/// attribute metadata are defined and stored on Windows files.
///
/// [`Permissions`]: fs::Permissions
/// [`File Attribute Constants`]:
/// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
///
/// # Example
///
/// ```no_run
/// #![feature(windows_permissions_ext)]
/// use std::fs::Permissions;
/// use std::os::windows::fs::PermissionsExt;
///
/// const FILE_ATTRIBUTE_SYSTEM: u32 = 0x4;
/// const FILE_ATTRIBUTE_ARCHIVE: u32 = 0x20;
/// let my_file_attr = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE;
/// let mut permissions = Permissions::from_file_attributes(my_file_attr);
/// assert_eq!(permissions.file_attributes(), my_file_attr);
///
/// const FILE_ATTRIBUTE_HIDDEN: u32 = 0x2;
/// let new_file_attr = permissions.file_attributes() | FILE_ATTRIBUTE_HIDDEN;
/// permissions.set_file_attributes(new_file_attr);
/// assert_eq!(permissions.file_attributes(), new_file_attr);
/// ```
#[unstable(feature = "windows_permissions_ext", issue = "152956")]
pub trait PermissionsExt: Sealed {
/// Returns the file attribute bits.
#[unstable(feature = "windows_permissions_ext", issue = "152956")]
fn file_attributes(&self) -> u32;
/// Sets the file attribute bits.
#[unstable(feature = "windows_permissions_ext", issue = "152956")]
fn set_file_attributes(&mut self, mask: u32);
/// Creates a new instance from the given file attribute bits.
#[unstable(feature = "windows_permissions_ext", issue = "152956")]
fn from_file_attributes(mask: u32) -> Self;
}
#[unstable(feature = "windows_permissions_ext", issue = "152956")]
impl Sealed for fs::Permissions {}
#[unstable(feature = "windows_permissions_ext", issue = "152956")]
impl PermissionsExt for fs::Permissions {
fn file_attributes(&self) -> u32 {
self.as_inner().file_attributes()
}
fn set_file_attributes(&mut self, mask: u32) {
*self = Permissions::from_inner(FromInner::from_inner(mask));
}
fn from_file_attributes(mask: u32) -> Self {
Permissions::from_inner(FromInner::from_inner(mask))
}
}
/// Windows-specific extensions to [`fs::Metadata`].
///
/// The data members that this trait exposes correspond to the members
+10
View File
@@ -1167,6 +1167,16 @@ pub fn set_readonly(&mut self, readonly: bool) {
self.attrs &= !c::FILE_ATTRIBUTE_READONLY;
}
}
pub fn file_attributes(&self) -> u32 {
self.attrs as u32
}
}
impl FromInner<u32> for FilePermissions {
fn from_inner(attrs: u32) -> FilePermissions {
FilePermissions { attrs }
}
}
impl FileTimes {