Article 10101 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:10101
Path: feenix.metronet.com!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!pipex!uunet!olivea!koriel!sh.wide!wnoc-tyo-news!scslwide!wsgw!headgw!cvgw3!tshiono
From: [email protected] (Toru SHIONO)
Newsgroups: comp.lang.perl
Subject: Re: One Character
Message-ID: <[email protected]>
Date: 24 Jan 94 12:47:17 GMT
References: <[email protected]>
Sender: [email protected] (Usenet News System)
Organization: Sony Corporation, Tokyo, Japan
Lines: 45
Nntp-Posting-Host: aquarius
X-Newsreader: prn Ver 1.10
In-reply-to: [email protected]'s message of 20 Jan 94 14:55:36 GMT

In article <[email protected]>
       [email protected] (Gregg D. Brekke) writes:

:How do you grab just _ONE_ character from STDIN without a carriage return?
:
:I'm converting a bunch of utilities I wrote in C and would like to make
:them independent of outside routines.
:
:This would be akin to setting raw mode in C to read one character.
:i.e. The C code reads:
:
:char one_char ()
:{
:       struct sgttyb orig, myttyb;
:  char c;
:
:        ioctl (fileno(stdin), TIOCGETP, &myttyb)
:       orig = myttyb;
:  myttyb.sg_flags |= (RAW);
:        ioctl (fileno(stdin), TIOCSETP, &myttyb)
:        read(0, &c, 1);
:        ioctl (fileno(stdin), TIOCSETP, &orig)
:  return (c);
:}

Perl version may look like:

require 'sys/ioctl.ph';

sub one_char {
   ioctl(STDIN, &TIOCGETP, $sgo);
   $sgn = $sgo;
   @array = unpack('ccccs', $sgn);
   $array[4] |= &RAW;
   $sgn = pack('ccccs', @array);
   ioctl(STDIN, &TIOCSETP, $sgn);
   read(STDIN, $c, 1);
   ioctl(STDIN, &TIOCSETP, $sgo);
   $c;
}

It will be better to replace '&RAW' with '&CBREAK' and write
a proper signal handler to trap interrupts.
--
Toru "devil-may-care" Shiono          Sony Corporation, JAPAN