这就是说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)
,所以syscall 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. */
那么什么是“传统”方式呢?是否有任何现代系统仍然存在这种情况?
答案1
Perl 文档中的这一段是在Perl 5.004_041997 年 9 月。我不熟悉SYS_pipe
当时特定的 Unix 内核的处理方式;但 Unix V6 中的原始实现在寄存器中返回两个文件描述符,然后库的pipe
实现将这些值存储在整数数组中。V6pipe(2)
联机帮助页简要记录这一点:
(管道 = 42。)
系统管道
(读取r0中的文件描述符)
(写入r1中的文件描述符)
提交消息于Linux补丁其中统一了各种sys_pipe
实现也提到了这一点:
传统的 UNIX 实现通常返回寄存器中的两个文件描述符
大概 Perl 的注释syscall
来自于这样的事实:传统SYS_pipe
上,无论使用什么寄存器来返回函数的结果(上面的 r0、PC 上的 AX/EAX/RAX 等),都会返回读取的文件描述符,这可以从 Perl 代码中访问,但您无法读取 r1 中返回的值。
我不知道有哪个现代系统仍然以这种方式返回文件描述符。我也不清楚 1997 年有多少 Unix 系统有这种行为;我的印象是至少 Solaris (2.6) 没有。