extra printout with Term::ReadKey

L

lucas

I'm using Term::ReadKey, and I'm not sure why, but it prints out extra
characters, every few characters, it'll print out an extra byte, as you can
see below:
bash-2.05a$ perl x
abccdefgg << this is what is displayed
[abcdefg] << this is what was actually typed

I pulled this out of my program, and I can recreate the problem exactly with
this:

use Term::ReadKey;
open(TTY, "</dev/tty"); #read from terminal (keyboard)
my $ttybuf = '';
while (1) {
ReadMode "raw";
if($key = ReadKey -1, *TTY) {
ReadMode "normal";
if (ord($key) == 27) { die "\nEscaping\n"; }
elsif (ord($key) == 3) { die "\nSIGINT Caught\n"; }
elsif (ord($key) == 127){ print "\x08\x20\x08"; chop($ttybuf); }
#print destructive backsapce
else {
print $key; #<<<this is the line that prints out each key stroke
if (ord($key) == 10) { print "[$ttybuf]\n"; undef($ttybuf); }
else { $ttybuf .= $key; } #save all keystrokes in buffer
}
}
else { ReadMode "normal"; }
}


I've been hammering at this for awhile, but I can't figure out why extra
bytes are printed out. If there is a better way, or a fix, plz let me
know, and if you can think of a better destructive backspace, paste it :)

thx
 
L

lucas

I found the problem in the second last line:
else { ReadMode "normal"; }

When I comment that out, it all works perfectly. Except I need it there.
In my actual program, there is more code after that section that reads from
a socket, and prints to STDOUT, which means I need to have the ReadMode set
to 'normal'.

What I think is happening is, there is a race condition, and I hit a key,
just after the if($key = ReadKey -1, *TTY) { has passed, and the
else { ReadMode "normal"; } echos it to STDOUT.

I still need a fix tho.

I've also been working on something like the following:
while(1) {
if (vec($rout, fileno(STDIN), 1)) {
print "found input\n";
}
}

But I can't get that to work.
 
A

Anno Siegel

lucas said:
I found the problem in the second last line:
else { ReadMode "normal"; }

When I comment that out, it all works perfectly. Except I need it there.
In my actual program, there is more code after that section that reads from
a socket, and prints to STDOUT, which means I need to have the ReadMode set
to 'normal'.

What I think is happening is, there is a race condition, and I hit a key,
just after the if($key = ReadKey -1, *TTY) { has passed, and the
else { ReadMode "normal"; } echos it to STDOUT.

Sure. While the loop runs, read mode is "raw" for part of the time
and "normal" for another. Depending on when you hit a key, you see
the (extra) echo or you don't. I wouldn't even call that a race
condition, it's just random.
I still need a fix tho.

Explain what you want to achieve.

Anno
 
L

lucas

Looks like I got it fixed...finally. It seems a bit slow, but good enough.
I just changed all the ReadMode "normal" to ReadMode "noecho".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top