Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Non-blocking read

by tomazos (Deacon)
on Nov 12, 2001 at 22:28 UTC ( [id://124876]=perlquestion: print w/replies, xml ) Need Help??

tomazos has asked for the wisdom of the Perl Monks concerning the following question:

How do you perform a non-blocking read from standard input?

I want to write an interactive script that I am going to run from a command-line.

I want it to do things and read input keystrokes that may be present at the same time.

To do this, I believe the best way would be to setup a tight loop that alternated between testing if there are any characters on the input and going on with it's tasks at the same time.

In order to do that I would need a call (similar to the flock non-blocking flag) that would tell me if new input is present yet and return immediately if it is not.

Any ideas?

Replies are listed 'Best First'.
Re: Non-blocking read
by wog (Curate) on Nov 12, 2001 at 23:11 UTC
    Probably the easiest, and most portable (since, apparently, Windows perl only supports select for sockets, not to mention that it probably doesn't support termios.), way to do this would be to use Term::ReadKey:

    use Term::ReadKey; for (;;) { if (defined(my $c = ReadKey(-1))) { # got a character $c, process } # do other stuff }
Re: Non-blocking read
by kwoff (Friar) on Nov 12, 2001 at 22:43 UTC
    Use select. Example in the while loop below:
    #!/usr/local/bin/perl -w use strict; BEGIN { # from Camel book 2nd ed. p.474 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); $term->setcc(VTIME, 1); $term->setattr($fd_stdin, TCSANOW); } sub cooked { $term->setlflag($oterm); $term->setcc(VTIME, 0); $term->setattr($fd_stdin, TCSANOW); } } END { cooked(); } cbreak(); while (1) { my ($rin, $rout, $nfound); $rin = ''; vec($rin, fileno(STDIN), 1) = 1; if ($nfound = select($rout=$rin, undef, undef, 0.001)) { my ($key); sysread(STDIN, $key, 1); if ($key eq 'j') { print "It was j!\n"; } elsif ($key eq 'q') { print "I'm melting!\n"; exit; } } }
Re: Non-blocking read
by Anonymous Monk on Nov 13, 2001 at 19:29 UTC
    If you're on a Unix like system you can user termios to set a timeout. Will a timeout do what you want?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://124876]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-03-28 21:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found