You'd like to manipulate your terminal characteristics directly.
Use the POSIX termios interface.
Think of everything you can do with the stty commandyou can set everything from special characters to flow control and carriage-return mapping. The standard POSIX module provides direct access to the low-level terminal interface to implement stty-like capabilities in your program.
Example 15-2 finds what your tty's erase and kill characters are (probably backspace and Ctrl-U). Then it sets them back to their original values out of antiquity, # and @, and has you type something. It restores them when done.
#!/usr/bin/perl -w # demo POSIX termios use POSIX qw(:termios_h); $term = POSIX::Termios->new; $term->getattr(fileno(STDIN)); $erase = $term->getcc(VERASE); $kill = $term->getcc(VKILL); printf "Erase is character %d, %s\n", $erase, uncontrol(chr($erase)); printf "Kill is character %d, %s\n", $kill, uncontrol(chr($kill)); $term->setcc(VERASE, ord('#')); $term->setcc(VKILL, ord('@')); $term->setattr(1, TCSANOW); print("erase is #, kill is @; type something: "); $line = <STDIN>; print "You typed: $line"; $term->setcc(VERASE, $erase); $term->setcc(VKILL, $kill); $term->setattr(1, TCSANOW); sub uncontrol { local $_ = shift; s/([\200-\377])/sprintf("M-%c",ord($1) & 0177)/eg; s/([\0-\37\177])/sprintf("^%c",ord($1) ^ 0100)/eg; return $_; }
Here's a module called HotKey that implements a readkey function in pure Perl. It doesn't provide any benefit over Term::ReadKey, but it shows POSIX termios in action:
# HotKey.pm package HotKey; @ISA = qw(Exporter); @EXPORT = qw(cbreak cooked readkey); use strict; use POSIX qw(:termios_h); my ($term, $oterm, $echo, $noecho, $fd_stdin); $fd_stdin = fileno(STDIN); $term = POSIX::Termios->new( ); $term->getattr($fd_stdin); $oterm = $term->getlflag( ); $echo = ECHO | ECHOK | ICANON; $noecho = $oterm & ~$echo; sub cbreak { $term->setlflag($noecho); # ok, so i don't want echo either $term->setcc(VTIME, 1); $term->setattr($fd_stdin, TCSANOW); } sub cooked { $term->setlflag($oterm); $term->setcc(VTIME, 0); $term->setattr($fd_stdin, TCSANOW); } sub readkey { my $key = ''; cbreak( ); sysread(STDIN, $key, 1); cooked( ); return $key; } END { cooked( ) } 1;
POSIX Programmer's Guide, by Donald Lewine; the documentation for the standard POSIX module, also in Chapter 32 of Programming Perl; Recipe 15.6; Recipe 15.9