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

Dear Monks,
I'm working on implementing a simple data entry thingy and connect to an AnyEvent::Handle via the telnet command-line program. I'm trying to get it to not just "read" on getting a newline, but also on pressing arrow keys. I know that I can register a different EOL character via ::Handle's push_read() method, but I haven't got it to work on my terminal, btw. which is Ubuntu's default, where I then run the default telnet command.

What *does* work is a procedure like:
  1. I enter a "right arrow",
  2. the terminal then echoes the char "^[[C") and
  3. I press ENTER after that,
  4. the "special arrow char" is transmitted.
Of course, as ::Handle by default operates on the newline/carriage-return and transmits all the stuff before that.


My second hunch was that maybe telnet always only transmits upon ENTER, but I've tried other people's telnet applications where my telnet DOES transmit arrow keys and also the local echo'ing of the special arrow keys on my end is suppressed. How does that work? Do such applications send a special "handshake" that puts my telnet + shell into "application mode" or how is such a remote telnet handle configured to munge chars terminated by a newline/ENTER *and* special key input, like arrow keys?

I hope someone with knowledge from the olden times when telnet was in vogue can shed some light. If that's possible with AnyEvent::Handle. And how I can go forth from here.
Thanks a ton already!
  • Comment on How do I get AnyEvent::Handle to munge arrow keys?

Replies are listed 'Best First'.
Re: How do I get AnyEvent::Handle to munge arrow keys?
by soonix (Chancellor) on Dec 09, 2022 at 21:37 UTC
    Sounds like IO::Stty might be(come) your friend, and/or stty(1).
    In both cases, you'd want "raw" vs. "cooked".
      Any more help? As much as I value your input (and I did already learn a bit more, as to where obstacles might be) - I'd need a little help to understand if what I have in mind is generally doable with AnyEvent::Handle. My current tasks are poking around in what ::Handle internally does and see if I need to get in-between ::Socket and ::Handle for a solution.

      My current idea is that the $filehandle I get from ::Handle isn't the same as the real raw $filehandle connected by ::Socket. Could that be true? Would I need to get access to this lower-level $filehandle? For example, I tried the chars() method from Term::Size::Any on ::Handle's internal $fh - result: undefined. So this doesn't automagically work.
      Also, for example, am I able to catch the signal WINCH (issued on window resize events) from the remote terminal on a connected socket/filehandle if this remote terminal is connected via Telnet?

      Or am I completely on the wrong track?

        Can't help with AnyEvent. The reason why I suggested stty is that Telnet is mostly line oriented.

        I guess that SIGWINCH usually is passed through, but in fact that depends on the Telnet server (and on the client).
Re: How do I get AnyEvent::Handle to munge arrow keys?
by isync (Hermit) on Jan 05, 2023 at 01:24 UTC
    Four weeks later, I can answer my own post:
    Terminal (VT100ß) "Application mode" is something different - forget this term.
    What you want is a "raw" (character at a time) tty connection, vs a "cooked" (line at a time) connection. Read the Wikipedia articles on Terminal mode and Line discipline, and this article: BBS FAQ, the whole section on how "lightbars" in BBS work. There you'll learn about how Telnet can switch the TTY "line discipline" buffer into "character mode" (just pass through, immediately). In character mode, your terminal, via Telnet, sends all key strokes as they happen, not waiting for Enter or EOT. Telnet is configured via the IAC marker mechanism, it requires to handle SGA and ECHO settings to tell Telnet to start character mode.