http://www.perlmonks.org?node_id=804331

gnosti has asked for the wisdom of the Perl Monks concerning the following question:

Hello Esteemed Monks,

I have an app using Tk's main window integrated with Term::ReadLine::Gnu in the terminal window. I would like to be able to clean up before exiting on Ctrl-C issued in either window.

With main window focus, I use Tk::bind to associate Ctrl-C with a callback (\&abort) that exits via CORE::exit. Although this causes a hard landing (segfault), the terminal functions normally afterwards.

With terminal window focus, the signal handler exits in the same way, however, after exiting, the terminal fails to echo the characters I type. Leaving via Tk::exit() results in the same echoless state, regardless of how it is invoked.

I suspect the line $OUT = $term->OUT || \*STDOUT (which I cut and pasted) of doing some redirection.

Update:This line provides an output filehandle, however all of my print statements output correctly without writing print $OUT $something.

I also looked at the Term::ReadLine methods such as rl_reset_terminal() without finding a solution.

Update: Issuing $term->rl_deprep_terminal() before exit() appears to solve the problem. (c.f 'man readline')

Here is my (revised) code:

use Tk; my $mw = MainWindow->new; $mw->bind('<Control-Key-c>' => \&abort); use Term::ReadLine; $SIG{INT} = \&abort; my $term = new Term::ReadLine(); loop(); sub loop { $term->tkRunning(1); $OUT = $term->OUT || \*STDOUT; while (1) { my ($user_input) = $term->readline("input>") ; process_line( $user_input ); } } sub abort { # do some cleanup $term->rl_deprep_terminal(); # Update! CORE::exit(); } sub process_line { print "user input: $_[0]\n" }
Update: Including $term->rl_deprep_terminal() in &abort appears sufficient to terminate the application.

Replies are listed 'Best First'.
Re: Echoless terminal state after exiting Tk/Term::ReadLine event loop (Solved!)
by zentara (Archbishop) on Nov 01, 2009 at 14:52 UTC
      Thanks. I have Tk and Term::ReadLine playing well together using the same basic code as this example.

      In the same project, I also have a use case where Tk is not running. I am using Event.pm there. From the link you provided, I see that event loops can live together. I'm also curious if I can simplify my code by using AnyEvent to provide the same interface, regardless of the underlying event loop.

        I see that event loops can live together.

        to be honest, it seems that you want to do complicated nested loop operations, but by using a distinct set of modules, which may or may not be thread safe or reliable together

        there is a solution, however.... the GLib module, which is the Perl interface to the glib, (upon which gtk2 is based.... so its on alot of systems.... firefox uses it on linux)

        So Glib has your basic eventloop, that has been well thought out..

        ...it works in threads....you can nest the loops.....you can give threads context, and priorities.... etc....

        So I would switch to GLib if you want looping complexity.....and for that matter.....the glib c library is pretty simple to code for basic loop recipes like timers and filehandle watching.....plus the c does a cleaner job of thread memory reclamation(as compared to Perl)..... it is so elegant in depth, that you probably could model the thought process with it


        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku