Article 11235 of comp.lang.perl:
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!convex!cs.utexas.edu!math.ohio-state.edu!caen!uunet!amgen!richard!rbaumann
From: [email protected] (Richard Baumann)
Subject: Re: keyboard input without CR, CTRL-D problem..
Message-ID: <[email protected]>
Keywords: keyboard input, control char comparison
Sender: rbaumann@richard (Richard Baumann)
Nntp-Posting-Host: richard
Organization: AMGEN Inc.
References:  <[email protected]>
Distribution: usa
Date: Tue, 1 Mar 1994 14:47:15 GMT
X-Disclaimer: The opinions expressed are solely the user's and not those of Amgen.
Lines: 75

In article <[email protected]>, [email protected] () writes:
|>
|>    (some stuff omitted)
|>
|> Problem 3: Waiting for keyboard input
|>      How can I make the program run while checking for a keyboard entry in the
|>      background? How can interrupts be trapped/detected in PERL?
|>

The following is what I did, which works fine.  It checks to see whether the user
has pressed the enter key.  If so, it processes the first keystroke (if any) of
the keystrokes that preceded the enter key.  If not (enter key has not been
pressed) it does other things before checking for keyboard input again.

What I had originally wanted to do was detect any keystroke as soon as it was
made, without the user having to press the enter key.  But my experiments with
the select() function showed that the function does not know that keyboard input
is available until the enter key has been pressed.  I'd made two posts to this
newsgroup asking for anyone's experience on how to do that, but got no reply.

If you're willing to wait for the user to press enter to process the keyboard
input, then the following code excerpt allows the program to do other things
while keyboard input is not yet ready.

Hope this helps.

Richard L. Baumann
International Clinical Safety

#
#   Run the main program logic
#

   &InitializeEnvironment;

   $Menu = "main";
   $ProcessingUserCommands = 1;

   while ($ProcessingUserCommands)
       {
           &DoMenu("display");
           if (($Keystroke = &CaptureAnyAvailableKeystroke) eq "")
               {
                   #   The following "select" allows this process to
                   #   sleep for a tenth of a second before re-checking
                   #   for a keystroke.  Without this, the process would
                   #   quickly climb to around 90% of CPU usage

                   select(undef, undef, undef, 0.1);
               }
           else
               {
                   &DoMenu("process_keystroke", $Keystroke);
                   $NeedForManualRefresh = 1;
               }
       };

#
#   Subroutines
#

   sub CaptureAnyAvailableKeystroke
       {
           local($Keystroke);

           $rin = '';
           vec($rin, fileno(STDIN), 1) = 1;
           ($nfound, $ntimeleft) = select($rout=$rin, undef, undef, 0);

           if ($nfound != 0)
               {
                   #  return just the first character of what they entered
                   substr(<STDIN>, 0, 1);
               };
       }