Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Well, opening the fd you like isn't difficult at all, as dave_the_m suggested - even if I have to admit that things might be less portable than I'm impling here. Pragmatically, what I see in my Linux system is that the lowest available file descriptor is always going to be used.

The first thing you have to pay attention to is the starting file descriptor. For a brand new process, you should get 0, 1 and 2 assigned to standard input, standard output and standard error resp. (I know you *already* know this, but bear with me). So, if you really want to start from 4 instead of 3 (I wonder why, but I'm sure you have a good reason), you first have to do a fake open to get the spare file descriptor:

open my $fh, '<', '/dev/zero' or die "$!";
Then, pipe calls come in pairs, so you can get the couples you want:
pipe my ($header_in, $header_out); pipe my ($body_in, $body_out);
To take into account your need for handles 0 and 1 as well:
use Fatal qw( close ); close STDIN; close STDOUT; pipe my ($message_in, $message_out);

The best thing to do is probably write a subroutine for this:

#!/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 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
I know, using this for each pair means that you will re-open fake handles for lower descriptors at each call. Feel free to optimise, if you think this is really needed :)

Update: if you're wondering why I'm explicitly close-ing the handles instead of letting scoping do its work, I have to admit that I've been biten by this. In particular, I noted that the file descriptor 0 wasn't released when getting out of the while. If anyone can shed a light on it I'd be grateful! This was the original loop:

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)
and of course I had no close pop @fakes; line after it. I thought that it could be that any time you open file descriptor 0, you can access it via STDIN (that is *STDIN{IO}), so when $fh goes out of scope the handle's reference count does not drop to zero, and auto-closing is not triggered.

Hey! Up to Dec 16, 2007 I was named frodo72, take note of the change! Flavio
perl -ple'$_=reverse' <<<ti.xittelop@oivalf

Io ho capito... ma tu che hai detto?

In reply to Re^2: Open a file on a specific file descriptor? by polettix
in thread Open a file on a specific file descriptor? by benizi

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    Domain Nodelet?
    and the web crawler heard nothing...

    How do I use this?Last hourOther CB clients
    Other Users?
    Others perusing the Monastery: (5)
    As of 2024-07-12 21:35 GMT
    Find Nodes?
      Voting Booth?

      No recent polls found

      erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.