open my $fh, '<', '/dev/zero' or die "$!";
####
pipe my ($header_in, $header_out);
pipe my ($body_in, $body_out);
##
##
use Fatal qw( close );
close STDIN;
close STDOUT;
pipe my ($message_in, $message_out);
##
##
#!/usr/bin/perl
use strict;
use warnings;
use Fatal qw( close ); # monitored (auto-)close
close STDIN;
close STDOUT;
my %handle_for;
@handle_for{qw( message_in message_out )} = pipe_from(0);
@handle_for{qw( header_in header_out )} = pipe_from(4);
@handle_for{qw( body_in body_out )} = pipe_from(6);
print {*STDERR} "$_ has descriptor ", fileno($handle_for{$_}), "\n"
for sort { fileno($handle_for{$a}) <=> fileno($handle_for{$b}) }
keys %handle_for;
sub pipe_from { # Assuming consecutive numbers are ok
my ($n) = @_;
my @fakes;
while (1) {
open my $fh, '<', '/dev/zero' or die "open(): $!";
push @fakes, $fh;
last if fileno($fh) == $n;
die "file descriptor $n not available" if fileno($fh) > $n;
} ## end while (1)
close pop @fakes; # Free last used descriptor, that's equal to $n
pipe my ($r, $w);
die "pipe(): $!" unless defined $r;
close $_ for @fakes;
return ($r, $w);
} ## end sub pipe_from
__END__
poletti@PolettiX:~/sviluppo/perl$ perl pipes.pl
message_in has descriptor 0
message_out has descriptor 1
header_in has descriptor 4
header_out has descriptor 5
body_in has descriptor 6
body_out has descriptor 7
##
##
while (1) {
open my $fh, '<', '/dev/zero' or die "open(): $!";
last if fileno($fh) == $n;
die "file descriptor $n not available" if fileno($fh) > $n;
push @fakes, $fh;
} ## end while (1)