内核:SEEK 补真正的 whence(0=SET 1=CUR 2=END,END 时 offset 为距末尾的距离,offset>size 返回 -1);删除 TELL/SIZE 的枚举项、派发分支与 TELL/fsize 函数(fat32.tell/size 仍留给 SEEK 内部用)。 SDK:vpsdk/fs.vp 的 seek() 增加 whence 参数(默认 0,调用方不变);tell() 改为 lseek(fd,0,SEEK_CUR);fsize() 改为三次 lseek 往返(记住位置 → 跳末尾取大小 → 复位),不改变最终位置。 私有段只剩 5 项:OPENDIR/READDIR/CLOSEDIR(openat+getdents64)与 LOAD_SO/SO_CALL1(动态库加载下沉)。
150 lines
4.9 KiB
Plaintext
150 lines
4.9 KiB
Plaintext
from . import syscall as syscall
|
||
|
||
|
||
define O_RDONLY = 0x01
|
||
define O_WRONLY = 0x02
|
||
define O_RDWR = 0x03
|
||
define O_CREAT = 0x04
|
||
define O_TRUNC = 0x08
|
||
define O_APPEND = 0x30
|
||
|
||
define SEEK_SET = 0
|
||
define SEEK_CUR = 1
|
||
define SEEK_END = 2
|
||
|
||
define DT_UNKNOWN = 0
|
||
define DT_FILE = 1
|
||
define DT_DIR = 2
|
||
|
||
def open(path: const str, flags: uint32) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.OPEN), uint64(path), uint64(flags), 0))
|
||
|
||
def close(fd: int) -> int:
|
||
return int(syscall._syscall1(uint64(syscall.Syscall.CLOSE), uint64(fd)))
|
||
|
||
def read(fd: int, buf: rawptr, count: uint32) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.READ), uint64(fd), uint64(buf), uint64(count)))
|
||
|
||
def write(fd: int, buf: rawptr, count: uint32) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.WRITE), uint64(fd), uint64(buf), uint64(count)))
|
||
|
||
def seek(fd: int, offset: uint32, whence: uint32 = 0) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.SEEK), uint64(fd), uint64(offset), uint64(whence)))
|
||
|
||
def tell(fd: int) -> uint32:
|
||
"""当前位置 = lseek(fd, 0, SEEK_CUR)(TELL 私有 syscall 已删除)。"""
|
||
return uint32(syscall._syscall3(uint64(syscall.Syscall.SEEK), uint64(fd), 0, uint64(SEEK_CUR)))
|
||
|
||
def fsize(fd: int) -> uint32:
|
||
"""文件大小:SIZE 私有 syscall 已删除,改用 lseek 往返(不改变最终位置)。
|
||
|
||
三次 lseek:记住当前位置 → 跳到末尾拿到大小 → 复位。多两次 syscall,换掉一个私有号。
|
||
"""
|
||
cur: uint32 = uint32(syscall._syscall3(uint64(syscall.Syscall.SEEK), uint64(fd), 0, uint64(SEEK_CUR)))
|
||
end: uint32 = uint32(syscall._syscall3(uint64(syscall.Syscall.SEEK), uint64(fd), 0, uint64(SEEK_END)))
|
||
syscall._syscall3(uint64(syscall.Syscall.SEEK), uint64(fd), uint64(cur), uint64(SEEK_SET))
|
||
return end
|
||
|
||
def mkdir(path: const str) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.MKDIR), uint64(path), 0, 0))
|
||
|
||
def remove(path: const str) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.REMOVE), uint64(path), 0, 0))
|
||
|
||
def opendir(path: const str) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.OPENDIR), uint64(path), 0, 0))
|
||
|
||
def readdir(dd: int, info: rawptr) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.READDIR), uint64(dd), uint64(info), 0))
|
||
|
||
def closedir(dd: int) -> int:
|
||
return int(syscall._syscall1(uint64(syscall.Syscall.CLOSEDIR), uint64(dd)))
|
||
|
||
def stat(path: const str, info: rawptr) -> int:
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.STAT), uint64(path), uint64(info), 0))
|
||
|
||
def ioctl(fd: int, request: uint32, arg: rawptr) -> int:
|
||
"""设备控制(Linux ioctl 子集)。当前只有 devfs 设备(如 /dev/fb0)实现了它。"""
|
||
return int(syscall._syscall3(uint64(syscall.Syscall.IOCTL), uint64(fd), uint64(request), uint64(arg)))
|
||
|
||
class FileIO:
|
||
_fd: int
|
||
_pos: uint32
|
||
_size: uint32
|
||
_flags: uint32
|
||
_closed: int
|
||
|
||
def __init__(self, fd: int, flags: uint32):
|
||
self._fd = fd
|
||
self._flags = flags
|
||
self._pos = 0
|
||
self._size = fsize(fd)
|
||
self._closed = 0
|
||
|
||
def read(self, buf: rawptr, count: uint32) -> int:
|
||
if self._closed: return -1
|
||
n: int = read(self._fd, buf, count)
|
||
if n > 0:
|
||
self._pos = self._pos + uint32(n)
|
||
return n
|
||
|
||
def write(self, buf: rawptr, count: uint32) -> int:
|
||
if self._closed: return -1
|
||
n: int = write(self._fd, buf, count)
|
||
if n > 0:
|
||
self._pos = self._pos + uint32(n)
|
||
if self._pos > self._size:
|
||
self._size = self._pos
|
||
return n
|
||
|
||
def seek(self, offset: uint32) -> int:
|
||
if self._closed: return -1
|
||
res: int = seek(self._fd, offset)
|
||
if res == 0:
|
||
self._pos = offset
|
||
return res
|
||
|
||
def tell(self) -> uint32:
|
||
return self._pos
|
||
|
||
def size(self) -> uint32:
|
||
return self._size
|
||
|
||
def close(self) -> int:
|
||
if self._closed: return 0
|
||
self._closed = 1
|
||
return close(self._fd)
|
||
|
||
def is_closed(self) -> int:
|
||
return self._closed
|
||
|
||
class DirIO:
|
||
_dd: int
|
||
_closed: int
|
||
|
||
def __init__(self, dd: int):
|
||
self._dd = dd
|
||
self._closed = 0
|
||
|
||
def read(self, info: rawptr) -> int:
|
||
if self._closed: return -1
|
||
return readdir(self._dd, info)
|
||
|
||
def close(self) -> int:
|
||
if self._closed: return 0
|
||
self._closed = 1
|
||
return closedir(self._dd)
|
||
|
||
def is_closed(self) -> int:
|
||
return self._closed
|
||
|
||
def open_file(path: const str, flags: uint32) -> FileIO:
|
||
fd: int = open(path, flags)
|
||
if fd < 0: return None
|
||
return FileIO(fd, flags)
|
||
|
||
def open_dir(path: const str) -> DirIO:
|
||
dd: int = opendir(path)
|
||
if dd < 0: return None
|
||
return DirIO(dd)
|