""" Android System 组件 — Os, StructStat, StructUtsname, OsConstants 等 方法签名完全对齐 Android SDK (android.system 包) """ import os as _os import stat as _stat import platform import errno from typing import Any, Dict, List, Optional, Tuple from .._core import Stub, AndroidOnlyError # ═══════════════════════════════════════════════════════════════ # OsConstants # ═══════════════════════════════════════════════════════════════ class OsConstants(Stub): """OsConstants — 系统调用常量,映射自 os/stat 模块""" # 文件访问常量 R_OK = _os.R_OK W_OK = _os.W_OK X_OK = _os.X_OK F_OK = _os.F_OK # 文件权限常量 S_IRWXU = _stat.S_IRWXU S_IRUSR = _stat.S_IRUSR S_IWUSR = _stat.S_IWUSR S_IXUSR = _stat.S_IXUSR S_IRWXG = _stat.S_IRWXG S_IRGRP = _stat.S_IRGRP S_IWGRP = _stat.S_IWGRP S_IXGRP = _stat.S_IXGRP S_IRWXO = _stat.S_IRWXO S_IROTH = _stat.S_IROTH S_IWOTH = _stat.S_IWOTH S_IXOTH = _stat.S_IXOTH S_ISUID = _stat.S_ISUID S_ISGID = _stat.S_ISGID S_ISVTX = _stat.S_ISVTX # 文件类型常量 S_IFMT = _stat.S_IFMT S_IFSOCK = _stat.S_IFSOCK S_IFLNK = _stat.S_IFLNK S_IFREG = _stat.S_IFREG S_IFBLK = _stat.S_IFBLK S_IFDIR = _stat.S_IFDIR S_IFCHR = _stat.S_IFCHR S_IFIFO = _stat.S_IFIFO # 标准文件描述符 STDIN_FILENO = 0 STDOUT_FILENO = 1 STDERR_FILENO = 2 # 信号常量 SIGHUP = 1 SIGINT = 2 SIGQUIT = 3 SIGILL = 4 SIGTRAP = 5 SIGABRT = 6 SIGBUS = 7 SIGFPE = 8 SIGKILL = 9 SIGUSR1 = 10 SIGSEGV = 11 SIGUSR2 = 12 SIGPIPE = 13 SIGALRM = 14 SIGTERM = 15 SIGCHLD = 17 SIGCONT = 18 SIGSTOP = 19 SIGTSTP = 20 SIGTTIN = 21 SIGTTOU = 22 # errno 常量 (使用 getattr 处理 Windows 上不存在的常量) EPERM = errno.EPERM ENOENT = errno.ENOENT ESRCH = errno.ESRCH EINTR = errno.EINTR EIO = errno.EIO ENXIO = errno.ENXIO E2BIG = errno.E2BIG ENOEXEC = errno.ENOEXEC EBADF = errno.EBADF ECHILD = errno.ECHILD EAGAIN = errno.EAGAIN ENOMEM = errno.ENOMEM EACCES = errno.EACCES EFAULT = errno.EFAULT ENOTBLK = getattr(errno, 'ENOTBLK', 15) # Windows 不支持 EBUSY = errno.EBUSY EEXIST = errno.EEXIST EXDEV = errno.EXDEV ENODEV = errno.ENODEV ENOTDIR = errno.ENOTDIR EISDIR = errno.EISDIR EINVAL = errno.EINVAL ENFILE = errno.ENFILE EMFILE = errno.EMFILE ENOTTY = errno.ENOTTY ETXTBSY = getattr(errno, 'ETXTBSY', 139) EFBIG = errno.EFBIG ENOSPC = errno.ENOSPC ESPIPE = errno.ESPIPE EROFS = errno.EROFS EMLINK = errno.EMLINK EPIPE = errno.EPIPE EDOM = errno.EDOM ERANGE = errno.ERANGE EDEADLK = errno.EDEADLK ENAMETOOLONG = errno.ENAMETOOLONG ENOLCK = errno.ENOLCK ENOSYS = errno.ENOSYS ENOTEMPTY = errno.ENOTEMPTY ELOOP = errno.ELOOP ENOMSG = errno.ENOMSG EIDRM = errno.EIDRM ENOSTR = getattr(errno, 'ENOSTR', 125) ENODATA = getattr(errno, 'ENODATA', 120) ETIME = getattr(errno, 'ETIME', 137) ENOSR = getattr(errno, 'ENOSR', 124) EREMOTE = getattr(errno, 'EREMOTE', 10071) ENOLINK = getattr(errno, 'ENOLINK', 121) EPROTO = errno.EPROTO EMULTIHOP = getattr(errno, 'EMULTIHOP', 10072) # Windows 不支持 EBADMSG = getattr(errno, 'EBADMSG', 104) EOVERFLOW = getattr(errno, 'EOVERFLOW', 132) EILSEQ = errno.EILSEQ ENOTSOCK = errno.ENOTSOCK EDESTADDRREQ = errno.EDESTADDRREQ EMSGSIZE = errno.EMSGSIZE EPROTOTYPE = errno.EPROTOTYPE ENOPROTOOPT = errno.ENOPROTOOPT EPROTONOSUPPORT = errno.EPROTONOSUPPORT ESOCKTNOSUPPORT = getattr(errno, 'ESOCKTNOSUPPORT', 10044) EOPNOTSUPP = getattr(errno, 'EOPNOTSUPP', 10045) EPFNOSUPPORT = getattr(errno, 'EPFNOSUPPORT', 10046) EAFNOSUPPORT = getattr(errno, 'EAFNOSUPPORT', 10047) EADDRINUSE = errno.EADDRINUSE EADDRNOTAVAIL = errno.EADDRNOTAVAIL ENETDOWN = errno.ENETDOWN ENETUNREACH = errno.ENETUNREACH ENETRESET = errno.ENETRESET ECONNABORTED = errno.ECONNABORTED ECONNRESET = errno.ECONNRESET ENOBUFS = errno.ENOBUFS EISCONN = errno.EISCONN ENOTCONN = errno.ENOTCONN ESHUTDOWN = getattr(errno, 'ESHUTDOWN', 10058) ETOOMANYREFS = getattr(errno, 'ETOOMANYREFS', 10059) ETIMEDOUT = errno.ETIMEDOUT ECONNREFUSED = errno.ECONNREFUSED EHOSTDOWN = getattr(errno, 'EHOSTDOWN', 10064) EHOSTUNREACH = errno.EHOSTUNREACH EALREADY = errno.EALREADY EINPROGRESS = errno.EINPROGRESS ESTALE = getattr(errno, 'ESTALE', 10070) EUCLEAN = getattr(errno, 'EUCLEAN', 117) # Windows 不支持 ENOTNAM = getattr(errno, 'ENOTNAM', 118) # Windows 不支持 ENAVAIL = getattr(errno, 'ENAVAIL', 119) # Windows 不支持 EISNAM = getattr(errno, 'EISNAM', 120) # Windows 不支持 EREMOTEIO = getattr(errno, 'EREMOTEIO', 121) # Windows 不支持 EDQUOT = getattr(errno, 'EDQUOT', 10069) ENOMEDIUM = getattr(errno, 'ENOMEDIUM', 123) # Windows 不支持 EMEDIUMTYPE = getattr(errno, 'EMEDIUMTYPE', 124) # Windows 不支持 ECANCELED = getattr(errno, 'ECANCELED', 105) ENOKEY = getattr(errno, 'ENOKEY', 126) # Windows 不支持 EKEYEXPIRED = getattr(errno, 'EKEYEXPIRED', 127) # Windows 不支持 EKEYREVOKED = getattr(errno, 'EKEYREVOKED', 128) # Windows 不支持 EKEYREJECTED = getattr(errno, 'EKEYREJECTED', 129) # Windows 不支持 EOWNERDEAD = getattr(errno, 'EOWNERDEAD', 133) ENOTRECOVERABLE = getattr(errno, 'ENOTRECOVERABLE', 127) ERFKILL = getattr(errno, 'ERFKILL', 132) # Windows 不支持 EHWPOISON = getattr(errno, 'EHWPOISON', 1001) # Windows 不支持 def __init__(self): super().__init__() # ═══════════════════════════════════════════════════════════════ # StructStat # ═══════════════════════════════════════════════════════════════ class StructStat(Stub): """StructStat — stat() 返回的文件状态结构体""" def __init__(self, st_mode: int = 0, st_ino: int = 0, st_dev: int = 0, st_nlink: int = 0, st_uid: int = 0, st_gid: int = 0, st_size: int = 0, st_atime: int = 0, st_mtime: int = 0, st_ctime: int = 0, st_blksize: int = 4096, st_blocks: int = 0, st_rdev: int = 0): super().__init__() self.st_mode = st_mode self.st_ino = st_ino self.st_dev = st_dev self.st_nlink = st_nlink self.st_uid = st_uid self.st_gid = st_gid self.st_size = st_size self.st_atime = st_atime self.st_mtime = st_mtime self.st_ctime = st_ctime self.st_blksize = st_blksize self.st_blocks = st_blocks self.st_rdev = st_rdev self.st_atime_ns = st_atime * 1_000_000_000 self.st_mtime_ns = st_mtime * 1_000_000_000 self.st_ctime_ns = st_ctime * 1_000_000_000 @staticmethod def from_os_stat(st: _os.stat_result) -> "StructStat": """从 Python os.stat_result 创建 StructStat""" return StructStat( st_mode=st.st_mode, st_ino=st.st_ino, st_dev=st.st_dev, st_nlink=st.st_nlink, st_uid=st.st_uid, st_gid=st.st_gid, st_size=st.st_size, st_atime=int(st.st_atime), st_mtime=int(st.st_mtime), st_ctime=int(st.st_ctime), st_blksize=st.st_blksize, st_blocks=st.st_blocks, st_rdev=st.st_rdev, ) def toString(self) -> str: return (f"StructStat(st_mode={oct(self.st_mode)}, st_size={self.st_size}, " f"st_mtime={self.st_mtime}, st_uid={self.st_uid}, st_gid={self.st_gid})") def hashCode(self) -> int: return hash((self.st_dev, self.st_ino, self.st_mode)) & 0x7FFFFFFF def equals(self, other) -> bool: if not isinstance(other, StructStat): return False return (self.st_dev == other.st_dev and self.st_ino == other.st_ino and self.st_mode == other.st_mode and self.st_size == other.st_size) # ═══════════════════════════════════════════════════════════════ # StructUtsname # ═══════════════════════════════════════════════════════════════ class StructUtsname(Stub): """StructUtsname — uname() 返回的系统信息结构体""" def __init__(self, sysname: str = "", nodename: str = "", release: str = "", version: str = "", machine: str = ""): super().__init__() self.sysname = sysname or platform.system() self.nodename = nodename or platform.node() self.release = release or platform.release() self.version = version or platform.version() self.machine = machine or platform.machine() @staticmethod def from_platform() -> "StructUtsname": """从 Python platform 模块创建 StructUtsname""" uname = platform.uname() return StructUtsname( sysname=uname.system, nodename=uname.node, release=uname.release, version=uname.version, machine=uname.machine, ) def toString(self) -> str: return (f"StructUtsname(sysname={self.sysname}, nodename={self.nodename}, " f"release={self.release}, version={self.version}, machine={self.machine})") def hashCode(self) -> int: return hash((self.sysname, self.nodename, self.release)) & 0x7FFFFFFF def equals(self, other) -> bool: if not isinstance(other, StructUtsname): return False return (self.sysname == other.sysname and self.nodename == other.nodename and self.release == other.release) # ═══════════════════════════════════════════════════════════════ # Os # ═══════════════════════════════════════════════════════════════ class Os(Stub): """Os — 系统调用包装器,代理到 Python os 模块""" def __init__(self): super().__init__() # ── 文件操作 ── @staticmethod def stat(path: str) -> StructStat: """获取文件状态""" st = _os.stat(path) return StructStat.from_os_stat(st) @staticmethod def lstat(path: str) -> StructStat: """获取符号链接自身状态""" st = _os.lstat(path) return StructStat.from_os_stat(st) @staticmethod def chmod(path: str, mode: int): """修改文件权限""" _os.chmod(path, mode) @staticmethod def chown(path: str, uid: int, gid: int): """修改文件所有者""" _os.chown(path, uid, gid) @staticmethod def link(oldpath: str, newpath: str): """创建硬链接""" _os.link(oldpath, newpath) @staticmethod def symlink(target: str, linkpath: str): """创建符号链接""" _os.symlink(target, linkpath) @staticmethod def readlink(path: str) -> str: """读取符号链接目标""" return _os.readlink(path) @staticmethod def unlink(pathname: str): """删除文件(解除链接)""" _os.unlink(pathname) @staticmethod def remove(path: str): """删除文件""" _os.remove(path) @staticmethod def rename(oldpath: str, newpath: str): """重命名文件""" _os.rename(oldpath, newpath) @staticmethod def mkdir(path: str, mode: int = 0o777): """创建目录""" _os.mkdir(path, mode) @staticmethod def rmdir(path: str): """删除空目录""" _os.rmdir(path) @staticmethod def listdir(path: str) -> List[str]: """列出目录内容""" return _os.listdir(path) @staticmethod def truncate(path: str, length: int): """截断文件到指定长度""" with open(path, 'ab') as f: f.truncate(length) @staticmethod def access(path: str, mode: int) -> bool: """检查文件访问权限""" return _os.access(path, mode) # ── 文件描述符操作 ── @staticmethod def dup(oldfd: int) -> int: """复制文件描述符""" return _os.dup(oldfd) @staticmethod def dup2(oldfd: int, newfd: int): """复制文件描述符到指定值""" _os.dup2(oldfd, newfd) @staticmethod def close(fd: int): """关闭文件描述符""" _os.close(fd) @staticmethod def read(fd: int, count: int) -> bytes: """从文件描述符读取""" return _os.read(fd, count) @staticmethod def write(fd: int, data: bytes) -> int: """写入文件描述符""" return _os.write(fd, data) @staticmethod def lseek(fd: int, offset: int, whence: int) -> int: """移动文件读写位置""" return _os.lseek(fd, offset, whence) @staticmethod def fsync(fd: int): """同步文件描述符""" _os.fsync(fd) @staticmethod def fstat(fd: int) -> StructStat: """获取文件描述符对应文件状态""" st = _os.fstat(fd) return StructStat.from_os_stat(st) @staticmethod def isatty(fd: int) -> bool: """判断文件描述符是否为终端""" return _os.isatty(fd) # ── 进程相关 ── @staticmethod def getpid() -> int: """获取当前进程 ID""" return _os.getpid() @staticmethod def getppid() -> int: """获取父进程 ID""" return _os.getppid() @staticmethod def getuid() -> int: """获取当前用户 ID""" return _os.getuid() @staticmethod def getgid() -> int: """获取当前组 ID""" return _os.getgid() @staticmethod def geteuid() -> int: """获取有效用户 ID""" return _os.geteuid() @staticmethod def getegid() -> int: """获取有效组 ID""" return _os.getegid() @staticmethod def setuid(uid: int): """设置用户 ID""" _os.setuid(uid) @staticmethod def setgid(gid: int): """设置组 ID""" _os.setgid(gid) @staticmethod def setsid() -> int: """创建新会话""" return _os.setsid() @staticmethod def umask(mask: int) -> int: """设置文件创建掩码""" return _os.umask(mask) @staticmethod def kill(pid: int, sig: int): """发送信号给进程""" _os.kill(pid, sig) @staticmethod def getenv(name: str, default: Optional[str] = None) -> Optional[str]: """获取环境变量""" return _os.environ.get(name, default) @staticmethod def setenv(name: str, value: str, overwrite: bool = True): """设置环境变量""" if overwrite or name not in _os.environ: _os.environ[name] = value @staticmethod def unsetenv(name: str): """删除环境变量""" _os.environ.pop(name, None) @staticmethod def environ() -> Dict[str, str]: """获取环境变量字典""" return dict(_os.environ) # ── 系统信息 ── @staticmethod def uname() -> StructUtsname: """获取系统信息""" return StructUtsname.from_platform() @staticmethod def sysconf(name: str) -> int: """获取系统配置值""" conf_names = { "SC_CLK_TCK": 100, "SC_PAGE_SIZE": 4096, "SC_NPROCESSORS_CONF": _os.cpu_count() or 1, "SC_NPROCESSORS_ONLN": _os.cpu_count() or 1, } return conf_names.get(name, -1) @staticmethod def getpagesize() -> int: """获取内存页大小""" return 4096 @staticmethod def getloadavg() -> List[float]: """获取系统负载平均值""" try: return list(_os.getloadavg()) except AttributeError: return [0.0, 0.0, 0.0] # ── 管道与 I/O ── @staticmethod def pipe() -> Tuple[int, int]: """创建管道""" return _os.pipe() @staticmethod def mkfifo(path: str, mode: int = 0o666): """创建命名管道 (FIFO)""" _os.mkfifo(path, mode) @staticmethod def tmpfile() -> str: """创建临时文件路径""" import tempfile return tempfile.mktemp() # ── 时间 ── @staticmethod def time() -> int: """获取当前时间戳 (秒)""" import time return int(time.time()) # ── 其他 ── @staticmethod def strerror(errno: int) -> str: """将错误码转为错误描述""" return _os.strerror(errno) def toString(self) -> str: return f"Os(sysname={platform.system()}, release={platform.release()})" def hashCode(self) -> int: return hash("android.system.Os") & 0x7FFFFFFF def equals(self, other) -> bool: return isinstance(other, Os) # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "Os", "StructStat", "StructUtsname", "OsConstants", ]