簡體   English   中英

Perl - 在fork / exec之間傳遞一個打開的套接字

[英]Perl - passing an open socket across fork/exec

我希望有一個Perl守護進程監聽接受來自客戶端的傳入連接,然后forkexec另一個Perl程序繼續與客戶端進行對話。

簡單地分叉時我可以做到這一點 - 守護進程代碼也包含子代碼。 但我沒有看到open socket如何通過exec()傳遞給另一個Perl程序。

不知怎的,我得到的印象是這在Unix(這是我的環境)中很容易,因此在Perl中也是如此。 真的可以嗎?

這可以通過大約三個步驟完成:

  1. 清除文件描述符上的close-on-exec標志。
  2. 告訴exec'd程序使用哪個文件描述符。
  3. 將文件描述符恢復為句柄。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM