Domanda

I am trying to set up more then one pipe to the same forked process in perl. This is a minimal example with just one, but in the end I want to have multiple pipes this way:

#!/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);

This fails because all file descriptors above 2 are closed when I call exec. How can I prevent this behaviour?

Fails with

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

I have tried to both unset the FD_CLOEXEC flag and increase $^F. Nothing works.

È stato utile?

Soluzione

CLOEXEC is set right when the pipe is opened, so you have to set $^F before running pipe. If you switch that order, it works fine for me, even without using fcntl.

Also, if you want to set it using fcntl, you need to use F_SETFD, not F_SETFL

Altri suggerimenti

In perlvar(1) it says:

The close-on-exec status of a file descriptor will be decided according to the value of $^F when the corresponding file, pipe, or socket was opened, not the time of the "exec()".

So move your $^F=255 before your pipe and it should work.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top