Friday, March 12, 2010

Creating Copy of File handles in Perl/Redirecting STDOUT to a file and screen

To Create an independent copy of file descriptor for the file handle: Use open with & mode
open(OLDOUT, ">&STDOUT" ) or die "Couldn't dup STDOUT: $!";
open(OLDIN, "<&STDIN" ) or die "Couldn't dup STDIN : $!";

Use open with the &= mode to create an alias for that filehandle's file descriptor:
open(OUTALIAS, ">&=STDOUT") or die "Couldn't alias STDOUT: $!";
open(INALIAS, "<&=STDIN") or die "Couldn't alias STDIN : $!";
open(BYNUMBER, ">&=5") or die "Couldn't alias file descriptor 5: $!";

If we try to create a copy of any file handle descriptor then actually we are calling dup (2) system call, by this we get two independent file descriptors whose file position, locks, and flags are shared, but which have independent stdio buffers. We can close any of file descriptor, which will not affect the other one.

But If we try to create a alias of any file handle then actually we are calling fdopen (3) stdio function. We get a single file descriptor with two stdio buffers accessed through two filehandles. Closing one filehandle closes the file descriptor of any aliases, but not their filehandles

# take copies of the file descriptors
open(OLDOUT, ">&STDOUT");
open(OLDERR, ">&STDERR");

# redirect stdout and stderr
open(STDOUT, "> /tmp/program.out")  or die "Can't redirect stdout: $!";
open(STDERR, ">&STDOUT")            or die "Can't dup stdout: $!";

# run the program
system($joe_random_program);

# close the redirected filehandles
close(STDOUT)                       or die "Can't close STDOUT: $!";
close(STDERR)                       or die "Can't close STDERR: $!";

# restore stdout and stderr
open(STDERR, ">&OLDERR")            or die "Can't restore stderr: $!";
open(STDOUT, ">&OLDOUT")            or die "Can't restore stdout: $!";

# avoid leaks by closing the independent copies
close(OLDOUT)                       or die "Can't close OLDOUT: $!";
close(OLDERR)                       or die "Can't close OLDERR: $!";

No comments:

Post a Comment