Pipe

pipe(2) 系統呼叫在“傳統”Unix 中是如何工作的

  • February 6, 2019

perldoc -f syscall就是說:

有一個問題syscall(SYS_pipe()):它返回它創建的管道的讀取端的文件號,但是沒有辦法檢索另一端的文件號。您可以通過使用來避免此問題pipe

但是,這並沒有檢查出來。syscallSYS_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), so syscall 42, $p, 0)。

fs/pipe.clinux核心原始碼中的評論說:

/*
 * 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) 沒有。

引用自:https://unix.stackexchange.com/questions/498720