Opening and Closing File Descriptors by Number

Problem

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

Solution

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.

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 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 ...

Get Perl Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.