Use the POSIX termios interface.
Think of everything you can do with the stty command—you 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
Copyright © 2003 O'Reilly & Associates. All rights reserved.