You know which file descriptors you'd like to do I/O on, but Perl requires filehandles, not descriptor numbers.
To open the file descriptor, use the
"<&="
or
"<&"
open modes or the IO::Handle module's
fdopen
class method:
open(FH, "<&=$FDNUM"); # open FH to the descriptor itself open(FH, "<&$FDNUM"); # open FH to a copy of the descriptor use IO::Handle; $fh->fdopen($FDNUM, "r"); # open file descriptor 3 for reading
To close one by number, either use the
POSIX::close
function or else first open it as we did previously.
Occasionally you have a file descriptor but no filehandle. Perl's I/O system uses filehandles instead of file descriptors, so you have to make a new filehandle for an already open file descriptor. The
"<&"
,
">&"
, and
"+<&"
modes to
open
will do this for reading, writing, and updating respectively. Adding an equal sign to these to make
"<&="
,
">&="
, and
"+<&="
is more parsimonious of file descriptors and nearly always what you want to do. That's because it used only a C-level
fdopen
function, not a
dup2
system call.
If you have version 5.004 or better installed, you can use the IO::Handle object method. This is the same as:
use IO::Handle; $fh = IO::Handle->new(); $fh->fdopen(3, "r"); # open fd 3 for reading
Closing a file descriptor by number is even rarer. The
POSIX::close
function does so directly. If your system doesn't have a working POSIX library but does have a working
syscall
(and your sysadmin has installed the
sys/syscall.ph
file created with the
h2ph
translator), you can call the not very portable
syscall
function. It has peculiar parameters and return values: You have to add 0 to numbers and append the empty string (
""
) to strings to coerce them to the right types for C, and the error return value is -1 rather than false as in other Perl calls. Needless to say, use
syscall
only as a last resort.
Here's how you'd open the file descriptors that the MH mail system feeds its child processes. It identifies them in the environment variable
MHCONTEXTFD
:
$fd = $ENV{MHCONTEXTFD}; open(MHCONTEXT, "<&=$fd") or die "couldn't fdopen $fd: $!"; # after processing close(MHCONTEXT) or die "couldn't close context file: $!";
If you want to close a descriptor by number, just
open
it first.
The
open
function in
perlfunc
(1) and in
Chapter 3
of
Programming Perl
; the documentation for the standard POSIX and IO::Handle modules (also in
Chapter 7
of
Programming Perl
); your system's
fdopen
(3) manpages
Copyright © 2001 O'Reilly & Associates. All rights reserved.