Subject: | Handle to std channel broken by the DESTROY method of Win32::Console |
Perl version : ActivePerl 5.8.8 (MSWin32-x86-multi-thread), build 819
OS : Microsoft Windows XP Professional
Module version : Win32::Console 0.07
PROBLEM:
The handle to standard channel is broken if the DESTROY method of
Win32::Console is (implicitly) invoked.
CODE TO REPRODUCE THE PROBLEM:
_CODE_BEGIN_
use Win32::Console;
{
Win32::Console->new(Win32::Console::STD_OUTPUT_HANDLE());
} # note that the Win32::Console "new" call is enclosed in a block
print "Hello\n";
_CODE_END_
SYMPTOM:
No "Hello" is displayed.
WHO'S GUILTY ?:
The guilty party is the DESTROY method of Win32::Console (implicitly
invoked at the end of the enclosing block), which calls the Win32 API
CloseHandle. This guilt can be revealed with the simple following code :
_CODE_BEGIN_
use Win32API::File;
Win32API::File::CloseHandle(Win32API::File::GetOsFHandle(STDOUT));
print "Hello\n";
_CODE_END_
EXPLANATION ATTEMPT:
The Win32::Console DESTROY method closes the file handle at the Windows
layer, and doesn't worry about the associated file handle at the Perl
layer (STDOUT in the present case). So finally, STDOUT points to a
closed Windows native file handle.
WORKAROUND:
After the DESTROY method has been invoked (might need a fine analysis on
some existing code), closing (explicitly) the Perl file handle, and
re-opening it.
e.g., to re-open the standard channels on the console (classical use) :
for STDOUT or STDERR :
close STDxxx;
open STDxxx, '>CONOUT$';
for STDIN :
close STDIN;
open STDIN, '+<CONIN$';
CORRECTION SUGGESTION:
Win32::Console does not create (*) - nor open, nor duplicate - some
Windows file handle... so, why closing it in the DESTROY method ?
(*) In opposition to what is written in the Win32::Console documentation
for the "new" method : the "new" method actually simply "gets" a
standard handle, it does not "creates" it, does it ?
P.S.:
I only talked about the standard channel mode of Win32::Console. Is the
console screen buffer mode also concerned ? I don't know.