Skip Menu |

This queue is for tickets about the Win32-Console CPAN distribution.

Report information
The Basics
Id: 59322
Status: open
Priority: 0/
Queue: Win32-Console

People
Owner: Nobody in particular
Requestors: chm [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.09
Fixed in: (no value)



Subject: SetConsoleCtrlHandler function not supported
A persistent and pernicious problem with using perl from the win32 console is the fact that Ctrl-C can not be caught. This makes it very difficult to implement cross-platform code that works on win32. If SetConsoleCtrlHandler() were available to handle these "signals" that would prevent Ctrl-C in a Term::ReadLine::Perl session in a CMD shell window from killing the perl instance and even the CMD shell if the exit routine query is not answered in the negative. I notice that there is commented out code for just this in the 0.09 version of Win32::Console. Is there a reason it was not enabled? Even a limited implementation that keeps perl and the CMD shell from exiting would be a huge win. --Chris
CC: libwin32 [...] perl.org
Subject: Re: [rt.cpan.org #59322] SetConsoleCtrlHandler function not supported
Date: Wed, 14 Jul 2010 17:00:32 -0700
To: bug-Win32-Console [...] rt.cpan.org
From: Bill Luebkert <dbecoll [...] roadrunner.com>
Chris Marshall via RT wrote: Show quoted text
> Tue Jul 13 12:59:28 2010: Request 59322 was acted upon. > Transaction: Ticket created by CHM > Queue: Win32-Console > Subject: SetConsoleCtrlHandler function not supported > Broken in: 0.09 > Severity: Important > Owner: Nobody > Requestors: chm@cpan.org > Status: new > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=59322 > > > A persistent and pernicious problem with using perl > from the win32 console is the fact that Ctrl-C can > not be caught. This makes it very difficult to implement > cross-platform code that works on win32. > > If SetConsoleCtrlHandler() were available to handle > these "signals" that would prevent Ctrl-C in a > Term::ReadLine::Perl session in a CMD shell window > from killing the perl instance and even the CMD > shell if the exit routine query is not answered > in the negative. > > I notice that there is commented out code for just > this in the 0.09 version of Win32::Console. Is > there a reason it was not enabled? Even a limited > implementation that keeps perl and the CMD shell > from exiting would be a huge win.
Can't you already trap Ctrl-C in the script ? What happens when you run this ? : test.pl: my $cnt = 0; sub handler { print "Caught a SIG '$_[0]'\n"; exit if ++$cnt > 2; } $SIG{INT} = \&handler; while (1) { Win32::Sleep(100); } __END__ Show quoted text
> perl test.pl
^C (type Ctrl-C) Caught a SIG 'INT' ^C Caught a SIG 'INT' ^C Caught a SIG 'INT' Should catch Ctrl-C, print the message and exit after the 3rd time. Not sure if changing the sleep to your readline call would alter the result - try changing it.
On Wed Jul 14 20:00:48 2010, dbecoll@roadrunner.com wrote: Show quoted text
> Chris Marshall via RT wrote:
> > Tue Jul 13 12:59:28 2010: Request 59322 was acted upon. > > Transaction: Ticket created by CHM > > Queue: Win32-Console > > Subject: SetConsoleCtrlHandler function not supported > > Broken in: 0.09 > > Severity: Important > > Owner: Nobody > > Requestors: chm@cpan.org > > Status: new > > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=59322 > > > > > A persistent and pernicious problem with using perl > > from the win32 console is the fact that Ctrl-C can > > not be caught. This makes it very difficult to implement > > cross-platform code that works on win32. > > > > If SetConsoleCtrlHandler() were available to handle > > these "signals" that would prevent Ctrl-C in a > > Term::ReadLine::Perl session in a CMD shell window > > from killing the perl instance and even the CMD > > shell if the exit routine query is not answered > > in the negative. > > > > I notice that there is commented out code for just > > this in the 0.09 version of Win32::Console. Is > > there a reason it was not enabled? Even a limited > > implementation that keeps perl and the CMD shell > > from exiting would be a huge win.
> > Can't you already trap Ctrl-C in the script ? > What happens when you run this ? : > > test.pl: > > my $cnt = 0; > sub handler { print "Caught a SIG '$_[0]'\n"; exit if ++$cnt > 2; } > $SIG{INT} = \&handler; > while (1) { Win32::Sleep(100); } > __END__ >
> > perl test.pl
> ^C (type Ctrl-C) > Caught a SIG 'INT' > ^C > Caught a SIG 'INT' > ^C > Caught a SIG 'INT' > > Should catch Ctrl-C, print the message and exit after the 3rd time. > Not sure if changing the sleep to your readline call would alter the > result - try changing it.
I think it has something to do with the Term::ReadLine stuff. If I run the perldl shell, end then type Ctrl-C followed by <Enter> I get the following: Show quoted text
perldl> # Typed Ctrl-C perldl> # Typed <Enter>
Show quoted text
perldl> # Typed Ctrl-C perldl> # Typed <Enter>
Show quoted text
perldl> # Typed Ctrl-C perldl> # Typed <Enter>
(Although sometimes extra newline for some reason) Show quoted text
perldl> # Typed Ctrl-C and then again without <Enter> perldl> Ctrl-C detected
END failed--call queue aborted at C:\chm\strawberry\perl\bin/perldl line 550. Terminate batch job (Y/N)? n C:\chm\strawberry> So the problem appears that the 1st Ctrl-C is caught but something in the readline part prevents reloading of the signal handler so an immediate Ctrl-C will send another "SIGINT" which will not be caught and then the console control handler will be called which offers to exit the CMD console. (Presumably, the default handler was also called from the 2nd Ctrl-C in perl which is why that application exited.... I think I've convinced myself it is tied in with the Term::ReadLine::Perl stuff but don't know how it could be fixed. If that is the case, having the missing SetConsoleCtrlHandler() routine might not help either. --Chris
http://bytes.com/topic/perl/answers/50015-signal-handling-term-readline-problem-perl This problem report at bytes.com is *exactly* the behavior that is the problem for me as well. No answer for them that I saw....
CC: libwin32 [...] perl.org
Subject: Re: [rt.cpan.org #59322] SetConsoleCtrlHandler function not supported
Date: Thu, 15 Jul 2010 02:30:32 -0700
To: bug-Win32-Console [...] rt.cpan.org
From: Bill Luebkert <dbecoll [...] roadrunner.com>
Chris Marshall via RT wrote: Show quoted text
> > So the problem appears that the 1st Ctrl-C is caught > but something in the readline part prevents reloading > of the signal handler so an immediate Ctrl-C will > send another "SIGINT" which will not be caught and > then the console control handler will be called which > offers to exit the CMD console. (Presumably, the > default handler was also called from the 2nd Ctrl-C > in perl which is why that application exited.... > > I think I've convinced myself it is tied in with the > Term::ReadLine::Perl stuff but don't know how it > could be fixed. If that is the case, having the > missing SetConsoleCtrlHandler() routine might not > help either.
Looks like 1) you have to stop reading after you get an EOF from readline; 2) readline seems to catch the first ^C and quits working after that - then you can catch ^C OK; 3) you can't create a new Readline obj after it fails. New test case: use strict; use warnings; use Term::ReadLine; $| = 1; my $cnt = 0; sub handler { print "Caught a SIG '$_[0]' - continuing\n"; die "Got three" if ++$cnt > 2; } $SIG{INT} = \&handler; my $term = new Term::ReadLine 'ProgramName'; while (1) { my $input = $term->readline('prompt> '); if (not defined $input) { print "EOF on input\n"; } elsif ($input eq 'q') { print "quitting\n"; exit; } else { printf "Got: '%s'\n", $input; } Win32::Sleep(1000); # stop runaway console } __END__ There's definitely some work that could be done in readline to make this a little more friendly and some docs to go with.
Thanks for the replies and code examples. I still see the same behavior in the perldl shell and the Devel::REPL shell on win32 but the structure there is tricky enough that I can't see what's wrong in the full code. Of course, the problem is more annoying since it does not show up on non-win32 (including cygwin) perls. I'll see about whittling down the code to see how small I can get with the problem and maybe I'll see the bug or have a better example to post. This has been a persistent problem for win32 usage with the PDL shell. Regards, Chris On Thu Jul 15 05:30:45 2010, dbecoll@roadrunner.com wrote: Show quoted text
> > Looks like 1) you have to stop reading after you get an EOF > from readline; 2) readline seems to catch the first ^C and > quits working after that - then you can catch ^C OK; 3) you > can't create a new Readline obj after it fails. > > New test case: > ...snip...