snapshot before regression test
This commit is contained in:
190
includes/os/_posix.py
Normal file
190
includes/os/_posix.py
Normal file
@@ -0,0 +1,190 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import posix
|
||||
import memhub
|
||||
import stdlib
|
||||
|
||||
|
||||
# POSIX 路径最大长度
|
||||
MAX_PATH_LEN: t.CDefine = 4096
|
||||
|
||||
# 模块级全局 MBuddy 指针(由用户在 main 中赋值初始化)
|
||||
_mbuddy: memhub.MemBuddy | t.CPtr
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 文件/目录属性查询
|
||||
# =============================================================================
|
||||
|
||||
def _stat(path: str) -> posix.Stat | t.CPtr:
|
||||
"""调用 stat 并返回 Stat 结构体指针。失败返回 None。
|
||||
注意:Stat 结构体通过 _mbuddy 分配,调用者负责释放。"""
|
||||
st: posix.Stat = posix.Stat()
|
||||
result: INT = posix.stat(path, t.CPtr(c.Addr(st)))
|
||||
if result != 0:
|
||||
return None
|
||||
return t.CPtr(c.Addr(st))
|
||||
|
||||
|
||||
def exists(path: str) -> bool:
|
||||
"""检查文件/目录是否存在"""
|
||||
result: INT = posix.access(path, posix.F_OK)
|
||||
if result == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def isdir(path: str) -> bool:
|
||||
"""检查路径是否为目录"""
|
||||
st: posix.Stat = posix.Stat()
|
||||
result: INT = posix.stat(path, t.CPtr(c.Addr(st)))
|
||||
if result != 0:
|
||||
return False
|
||||
if posix.S_ISDIR(st.st_mode):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def isfile(path: str) -> bool:
|
||||
"""检查路径是否为普通文件"""
|
||||
st: posix.Stat = posix.Stat()
|
||||
result: INT = posix.stat(path, t.CPtr(c.Addr(st)))
|
||||
if result != 0:
|
||||
return False
|
||||
if posix.S_ISREG(st.st_mode):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getsize(path: str) -> t.CInt64T:
|
||||
"""返回文件大小(字节)。失败返回 -1。"""
|
||||
st: posix.Stat = posix.Stat()
|
||||
result: INT = posix.stat(path, t.CPtr(c.Addr(st)))
|
||||
if result != 0:
|
||||
return -1
|
||||
return st.st_size
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 工作目录
|
||||
# =============================================================================
|
||||
|
||||
def getcwd_impl() -> str:
|
||||
"""返回当前工作目录(通过 _mbuddy 分配内存)"""
|
||||
buf: bytes = _mbuddy.alloc(MAX_PATH_LEN)
|
||||
if buf == None: return None
|
||||
result: CHARPTR = posix.getcwd(buf, MAX_PATH_LEN)
|
||||
if result == None:
|
||||
return None
|
||||
return str(buf)
|
||||
|
||||
|
||||
def chdir_impl(path: str) -> int:
|
||||
"""切换当前工作目录。成功返回 0,失败返回 -1。"""
|
||||
result: INT = posix.chdir(path)
|
||||
if result != 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 文件/目录操作
|
||||
# =============================================================================
|
||||
|
||||
def mkdir_impl(path: str) -> int:
|
||||
"""创建目录。成功返回 0,失败返回 -1。
|
||||
默认权限 0o755(rwxr-xr-x)。"""
|
||||
result: INT = posix.mkdir(path, 0o755)
|
||||
if result != 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
|
||||
def remove(path: str) -> int:
|
||||
"""删除文件。成功返回 0,失败返回 -1。"""
|
||||
result: INT = posix.unlink(path)
|
||||
if result != 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
|
||||
def rmdir_impl(path: str) -> int:
|
||||
"""删除空目录。成功返回 0,失败返回 -1。"""
|
||||
result: INT = posix.rmdir(path)
|
||||
if result != 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
|
||||
def rename_impl(old_path: str, new_path: str) -> int:
|
||||
"""重命名/移动文件或目录。成功返回 0,失败返回 -1。"""
|
||||
result: INT = posix.rename(old_path, new_path)
|
||||
if result != 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
|
||||
def chmod_impl(path: str, mode: int) -> int:
|
||||
"""修改文件权限。成功返回 0,失败返回 -1。
|
||||
mode 为 POSIX 权限位(如 0o755)。"""
|
||||
result: INT = posix.chmod(path, posix.mode_t(mode))
|
||||
if result != 0:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 目录列举(opendir / readdir / closedir)
|
||||
# =============================================================================
|
||||
|
||||
def listdir(path: str, out_names: str, max_count: ULONG) -> ULONG:
|
||||
"""列举目录下的文件/子目录名。
|
||||
out_names 为调用者提供的字符串指针数组(char**),每个元素指向一个文件名。
|
||||
文件名通过 _mbuddy 分配内存。
|
||||
max_count 为 out_names 数组最大容量。
|
||||
返回实际列举的条目数。失败返回 0。"""
|
||||
dirp: posix.DIR | t.CPtr = posix.opendir(path)
|
||||
if dirp == None:
|
||||
return 0
|
||||
|
||||
count: ULONG = 0
|
||||
while count < max_count:
|
||||
entry: posix.Dirent | t.CPtr = posix.readdir(dirp)
|
||||
if entry == None:
|
||||
break
|
||||
|
||||
# 读取 d_name 字段
|
||||
name: str = entry.d_name
|
||||
if name[0] == '.':
|
||||
if name[1] == 0:
|
||||
# "."
|
||||
continue
|
||||
if name[1] == '.' and name[2] == 0:
|
||||
# ".."
|
||||
continue
|
||||
|
||||
# 复制文件名到新分配的内存
|
||||
name_len: t.CSizeT = len(name)
|
||||
name_buf: bytes = _mbuddy.alloc(name_len + 1)
|
||||
if name_buf == None: break
|
||||
i: t.CSizeT = 0
|
||||
for ch in name:
|
||||
name_buf[i] = ch
|
||||
i += 1
|
||||
name_buf[name_len] = 0
|
||||
out_names[count] = str(name_buf)
|
||||
count += 1
|
||||
|
||||
posix.closedir(dirp)
|
||||
return count
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 命令执行
|
||||
# =============================================================================
|
||||
|
||||
def system_impl(cmd: str) -> int:
|
||||
"""执行命令行命令(通过 C 运行时 system())。
|
||||
命令输出直接到子进程的终端(继承父进程 stdout/stderr)。
|
||||
返回命令的退出码(0 表示成功)。"""
|
||||
return stdlib.system(cmd)
|
||||
Reference in New Issue
Block a user