[comp.lang.perl] grabchars in perl?

rjm@vulcan.anu.edu.au (Robert J. McArthur) (06/05/91)

Has anyone implemented the grabchars package in perl?

For those who don't know, grabchars is a PD program from comp.sources.misc
that implements timed reads from ttys and non-CR-requiring input.  eg. you
can  just type one letter in answer to a y/n question without needing the
CR.

Robert
-- 
Robert McArthur			Centre for Resource and Environment Studies
	     				     Australian National University
ACSNet                   rjm@arp.anu.oz.au	       ACT  Australia  2601
Pegasus|PeaceNet|EcoNet  peg:robert	     		      (06) 249 4760

tchrist@convex.COM (Tom Christiansen) (06/05/91)

From the keyboard of rjm@vulcan.anu.edu.au (Robert J. McArthur):
:Has anyone implemented the grabchars package in perl?
:
:For those who don't know, grabchars is a PD program from comp.sources.misc
:that implements timed reads from ttys and non-CR-requiring input.  eg. you
:can  just type one letter in answer to a y/n question without needing the
:CR.

Use "system stty" or ioctl to get yourself in the moral equivalent of
cbreak mode (per FAQ #16).  Use an ioctl if you're going to be doing a lot
of these.  Use system if you're only running it once.

Then set a timer with alarm (or SYS_setitimer if you have it and want that
granularity).  If your reads don't continue after interruptions, then just
return from your interrupt routine.  If they do, you need a
setjmp/longjmp, so do the getc in an eval, and have your interrupt routine
die, effectively longjumping out of the eval.

    sub BANG { die "alarm went off"; }
    $SIG{'ALRM'} = 'BANG';
    system "stty cbreak </dev/tty >/dev/tty 2>&1";
    print "go\n";
    alarm 2; $key = eval "getc(STDIN)"; alarm 0;
    if (!defined($key)) { 
	die $@ if $@ && $@ !~ /alarm/; # not my exception?
	print "timeout!\n";
    } else {
	printf "\nkey was %s (0x%x)\n", $key, ord($key);
    } 
    system "stty cooked </dev/tty >/dev/tty 2>&1";

I believe that this code needs 4.003 to work correctly.  Again, you
poor folks (SysV, POSIX) with non-restarting reads don't need to worry 
about the eval.  I wish perl gave me more control here, but I'm at
the mercy of my C library, and getting at the SV_INTERRUPT bit is 
non-trivial.


--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
	    "Perl is to sed as C is to assembly language."  -me

daniel@world.std.com (Daniel Smith) (06/05/91)

In <1991Jun5.052344.22684@newshost.anu.edu.au> rjm@vulcan.anu.edu.au (Robert J. McArthur) writes:

> Has anyone implemented the grabchars package in perl?

> For those who don't know, grabchars is a PD program from comp.sources.misc
> that implements timed reads from ttys and non-CR-requiring input.  eg. you
> can  just type one letter in answer to a y/n question without needing the
> CR.


	wow, they're using in Australia and Moscow and Berlin and...

	I wrote grabchars, and will see if I can do a port sometime in the
next week.  I had been thinking of doing a 2.0 C version that would handle
function/arrow keys, allow templates (like: 2 lower case letters, then a
number, then 3 upper case letters) and perhaps a little more.  Have to 
resist the creeping feature syndrome (as well as I can!).

	For the moment, grabchars can be called from perl.  If anyone is
interested in collaborating, let me know.

				Daniel
-- 
daniel@island.com  .....Daniel Smith, Island Graphics, (415) 491 0765 x 250(w)
daniel@world.std.com ...4000 CivicCenterDrive SanRafael MarinCounty CA 94903
dansmith@well.sf.ca.us .I must write this, or Island will take away my coffee.
Could we continue with the petty bickering? I find it most intriguing-Data:TNG