pipe(2) 系統呼叫在“傳統”Unix 中是如何工作的
這
perldoc -f syscall
就是說:有一個問題
syscall(SYS_pipe())
:它返回它創建的管道的讀取端的文件號,但是沒有辦法檢索另一端的文件號。您可以通過使用來避免此問題pipe
。但是,這並沒有檢查出來。
syscall
與SYS_pipe
任何其他系統呼叫一樣工作,我完全能夠檢索兩端:perl -e ' require "syscall.ph"; my $p = pack "i2"; syscall SYS_pipe(), $p; print join(",", unpack "i2", $p), "\n" ' 3,4
那是在linux上,在openbsd和solaris上是一樣的,只要你注意一些差異(在solaris上,系統呼叫實際上是
pipe2(2)
, sosyscall 42, $p, 0
)。
fs/pipe.c
linux核心原始碼中的評論說:/* * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */
那麼這種“傳統”方式是什麼?是否有任何現代系統仍然如此?
Perl 文件中的這一段是在 1997 年 9 月的Perl 5.004_04中引入的。我不熟悉當時特定的 Unix 核心的處理方式
SYS_pipe
。但是 Unix V6 中的原始實現在寄存器中返回了兩個文件描述符,然後庫的pipe
實現將這些值儲存在一個整數數組中。V6pipe(2)
手冊頁簡要記錄了這一點:(pipe = 42.)
sys pipe
(讀取 r0 中的文件描述符)
(寫入 r1 中的文件描述符)
統一各種實現的 Linux 更新檔上的送出消息
sys_pipe
也提到了這一點:傳統的 UNIX 實現通常在寄存器中返回兩個文件描述符
大概 Perl 註釋
syscall
來自這樣一個事實,即傳統SYS_pipe
在任何用於返回函式結果的寄存器中返回讀取文件描述符(上面的 r0,PC 上的 AX/EAX/RAX 等),可以從 Perl 程式碼訪問,但您將無法讀取 r1 中返回的值。我不知道任何現代系統仍然以這種方式返回文件描述符。我也不清楚 1997 年有多少 Unix 系統以這種方式執行。我得到的印象至少 Solaris (2.6) 沒有。