os: use underscore-prefixed stat macros on Windows for portability (#31060) (#31189)

* os: use underscore-prefixed stat macros on Windows for portability (#31060)

* os: use portable V constants for Windows stat mode bits

---------

Co-authored-by: Alexander Medvednikov <alexander@medvednikov.com>
This commit is contained in:
Mahdi ramezaan zaadeandAlexander Medvednikov authored and GitHub committed 2026-10-26 15:47:57 +03:00
1 parent 503b1dd017
commit 590ff0cbe2
3 files changed
+22 -22

No files matched your search

+14 -14
View File
@@ -139,12 +139,12 @@ fn windows_dangling_symlink_stat(path string) ?Stat {
}
fn windows_stat_from_find_data(path string, find_data Win32finddata) Stat {
mut mode := u32(C.S_IFREG) | u32(C.S_IREAD)
mut mode := u32(s_ifreg) | u32(s_irusr)
if find_data.dw_file_attributes & u32(C.FILE_ATTRIBUTE_READONLY) == 0 {
mode |= u32(C.S_IWRITE)
mode |= u32(s_iwusr)
}
match file_ext(path).to_lower() {
'.exe', '.com', '.bat', '.cmd' { mode |= u32(C.S_IEXEC) }
'.exe', '.com', '.bat', '.cmd' { mode |= u32(s_ixusr) }
else {}
}
return Stat{
@@ -167,8 +167,8 @@ fn windows_filetime_to_unix_seconds(filetime Filetime) i64 {
// get_filetype returns the FileType from the Stat struct.
pub fn (st Stat) get_filetype() FileType {
match st.mode & u32(C.S_IFMT) {
u32(C.S_IFDIR) {
match st.mode & u32(s_ifmt) {
u32(s_ifdir) {
return .directory
}
else {
@@ -183,19 +183,19 @@ pub fn (st Stat) get_mode() FileMode {
return FileMode{
typ: st.get_filetype()
owner: FilePermission{
read: (st.mode & u32(C.S_IREAD)) != 0
write: (st.mode & u32(C.S_IWRITE)) != 0
execute: (st.mode & u32(C.S_IEXEC)) != 0
read: (st.mode & u32(s_irusr)) != 0
write: (st.mode & u32(s_iwusr)) != 0
execute: (st.mode & u32(s_ixusr)) != 0
}
group: FilePermission{
read: (st.mode & u32(C.S_IREAD)) != 0
write: (st.mode & u32(C.S_IWRITE)) != 0
execute: (st.mode & u32(C.S_IEXEC)) != 0
read: (st.mode & u32(s_irusr)) != 0
write: (st.mode & u32(s_iwusr)) != 0
execute: (st.mode & u32(s_ixusr)) != 0
}
others: FilePermission{
read: (st.mode & u32(C.S_IREAD)) != 0
write: (st.mode & u32(C.S_IWRITE)) != 0
execute: (st.mode & u32(C.S_IEXEC)) != 0
read: (st.mode & u32(s_irusr)) != 0
write: (st.mode & u32(s_iwusr)) != 0
execute: (st.mode & u32(s_ixusr)) != 0
}
}
}
+7 -7
View File
@@ -36,9 +36,9 @@ fn test_windows_stat_from_find_data() {
assert link_stat.get_filetype() == .regular
assert link_stat.nlink == 1
assert link_stat.mode & u32(C.S_IREAD) != 0
assert link_stat.mode & u32(C.S_IWRITE) != 0
assert link_stat.mode & u32(C.S_IEXEC) != 0
assert link_stat.mode & u32(s_irusr) != 0
assert link_stat.mode & u32(s_iwusr) != 0
assert link_stat.mode & u32(s_ixusr) != 0
assert link_stat.size == (u64(1) << 32) | 7
assert link_stat.atime == -1
assert link_stat.mtime == 0
@@ -46,15 +46,15 @@ fn test_windows_stat_from_find_data() {
for extension in ['EXE', 'COM', 'BAT', 'CMD'] {
executable_stat := windows_stat_from_find_data('dangling.${extension}', find_data)
assert executable_stat.mode & u32(C.S_IEXEC) != 0
assert executable_stat.mode & u32(s_ixusr) != 0
}
mut read_only_data := find_data
read_only_data.dw_file_attributes = u32(C.FILE_ATTRIBUTE_READONLY)
read_only_stat := windows_stat_from_find_data('dangling.TXT', read_only_data)
assert read_only_stat.mode & u32(C.S_IREAD) != 0
assert read_only_stat.mode & u32(C.S_IWRITE) == 0
assert read_only_stat.mode & u32(C.S_IEXEC) == 0
assert read_only_stat.mode & u32(s_irusr) != 0
assert read_only_stat.mode & u32(s_iwusr) == 0
assert read_only_stat.mode & u32(s_ixusr) == 0
}
fn test_windows_get_mode_maps_stat_bits_to_file_mode() {
+1 -1
View File
@@ -35,7 +35,7 @@ fn C._getpid() i32
// cmd.exe uses when two programs differ only by extension.
const executable_suffixes = ['.com', '.exe', '.bat', '.cmd', '']
// these consts are declared for parity with the nix version, their values are not used, except for -cross
// Windows CRT file type and permission bits, also exposed for parity with Unix.
const s_ifmt = 0xF000 // type of file
const s_ifdir = 0x4000 // directory
const s_ifreg = 0x8000 // regular file