代码之家  ›  专栏  ›  技术社区  ›  Sergey L.

perl多管CLOEXEC

  •  1
  • Sergey L.  · 技术社区  · 10 年前

    我试图在perl中为同一个分叉进程设置多个管道。这是一个最小的例子,只有一个,但最后我希望这样有多个管道:

    #!/usr/bin/perl
    
    use Fcntl;
    
    pipe PIPEREAD, PIPEWRITE;
    
    # is supposed to increase the max file descriptors
    $^F = 255; # default is 2
    
    $flags = fcntl(PIPEREAD, F_GETFL, 0);
    # doesn't do anything 
    fcntl(PIPEREAD, F_SETFL, $flags & (~FD_CLOEXEC)) or die "Can't set flags: $!\n";
    
    if (!fork()) {
        exec("cat", "/dev/fd/" . fileno(PIPEREAD));
    }
    
    print PIPEWRITE "Test\n";
    close PIPEWRITE;
    
    sleep(1);
    

    此操作失败,因为上面的所有文件描述符 2 当我调用exec时关闭。我如何防止这种行为?

    失败的原因

    cat: /dev/fd/3: No such file or directory
    

    我已尝试取消设置 FD_CLOEXEC 标志和增加 $^F 。没有任何效果。

    2 回复  |  直到 10 年前
        1
  •  2
  •   Leon Timmermans    10 年前

    CLOEXEC 打开管道时设置正确,因此您必须设置 $^F 之前 跑步 pipe 。如果你改变那个顺序,对我来说很好,即使不用 fcntl .

    此外,如果要使用 文件锁 ,您需要使用 F_SETFD F_SETFL

        2
  •  2
  •   user2404501 user2404501    10 年前

    在perlvar(1)中写道:

    文件描述符的执行时关闭状态将根据打开相应文件、管道或套接字时$^F的值而不是“exec()”的时间来决定。

    所以,移动你的 $^F=255 在您的 pipe 它应该会起作用。