[英]Perl - passing an open socket across fork/exec
我希望有一個Perl守護進程監聽並接受來自客戶端的傳入連接,然后fork & exec另一個Perl程序繼續與客戶端進行對話。
簡單地分叉時我可以做到這一點 - 守護進程代碼也包含子代碼。 但我沒有看到open socket如何通過exec()傳遞給另一個Perl程序。
不知怎的,我得到的印象是這在Unix(這是我的環境)中很容易,因此在Perl中也是如此。 真的可以嗎?
這可以通過大約三個步驟完成:
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: $!";
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)
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.默認跨越高管,2。已知數字,所以不需要傳遞任何東西,並且3. perl將自動為它們創建相應的句柄。
open STDIN, '+<&', $fh; # now STDIN refers to the socket
exec 'that_program';
現在that_program
可以簡單地使用STDIN
。 這甚至適用於輸出; 文件描述符0,1,2沒有固有的限制,它們僅用於輸入或輸出。 這只是所有unix程序遵循的慣例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.