Windows uses file descriptors natively. See Low-Level I/O on MSDN. They all report errors through the C variable errno
, which means they show up in Perl's $!
.
Note that you can save yourself a bit of typing:
open(STDOUT, ">&=", $saveout) or ...;
This works because the documentation for open
in perlfunc provides:
If you use the 3-arg form then you can pass either a number, the name of a filehandle or the normal “reference to a glob.”
Finally, always include meaningful diagnostics when you call die
! The program below identifies itself ($0
), tells what it was trying to do (open
), and why it failed ($!
). Also, because the message doesn't end with a newline, die
adds the name of the file and line number where it was called.
my $fakefd = 12345;
open(STDOUT, ">&=", $fakefd) or die("$0: open: $!");
This produces
prog.pl: open: Bad file descriptor at foo.pl line 2.
According to the documentation for _fdopen
(because you used >&=
and not >&
), it has two failure modes:
If execution is allowed to continue, errno
is set either to EBADF
, indicating a bad file descriptor, or EINVAL
, indicating that mode was a null pointer.
The second would be a bug in perl and highly unlikely because I don't see anywhere in perlio.c
that involves a computed mode: they're all static strings.
Something appears to have gone wrong with $saveout
. Could $saveout
have been closed before you try to restore it? From your example, it's unclear whether you enabled the strict
pragma. If it's not lexical (declared with my
), are you calling a function that also monkeys with $saveout
?