扩展流

作为构建流的第二步,可以将模块添加到流中。

在 "流设置" 图 (图 1) 中的右手流中,添加了 CANONPROC 模块以提供对头和驱动程序之间发送的字符的额外处理。

将按最后一个先进先出 (LIFO) 顺序从流中添加和除去模块。 它们通过使用 ioctl 操作在流头处插入和删除。 在 "模块可重用性" 图 (图 1) 左侧的流中,首先添加了 1 类传输,然后添加了规范模块。 要将 Class 1 模块替换为 Class 0 模块,必须先除去 Canonical 模块,然后再除去 Class 1 模块。 最后,将添加一个 Class 0 模块,然后将 Canonical 模块放回。

图 1。 模块可复用性
此图显示左侧的用户进程,其中规范模块与 SAME 模块和 SAME 接口的 Boarder 进行双向通信。 规范模块还与类 1 传输协议进行双向通信。 还有从传输协议到 LAPB (链路访问过程均衡) 驱动程序的双向通信。 右侧的第二流用户进程显示一个规范模块,该规范模块与 SAME 模块和 SAME 接口的接口具有双向通信。 规范模块还与原始 tty 驱动程序进行双向通信。

由于添加和除去模块类似于堆栈操作,因此添加例程称为 推送 ,除去例程称为 popI_PUSHI_POP 是 ioctl 操作 ( streamio 操作) 的 STREAMS 子集中包含的两个操作。 这些操作对流执行各种操作。 以此方式处理的模块称为 可推送模块,与流头和流端中包含的模块不同。 此堆栈术语仅适用于流的设置,修改和细分。

注: 后续使用单词 module 将引用流头和流端之间的那些可推送模块。

流头处理 streamio 操作并执行推送,这类似于打开流驱动程序。 模块由包含在 STREAMS fmodsw 模块表中的唯一符号名称引用 (类似于与设备文件关联的 devsw 表)。 模块表和模块名称是 STREAMS 的内部名称,只能通过 STREAMS ioctl 子例程从用户空间进行访问。 fmodsw 表指向内核中的模块模板。 推送模块时,将找到模板,分配两个 QUEUE 的模块结构,并将模板值复制到结构中。

除了模块元素外,每个模块还包含指向打开例程和关闭例程的指针。 在推送模块时调用 open 例程,在弹出模块时调用 close 例程。 模块打开和关闭过程类似于驱动程序打开和关闭过程。

与其他文件一样,当最后一个打开 STREAMS 文件的进程通过 close 子例程关闭该文件时, STREAMS 文件将关闭。 此子例程使流被拆除 (即,模块被弹出,驱动程序关闭例程被执行)。