Files
TransPyC/includes/os/_posix.py
2026-07-18 19:25:40 +08:00

191 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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。
默认权限 0o755rwxr-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)