扩展流
作为构建流的第二步,可以将模块添加到流中。
在 "流设置" 图 (图 1) 中的右手流中,添加了 CANONPROC 模块以提供对头和驱动程序之间发送的字符的额外处理。
将按最后一个先进先出 (LIFO) 顺序从流中添加和除去模块。 它们通过使用 ioctl 操作在流头处插入和删除。 在 "模块可重用性" 图 (图 1) 左侧的流中,首先添加了 1 类传输,然后添加了规范模块。 要将 Class 1 模块替换为 Class 0 模块,必须先除去 Canonical 模块,然后再除去 Class 1 模块。 最后,将添加一个 Class 0 模块,然后将 Canonical 模块放回。

由于添加和除去模块类似于堆栈操作,因此添加例程称为 推送 ,除去例程称为 pop。 I_PUSH 和 I_POP 是 ioctl 操作 ( streamio 操作) 的 STREAMS 子集中包含的两个操作。 这些操作对流执行各种操作。 以此方式处理的模块称为 可推送模块,与流头和流端中包含的模块不同。 此堆栈术语仅适用于流的设置,修改和细分。
流头处理 streamio 操作并执行推送,这类似于打开流驱动程序。 模块由包含在 STREAMS fmodsw 模块表中的唯一符号名称引用 (类似于与设备文件关联的 devsw 表)。 模块表和模块名称是 STREAMS 的内部名称,只能通过 STREAMS ioctl 子例程从用户空间进行访问。 fmodsw 表指向内核中的模块模板。 推送模块时,将找到模板,分配两个 QUEUE 的模块结构,并将模板值复制到结构中。
除了模块元素外,每个模块还包含指向打开例程和关闭例程的指针。 在推送模块时调用 open 例程,在弹出模块时调用 close 例程。 模块打开和关闭过程类似于驱动程序打开和关闭过程。
与其他文件一样,当最后一个打开 STREAMS 文件的进程通过 close 子例程关闭该文件时, STREAMS 文件将关闭。 此子例程使流被拆除 (即,模块被弹出,驱动程序关闭例程被执行)。