豫言操作系统底层接口之文件:按目录句柄授权的打开、状态、目录读取与增删改名;读写与寻址用句柄包。
源码浏览已生成;不能解析的文件以纯文本展示,不表示通过类型检查。
# 豫言操作系统底层文件 0.1.0 状态:草案。文言本见[文言版](规范.文言.md)。通用规则见[调用约定](../调用约定.汉语.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。
# 豫言操作系统底层文件〇点一点〇 状:草案。汉语本见[汉语版](规范.汉语.md)。通用之规,见[调用约定](../调用约定.文言.md);状态之码表,见[底层基础](../底层基础/规范.文言.md);读写与寻址,见[底层句柄](../底层句柄/规范.文言.md)。 ## 范围 按目录柄授权之文件系统操作:打开、取状态、读目录、建目录、删文件、删目录、改名、读符号链接。既开之后,读写、寻址、同步、设长度、关闭,皆用底层句柄之函数。本包依底层句柄。 ## 授权与越界 - 诸路径皆**相对一目录柄**(出自初始柄表,或由 `打开` 所得之目录柄)。路径为 UTF-8,分隔以 `/`,不带尾零;空路径返 44。 - 路径之解**不得越出**其目录柄之子树:`..` 可用于子树之内,而出子树者、绝对路径(以 `/` 起者)、经符号链接而出子树者,皆返 76。 - 符号链接:路径中间者,恒循之(受上条所限);末段循否,视标志(`打开` 之标志 128,`取路径状态` 之标志 1)。 - 当前目录、路径之规整(`.`、`..`、重叠之斜线),垫层持之;后端唯按字面解之,而守其界。 ## 函数(`文件。接口。豫`) | 函数 | 参 | 用 | | --- | --- | --- | | 打开 | 目录句柄, 路径址, 路径长, 标志, 出 | 开文件或目录,新柄四字节书于出址;标志见下 | | 取状态 | 句柄, 出 | 六十四字节之状态块 | | 取路径状态 | 目录句柄, 路径址, 路径长, 标志, 出 | 标志 1 谓循末段符号链接,0 谓取链接本身;六十四字节之状态块 | | 读目录 | 目录句柄, 缓冲址, 缓冲长, 游标址, 出 | 见下;已用字节数四字节 | | 建目录 | 目录句柄, 路径址, 路径长 | 已有则返 20,上级无则返 44 | | 删文件 | 目录句柄, 路径址, 路径长 | 删文件或符号链接;遇目录返 31 | | 删目录 | 目录句柄, 路径址, 路径长 | 唯删空目录;非空返 55,非目录返 54 | | 改名 | 旧目录, 旧路径址, 旧路径长, 新目录, 新路径址, 新路径长 | 改名或移;目标已有者,文件则代之,目录须空;跨文件系统返 75 | | 读链接 | 目录句柄, 路径址, 路径长, 缓冲址, 缓冲长, 出 | 链接之目标书于缓冲(不带零),其长四字节书于出址;缓冲不足返 61;非链接返 28;无符号链接之平台返 58 | ## 打开之标志 按位: | 位 | 义 | | --- | --- | | 1 | 读 | | 2 | 写 | | 4 | 追加(每书皆至文件之末) | | 8 | 无则创;须兼有写;新文件之权限,平台默认 | | 16 | 独占:与创合用,已有则返 20;单用则返 28 | | 32 | 开时截为空;须兼有写 | | 64 | 须为目录:非目录返 54;对目录而兼求写返 31 | | 128 | 不循末段符号链接(末段为符号链接则返 32) | 读与写皆不设,则按读。不识之位返 28。 ## 状态块 六十四字节,沿 WASI filestat 之布局,时以自一九七〇年正月朔日 UTC 起之纳秒: | 偏移 | 宽 | 字段 | | --- | --- | --- | | 0 | 8 | 设备 | | 8 | 8 | 索引节点 | | 16 | 1 | 类型:0 未知、1 块设备、2 字符设备、3 目录、4 普通文件、5 数据报套接字、6 流套接字、7 符号链接 | | 20 | 4 | 权限位(占 WASI 之填充位,WASI 垫层略之;平台无则为零) | | 24 | 8 | 链接数 | | 32 | 8 | 大小(字节) | | 40 | 8 | 访问之时 | | 48 | 8 | 修改之时 | | 56 | 8 | 变更之时 | ## 目录项 沿 WASI dirent 之布局:下一游标八字节、索引节点八字节、名长四字节、类型一字节(同状态块之类型)、填充三字节,共二十四字节,其后为名之字节(不带零);诸项相接而排。 `读目录` 自游标(八字节,入而复书)之后而读,游标零谓自首;缓冲尽装完整之项,最后一项可被截断;已用之字节数书于出址:**小于缓冲长,则已读毕;与缓冲长等,则或有余项**,以所复书之游标再读。项中含 `.` 与 `..`,居最前。 ## 平台之注 - **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,权限位为零。