豫言 / 豫言操作系统底层句柄 @ 0.1.0

豫言操作系统底层接口之句柄:句柄的读写、寻址、同步、等待与管道;文件、套接字、终端、进程共用的部分。

源码浏览已生成;不能解析的文件以纯文本展示,不表示通过类型检查。

规范.汉语.md

# 豫言操作系统底层句柄 0.1.0

状态:草案。文言本见[文言版](规范.文言.md)。通用规则见[调用约定](../调用约定.汉语.md),状态码表见[底层基础](../底层基础/规范.汉语.md)。

## 范围

句柄的通用操作:读、写、定位读写、寻址、同步、设长度、设非阻塞、等待、建管道,以及枚举初始授权与查询类别。文件、套接字、终端、进程的句柄都用这里的函数收发数据;打开、连接、启动它们的函数在各自的包里。本包依赖底层基础(状态码)。

## 句柄模型

- 句柄是非负整数,由平台发放;0、1、2 恒为标准输入、输出、错误;-1 无效;关闭后编号可能复用。
- **初始句柄表**:启动时平台授予的其余句柄(预开目录等),用 `取初始句柄` 按序号(从 0 起)枚举,每项给出类别、句柄和名字(预开目录的名字是客体看到的路径,如 `/`)。这是程序获得授权的唯一来源。
- **类别**(`取句柄类别`):0 未知、1 普通文件、2 目录、3 终端、4 其他字符设备、5 管道、6 套接字、7 进程。
- 各函数对不适用的类别返回 28(参数无效):例如对目录 `读`,对管道 `寻址`(返回 70,不可寻址)。

## 句柄(`句柄。接口。豫`)

| 函数 | 参数 | 作用 |
| --- | --- | --- |
| 取初始句柄 | 序号, 类别出, 句柄出, 名缓冲址, 名缓冲长, 名总长出 | 出类别、句柄各 4 字节;名字写入名缓冲,名字总长 4 字节;序号越界返回 44;名缓冲不足返回 61 |
| 取句柄类别 | 句柄, 出 | 类别 4 字节 |
| 读 | 句柄, 缓冲址, 长, 出 | 至多读「长」字节;已读数 4 字节,0 表示文件尾;非阻塞句柄无数据返回 6;终端行模式按行送达,换行符含在所读字节中,空行因此读得至少 1 字节;缓冲区短于一行时,剩余字节由后续读取接收;长为 0 时不消耗输入 |
| 写 | 句柄, 址, 长, 出 | 已写数 4 字节,可短写;读端已关闭的管道返回 64 |
| 定位读 | 句柄, 缓冲址, 长, 偏移低, 偏移高, 出 | 不改变当前位置;不可寻址的句柄返回 70 |
| 定位写 | 句柄, 址, 长, 偏移低, 偏移高, 出 | 同上 |
| 寻址 | 句柄, 偏移低, 偏移高, 起点, 出 | 起点 0 开头、1 当前、2 末尾;新位置 8 字节;不可寻址返回 70 |
| 关闭 | 句柄 | 之后该编号失效 |
| 同步 | 句柄, 标志 | 标志 1 表示仅同步数据;不可同步的句柄返回 28 |
| 设长度 | 句柄, 低, 高 | 截断或扩展普通文件;其余类别返回 28 |
| 设非阻塞 | 句柄, 开关 | 开关 1 置为非阻塞、0 恢复阻塞 |
| 建管道 | 读端出, 写端出 | 两端各得一个句柄(各 4 字节);所有写端关闭后读端读得 0 |

## 等待(`等待。接口。豫`)

| 函数 | 参数 | 作用 |
| --- | --- | --- |
| 等待 | 订阅址, 订阅数, 事件址, 出 | 阻塞到至少有一个事件;事件写入事件址,事件个数(4 字节)写入出址;订阅数为 0 返回 28 |

**订阅**(16 字节):

| 偏移 | 宽 | 字段 |
| --- | --- | --- |
| 0 | 4 | 类别:1 时钟、2 可读、3 可写 |
| 4 | 4 | 句柄(时钟类忽略) |
| 8 | 8 | 超时纳秒(仅时钟类,相对当前时刻) |

**事件**(16 字节):

| 偏移 | 宽 | 字段 |
| --- | --- | --- |
| 0 | 4 | 订阅序号,即该订阅在数组中的下标 |
| 4 | 4 | 状态码:0,或该句柄出错的码(如 8) |
| 8 | 4 | 类别,同订阅 |
| 12 | 4 | 可用字节数(可读类,超过 32 位则取最大值;其余为 0) |

规则:时钟订阅到时即报告;可读订阅在句柄有数据或已到文件尾(此时可用字节数为 0)时报告;可写订阅在写入不会阻塞时报告;没有时钟订阅且没有句柄就绪则一直阻塞。没有句柄订阅、只有时钟订阅时就是睡眠。首版保证四类对象可等待:文件(恒就绪)、终端、管道、套接字与进程(进程可读即已退出)。

## 平台注记

