
![]() | ![]() |
15.8. Using POSIX termios
15.8.1. Problem
You'd like to manipulate your
terminal characteristics
directly.
15.8.2. Solution
Use the POSIX termios interface.
15.8.3. Description
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.
Example 15-2. demo POSIX termios
#!/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;
15.8.4. See Also
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
![]() | ![]() | ![]() |
15.7. Ringing the Terminal Bell | ![]() | 15.9. Checking for Waiting Input |

Copyright © 2003 O'Reilly & Associates. All rights reserved.