os: refactor to use os.stat and os.lstat instead of unsafe C calls (#20759)

This commit is contained in:
syrmel 2024-02-08 18:27:49 +01:00 committed by GitHub
parent 3c0257af1b
commit 410bd9db71
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 139 additions and 223 deletions

View file

@ -60,75 +60,16 @@ pub fn (m FileMode) bitmask() u32 {
// inode returns the metadata of the file/inode, containing inode type, permission information, size and modification time.
// it supports windows for regular files, but it doesn't matter if you use owner, group or others when checking permissions on windows.
// if a symlink is targetted, it returns info on the link, not the target
pub fn inode(path string) FileInfo {
mut attr := C.stat{}
$if windows {
// TODO: replace this with a C.GetFileAttributesW call instead.
// Use stat, lstat is not available on windows
unsafe { C.stat(&char(path.str), &attr) }
mut typ := FileType.regular
if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFDIR) {
typ = .directory
}
return FileInfo{
typ: typ
size: attr.st_size
mtime: attr.st_mtime
owner: FilePermission{
read: (attr.st_mode & u32(C.S_IREAD)) != 0
write: (attr.st_mode & u32(C.S_IWRITE)) != 0
execute: (attr.st_mode & u32(C.S_IEXEC)) != 0
}
group: FilePermission{
read: (attr.st_mode & u32(C.S_IREAD)) != 0
write: (attr.st_mode & u32(C.S_IWRITE)) != 0
execute: (attr.st_mode & u32(C.S_IEXEC)) != 0
}
others: FilePermission{
read: (attr.st_mode & u32(C.S_IREAD)) != 0
write: (attr.st_mode & u32(C.S_IWRITE)) != 0
execute: (attr.st_mode & u32(C.S_IEXEC)) != 0
}
}
} $else {
// note, that we use lstat here on purpose, to know the information about
// the potential symlinks themselves, not about the entities they point at
unsafe { C.lstat(&char(path.str), &attr) }
mut typ := FileType.unknown
if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFREG) {
typ = .regular
} else if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFDIR) {
typ = .directory
} else if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFCHR) {
typ = .character_device
} else if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFBLK) {
typ = .block_device
} else if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFIFO) {
typ = .fifo
} else if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFLNK) {
typ = .symbolic_link
} else if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFSOCK) {
typ = .socket
}
return FileInfo{
typ: typ
size: attr.st_size
mtime: attr.st_mtime
owner: FilePermission{
read: (attr.st_mode & u32(C.S_IRUSR)) != 0
write: (attr.st_mode & u32(C.S_IWUSR)) != 0
execute: (attr.st_mode & u32(C.S_IXUSR)) != 0
}
group: FilePermission{
read: (attr.st_mode & u32(C.S_IRGRP)) != 0
write: (attr.st_mode & u32(C.S_IWGRP)) != 0
execute: (attr.st_mode & u32(C.S_IXGRP)) != 0
}
others: FilePermission{
read: (attr.st_mode & u32(C.S_IROTH)) != 0
write: (attr.st_mode & u32(C.S_IWOTH)) != 0
execute: (attr.st_mode & u32(C.S_IXOTH)) != 0
}
}
attr := lstat(path) or { Stat{} }
fm := attr.get_mode()
return FileInfo{
typ: fm.typ
owner: fm.owner
group: fm.group
others: fm.others
size: attr.size
mtime: attr.mtime
}
}