- **裸机**:0、1、2 是控制台;管道是执行器内的内存对象;等待时钟用内核滴答(精度 10 ms),等待邮箱与终端输入靠内核服务轮询;文件句柄由执行器内的文件系统提供(见[底层文件](../底层文件/规范.汉语.md))。
- **桌面**:句柄是对文件描述符(Linux、macOS)或 HANDLE(Windows)的一层编号;`等待` 落到 ppoll、kevent 或 WaitForMultipleObjects,这是各后端里最难保持一致的一处,首版只承诺上面四类对象。

规范.文言.md

# 豫言操作系统底层句柄〇点一点〇

状:草案。汉语本见[汉语版](规范.汉语.md)。通用之规,见[调用约定](../调用约定.文言.md);状态之码表,见[底层基础](../底层基础/规范.文言.md)。

## 范围

柄之通用操作:读、写、定位读写、寻址、同步、设长度、设非阻塞、等待、建管道,及枚举初始授权与询类别。文件、套接字、终端、进程之柄,皆用此中函数以收发数据;其打开、连接、启动之函数,则在各自之包。本包依底层基础(状态之码)。

## 柄之模

- 柄乃非负整数,平台颁之;零、一、二恒为标准入、出、误;负一为无效;既闭,其号或复用。
- **初始柄表**:启动时平台所授之余柄(预开之目录等),以 `取初始句柄` 按序号(自零起)枚举,每项给类别、柄与名(预开目录之名,乃客体所见之路径,如 `/`)。此为程序得授权之唯一来源。
- **类别**(`取句柄类别`):0 未知、1 普通文件、2 目录、3 终端、4 他字符设备、5 管道、6 套接字、7 进程。
- 诸函数遇不适之类别则返 28(参数无效):如对目录 `读`,对管道 `寻址`(返 70,不可寻址)。

## 句柄(`句柄。接口。豫`)

| 函数 | 参 | 用 |
| --- | --- | --- |
| 取初始句柄 | 序号, 类别出, 句柄出, 名缓冲址, 名缓冲长, 名总长出 | 出类别、柄各四字节;名书于名缓冲,名之总长四字节;序号越界返 44;名缓冲不足返 61 |
| 取句柄类别 | 句柄, 出 | 类别四字节 |
| 读 | 句柄, 缓冲址, 长, 出 | 至多读「长」字节;已读之数四字节,零为文件尾;非阻塞之柄无数据返 6;终端行模按行送达,换行符亦在所读字节中,空行故至少得一字节;缓冲短于一行则余字待后读;长为零则不耗输入 |
| 写 | 句柄, 址, 长, 出 | 已写之数四字节,可短写;读端已闭之管道返 64 |
| 定位读 | 句柄, 缓冲址, 长, 偏移低, 偏移高, 出 | 不易当前之位;不可寻址之柄返 70 |
| 定位写 | 句柄, 址, 长, 偏移低, 偏移高, 出 | 同上 |
| 寻址 | 句柄, 偏移低, 偏移高, 起点, 出 | 起点 0 始、1 今、2 末;新位八字节;不可寻址返 70 |
| 关闭 | 句柄 | 其后此号失效 |
| 同步 | 句柄, 标志 | 标志 1 谓仅同步数据;不可同步之柄返 28 |
| 设长度 | 句柄, 低, 高 | 截或扩普通文件;余类返 28 |
| 设非阻塞 | 句柄, 开关 | 开关 1 置为非阻塞,0 复其阻塞 |
| 建管道 | 读端出, 写端出 | 二端各得一柄(各四字节);诸写端皆闭,则读端读得 0 |

## 等待(`等待。接口。豫`)

| 函数 | 参 | 用 |
| --- | --- | --- |
| 等待 | 订阅址, 订阅数, 事件址, 出 | 阻塞至少有一事;事书于事件址,事之个数(四字节)书于出址;订阅数为零则返 28 |

**订**(十六字节):

| 偏移 | 宽 | 字段 |
| --- | --- | --- |
| 0 | 4 | 类别:1 钟、2 可读、3 可写 |
| 4 | 4 | 柄(钟类略之) |
| 8 | 8 | 超时纳秒(唯钟类,相对当前之刻) |

**事**(十六字节):

| 偏移 | 宽 | 字段 |
| --- | --- | --- |
| 0 | 4 | 订之序号,即其于数组中之下标 |
| 4 | 4 | 状态之码:零,或其柄出误之码(如 8) |
| 8 | 4 | 类别,同订 |
| 12 | 4 | 可用之字节数(可读类,逾三十二位则取其极;余为零) |

规:钟订至时即报;可读之订,柄有数据或已至文件尾(是时可用之字节数为零)则报;可写之订,写而不阻则报;无钟订而无柄就绪,则久阻。无柄之订而唯有钟订,即睡眠。首版保四类之物可候:文件(恒就绪)、终端、管道、套接字与进程(进程可读即已退)。

## 平台之注

- **裸机**:零、一、二为控制台;管道乃执行器内之内存物;候钟用内核滴答(精度十毫秒),候邮箱与终端之入,靠内核服务之轮询;文件之柄,由执行器内之文件系统供之(见[底层文件](../底层文件/规范.文言.md))。
- **桌面**:柄乃文件描述符(Linux、macOS)或 HANDLE(Windows)之上一层编号;`等待` 落于 ppoll、kevent 或 WaitForMultipleObjects,此诸后端中最难齐一之处,首版唯承上述四类之物。