豫言操作系统底层文件 0.1.0
状态:草案。文言本见文言版。通用规则见[调用约定](../调用约定.汉语.md),状态码表见[底层基础](../底层基础/规范.汉语.md),读写与寻址见[底层句柄](../底层句柄/规范.汉语.md)。
范围
按目录句柄授权的文件系统操作:打开、取状态、读目录、建目录、删文件、删目录、改名、读符号链接。打开之后的读写、寻址、同步、设长度、关闭都用底层句柄的函数。本包依赖底层句柄。
授权与越界
- 所有路径都相对一个目录句柄(来自初始句柄表,或由
打开得到的目录句柄)。路径是 UTF-8,分隔符是/,不带结尾零;空路径返回 44。 - 路径解析不得越出该目录句柄的子树:
..可以在子树内部使用,但走出子树、绝对路径(以/开头)、经符号链接走出子树,都返回 76。 - 符号链接:路径中间的符号链接总是跟随(受上一条限制);末段是否跟随由标志决定(
打开的标志 128,取路径状态的标志 1)。 - 当前目录、路径规范化(
.、..、重复斜线)由 shim 维护;后端只需按字面解析并守住边界。
函数(文件。接口。豫)
| 函数 | 参数 | 作用 | | --- | --- | --- | | 打开 | 目录句柄, 路径址, 路径长, 标志, 出 | 打开文件或目录,新句柄 4 字节写入出址;标志见下 | | 取状态 | 句柄, 出 | 64 字节状态块 | | 取路径状态 | 目录句柄, 路径址, 路径长, 标志, 出 | 标志 1 表示跟随末段符号链接,0 表示取链接本身;64 字节状态块 | | 读目录 | 目录句柄, 缓冲址, 缓冲长, 游标址, 出 | 见下;已用字节数 4 字节 | | 建目录 | 目录句柄, 路径址, 路径长 | 已存在返回 20,上级不存在返回 44 | | 删文件 | 目录句柄, 路径址, 路径长 | 删除文件或符号链接;对目录返回 31 | | 删目录 | 目录句柄, 路径址, 路径长 | 只删空目录;非空返回 55,不是目录返回 54 | | 改名 | 旧目录, 旧路径址, 旧路径长, 新目录, 新路径址, 新路径长 | 改名或移动;目标已存在时,文件被替换,目录须为空;跨文件系统返回 75 | | 读链接 | 目录句柄, 路径址, 路径长, 缓冲址, 缓冲长, 出 | 链接目标写入缓冲(不带零),长度 4 字节写入出址;缓冲不足返回 61;不是链接返回 28;没有符号链接的平台返回 58 |
打开标志
按位:
| 位 | 含义 | | --- | --- | | 1 | 读 | | 2 | 写 | | 4 | 追加(每次写都到文件末尾) | | 8 | 不存在则创建;须同时有写;新文件的权限由平台默认 | | 16 | 独占:与创建合用,已存在返回 20;单独使用返回 28 | | 32 | 打开时截断为空;须同时有写 | | 64 | 须为目录:不是目录返回 54;对目录同时要求写返回 31 | | 128 | 不跟随末段符号链接(末段是符号链接时返回 32) |
读和写都不设时按读处理。不认识的位返回 28。
状态块
64 字节,沿用 WASI filestat 布局,时间为自 1970-01-01 UTC 起的纳秒:
| 偏移 | 宽 | 字段 | | --- | --- | --- | | 0 | 8 | 设备 | | 8 | 8 | 索引节点 | | 16 | 1 | 类型:0 未知、1 块设备、2 字符设备、3 目录、4 普通文件、5 数据报套接字、6 流套接字、7 符号链接 | | 20 | 4 | 权限位(占用 WASI 的填充位,WASI shim 忽略它;平台没有则为 0) | | 24 | 8 | 链接数 | | 32 | 8 | 大小(字节) | | 40 | 8 | 访问时间 | | 48 | 8 | 修改时间 | | 56 | 8 | 变更时间 |
目录项
沿用 WASI dirent 布局:下一游标 8 字节、索引节点 8 字节、名长 4 字节、类型 1 字节(同状态块的类型)、填充 3 字节,共 24 字节,其后是名字节(不带零);各项紧接排列。
读目录 从游标(8 字节,读入并写回)之后开始读,游标 0 表示从头;缓冲尽量装入完整的项,最后一项可以被截断;已用字节数写入出址:小于缓冲长表示已读完,等于缓冲长表示可能还有余项,用写回的游标再读。项里包含 . 与 ..,在最前面。
平台注记
- Linux:打开使用
openat2加RESOLVE_BENEATH;返回ENOSYS时逐段用O_PATH|O_NOFOLLOW解析链接与..。路径状态经受限句柄调用statx;建删目录、改名和读链接先安全打开父目录。目录用getdents64。逐段回退仍有并发更名竞态,待办事项。 - macOS:当前后端在
openat使用O_RESOLVE_BENEATH,在fstatat使用AT_RESOLVE_BENEATH;无边界标志参数的建删、改名与读链接先受限打开父目录。旧系统不支持这些标志时的回退仍待实现。 - Windows:路径转 UTF-16,用
NtCreateFile的 RootDirectory 相对打开;没有一步到位的越界防护,逐段解析并检查重解析点;大小写不敏感由后端如实反映,接口不掩盖。 - 裸机:文件系统现在在执行器内,按整文件读写、日志结构(见[客体文件系统](../../豫言操作系统/裸机/文档/客体文件系统.汉语.md))。句柄接口的首版可在后端内用整文件缓存实现(读改写,关闭或同步时写回);块级读写另案。裸机没有符号链接,
读链接返回 58,权限位为 0。