Perl – 通过fork / exec传递一个开放的套接字

前端之家收集整理的这篇文章主要介绍了Perl – 通过fork / exec传递一个开放的套接字前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想要一个Perl守护进程监听并接受来自客户端的传入连接,然后fork&执行另一个Perl程序来继续与客户端的对话.

只要分叉,我可以做到这一点 – 守护进程代码还包含子代码.但是我看不到打开的socket可以通过exec()传递给另一个Perl程序.

不知怎的,我得到这样的印象,这在Unix(这是我的环境)很容易,因此也在Perl中.实际上可以做到吗

解决方法

这可以通过三个步骤完成:

>清除文件描述符上的close-on-exec标志.
>告诉exec’d程序哪个文件描述符使用.
>将文件描述符还原到句柄.

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: $!";

现在文件描述符将保持打开,你需要告诉程序哪个描述符是:

my $fd = fileno $fh;
exec 'that_program',$fd;  # pass it on the command line
# (you could also pass it via %ENV or whatever)

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

现在你再次在$fh中有一个Perl级别的句柄.

附录:由于ikegami在评论中提到,您还可以确保套接字正在使用三个“标准”文件描述符(0(stdin),1(stdout),2(stderr))之一,它们是1.打开在两个execs之间默认,2.已知数字,所以不需要传递任何东西,并且3. perl将自动为它们创建相应的句柄.

open STDIN,'+<&',$fh;  # now STDIN refers to the socket
exec 'that_program';

现在that_program只能使用STDIN.这甚至可以输出;对于文件描述符0,1,2,它们没有固有的限制,仅用于输入或输出.所有unix程序都遵循惯例.

猜你在找的Perl相关文章