JavaScript EditorFreeware JavaScript Editor     Perl Tutorials 



Main Page Previous Section Next Section

Recipe 7.9 Opening and Closing File Descriptors by Number

7.9.1 Problem

You know which file descriptors you'd like to do I/O on, but Perl requires filehandles, not descriptor numbers.

7.9.2 Solution

To open the file descriptor, supply open with "<&=" or "<&" as the part of the file access mode, combined with a directional arrow:

open(FH, "<&=", $FDNUM)       # open FH to the descriptor itself
open(FH, "<&",  $FDNUM);      # open FH to a copy of the descriptor

Or use the IO::Handle module's new_from_fd class method:

use IO::Handle;
$fh = IO::Handle->new_from_fd($FDNUM, "r");

To close a file descriptor by number, either use the POSIX::close function or open it first as shown previously.

7.9.3 Discussion

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 from an already open file descriptor. The "<&", ">&", and "+<&" access modes to open do this for reading, writing, and updating, respectively. Adding an equals sign to these—making them "<&=", ">&=", and "+<&="—is more parsimonious of file descriptors and nearly always what you want. That's because the underlying implementation of Perl's open statement uses only a C-level fdopen(3) function from the C library, not a dup2(2) syscall that calls the kernel.

The new_from_fd IO::Handle object method is equivalent to:

use IO::Handle;

$fh = new IO::Handle;
$fh->fdopen($FDNUM, "r");            # open fd 3 for reading

Here's how you'd open 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: $!";

Closing a file descriptor by number is even rarer. If you've already opened a filehandle for the file descriptor you want to close, simply use Perl's close function on the filehandle. If don't have a filehandle for that file descriptor, the POSIX::close function closes a file descriptor by number:

use POSIX;

POSIX::close(3);              # close fd 3

7.9.4 See Also

The open function in perlfunc(1) and in Chapter 29 of Programming Perl; the documentation for the standard POSIX and IO::Handle modules (also in Chapter 32 of Programming Perl); your system's fdopen(3) manpages

    Main Page Previous Section Next Section
    


    JavaScript EditorJavaScript Verifier     Perl Tutorials


    ©