perl で exec 後に file descriptor を渡す
通常は 0, 1, 2 しか渡されない。
open my $fh, ">", "file.txt"; exec "ls", "-al", "/proc/$$/fd";
> perl test.pl total 0 dr-x------ 2 skaji skaji 0 Mar 29 03:04 . dr-xr-xr-x 9 skaji skaji 0 Mar 29 03:04 .. lrwx------ 1 skaji skaji 64 Mar 29 03:04 0 -> /dev/pts/5 lrwx------ 1 skaji skaji 64 Mar 29 03:04 1 -> /dev/pts/5 lrwx------ 1 skaji skaji 64 Mar 29 03:04 2 -> /dev/pts/5 lr-x------ 1 skaji skaji 64 Mar 29 03:04 3 -> /proc/20500/fd
(注:3 -> /proc/20500/fd
は ls 自身が開いたもの)
方法1 : FD_CLOEXEC を 0 にする
use Fcntl; open my $fh, ">", "file.txt"; fcntl $fh, F_SETFD, 0; # FD_CLOEXEC を 0 に exec "ls", "-al", "/proc/$$/fd";
> perl test.pl total 0 dr-x------ 2 skaji skaji 0 Mar 29 03:07 . dr-xr-xr-x 9 skaji skaji 0 Mar 29 03:07 .. lrwx------ 1 skaji skaji 64 Mar 29 03:07 0 -> /dev/pts/5 lrwx------ 1 skaji skaji 64 Mar 29 03:07 1 -> /dev/pts/5 lrwx------ 1 skaji skaji 64 Mar 29 03:07 2 -> /dev/pts/5 l-wx------ 1 skaji skaji 64 Mar 29 03:07 3 -> /home/skaji/file.txt lr-x------ 1 skaji skaji 64 Mar 29 03:07 4 -> /proc/20651/fd
方法2 : $^F をいじる
perldoc -v '$^F'
曰く、$^F 以下の file descriptor のみ exec に渡すらしい。よってこれを大きくすれば渡せる。
my $fh; { local $^F = 10; open $fh, ">", "file.txt"; } exec "ls", "-al", "/proc/$$/fd";
SEE ALSO
- perldoc -v '$^F'
- man fcntl
- https://github.com/kazuho/p5-Server-Starter
fcntl($sock, F_SETFD, my $flags = '')
のmy $flags = ''
とする理由がよくわからない。