mel*_*ene 14
这可以通过大约三个步骤完成:
1. Perl(默认情况下)在它打开的文件描述符上设置close-on-exec标志.这意味着文件描述符不会被保留exec.你必须先清除这个标志:
use Fcntl;
my $flags = fcntl $fh, F_GETFD, 0 or die "fcntl F_GETFD: $!";
fcntl $fh, F_SETFD, $flags & ~FD_CLOEXEC or die "fcntl F_SETFD: $!";
Run Code Online (Sandbox Code Playgroud)
2.现在文件描述符将保持打开状态exec,您需要告诉程序它是哪个描述符:
my $fd = fileno $fh;
exec 'that_program', $fd; # pass it on the command line
# (you could also pass it via %ENV or whatever)
Run Code Online (Sandbox Code Playgroud)
3.恢复另一侧的文件句柄:
my $fd = $ARGV[0]; # or however you passed it
open my $fh, '+<&=', $fd; # fdopen
$fh->autoflush(1); # because "normal" sockets have that enabled by default
Run Code Online (Sandbox Code Playgroud)
现在你$fh又有了一个Perl级别的句柄.
附录:正如ikegami在评论中提到的那样,你也可以确保套接字使用三个"标准"文件描述符之一(0(stdin),1(stdout),2(stderr)),它们是1.默认跨越高管,2.已知数字,所以不需要传递任何东西,并且3. perl将自动为它们创建相应的句柄.
open STDIN, '+<&', $fh; # now STDIN refers to the socket
exec 'that_program';
Run Code Online (Sandbox Code Playgroud)
现在that_program可以简单地使用STDIN.这甚至适用于输出; 文件描述符0,1,2没有固有的限制,它们仅用于输入或输出.这只是所有unix程序遵循的惯例.