Polling stdin...

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Polling stdin...

Matthew Percival
G'Day,

        I have been searching around on this topic, and have not come up with
anything substantial, so I suspect there is currently no option for
this, but I thought it best to ask, in case a skilled Lua programmer
knows a way.  Quite simply, I want to check stdin to see if there is
anything currently buffered, and only perform stdin:read() if there is.
As a simple example:

i = 1
while (i != 0) do
        if (stdin:read("*ready")) then -- somehow test if it's ready
                i = stdin:read("*all")
        else
                print "Looping again...\n"
end

        So, if the user ever types a 0, the loop will exit; if the user types
nothing, it will continually print on the screen.  Perhaps a bad
example, but a nice, simple one.  Can this be done, or would something
like this have to be written in first?

Thanks,

Matthew

Reply | Threaded
Open this post in threaded view
|

Re: Polling stdin...

Klaus Ripke
On Tue, Feb 07, 2006 at 08:39:48AM +1100, Matthew Percival wrote:

> G'Day,
>
> I have been searching around on this topic, and have not come up with
> anything substantial, so I suspect there is currently no option for
> this, but I thought it best to ask, in case a skilled Lua programmer
> knows a way.  Quite simply, I want to check stdin to see if there is
> anything currently buffered, and only perform stdin:read() if there is.
> As a simple example:
>
> i = 1
> while (i != 0) do
> if (stdin:read("*ready")) then -- somehow test if it's ready
> i = stdin:read("*all")
> else
> print "Looping again...\n"
> end
>
> So, if the user ever types a 0, the loop will exit; if the user types
> nothing, it will continually print on the screen.  Perhaps a bad
> example, but a nice, simple one.  Can this be done, or would something
> like this have to be written in first?
>
> Thanks,
>
> Matthew
>
if you really want to do idle waiting then setting
the file descriptor nonblocking should do;
most implementations of stdio should then return
nothing read or an error (instead of looping internally).

On *nix, using a wrapper like nb.c:
#include <fcntl.h>
#include <unistd.h>
int main (int argc, char **argv)
{
        fcntl(0, F_SETFL, O_NONBLOCK);
        return execvp(argv[1], argv+1);
}

you can have
nb lua -e 'while (not io.stdin:read(1)) do print "." end'
print dots until there is some input.

Another problem may be to have your terminal deliver
a single character without waiting for a newline.
Add some ioctls to the wrapper, or use
stty raw; nb lua -e '...'; stty sane


cheers
Reply | Threaded
Open this post in threaded view
|

Re: Polling stdin...

Mark Edgar
In reply to this post by Matthew Percival
Matthew Percival wrote:

> G'Day,
>
> I have been searching around on this topic, and have not come up with
> anything substantial, so I suspect there is currently no option for
> this, but I thought it best to ask, in case a skilled Lua programmer
> knows a way.  Quite simply, I want to check stdin to see if there is
> anything currently buffered, and only perform stdin:read() if there is.
> As a simple example:
>
> i = 1
> while (i != 0) do
> if (stdin:read("*ready")) then -- somehow test if it's ready
> i = stdin:read("*all")
> else
> print "Looping again...\n"
> end
>
> So, if the user ever types a 0, the loop will exit; if the user types
> nothing, it will continually print on the screen.  Perhaps a bad
> example, but a nice, simple one.  Can this be done, or would something
> like this have to be written in first?

I believe that this applies:

http://www.c-faq.com/osdep/readavail.html

In other words, there is no way to do this in standard C, as C does not
provide non-blocking I/O.

That being said, it is possible to write a C module for "console" I/O
which would provide this behavior on <insert-your-platform-of-choice>.

I don't know of any projects which do this.

                                        -Mark
Reply | Threaded
Open this post in threaded view
|

Re: Polling stdin...

Mark Edgar
Mark Edgar wrote:
> That being said, it is possible to write a C module for "console" I/O
> which would provide this behavior on <insert-your-platform-of-choice>.
>
> I don't know of any projects which do this.

OK, so I found LuaCurses:

http://mega.ist.utl.pt/~tngd/lua/lcurses.html

At this point you may say "But I don't want a full-screen terminal
application, I just want to read from the terminal asynchronously."

You'll find that most text-based applications are either CLI-based
(reading a line at a time from the user, perhaps using something like
readline) or curses-based (taking up the full terminal screen for the
time that they are running).  You'll want to decide which flavor
application you want to build, and then stick with that choice.  There's
really no middle ground here.

                                        -Mark
Reply | Threaded
Open this post in threaded view
|

Re: Polling stdin...

Klaus Ripke
On Mon, Feb 06, 2006 at 05:00:31PM -0700, Mark Edgar wrote:
> At this point you may say "But I don't want a full-screen terminal
> application, I just want to read from the terminal asynchronously."
.. or nonblocking, which is much different.
One asynchronous option is quite easy and actually used
by some applications like less when following a file:
the asynchronous input is Ctrl-C.  Unlike the nonblocking loop,
this interrupts the work done during each step
(depending on whether and how a signal handler is installed).

> You'll find that most text-based applications are either CLI-based
> (reading a line at a time from the user, perhaps using something like
> readline) or curses-based (taking up the full terminal screen for the
> time that they are running).  You'll want to decide which flavor
> application you want to build, and then stick with that choice.
I hardly resisted dropping a note on curses world domination
in my previous post ...

> There's really no middle ground here.
... but yes, there is ample ground, and even if it's considered antisocial,
IMHO it's very Lua.


cheers
Reply | Threaded
Open this post in threaded view
|

Re: Polling stdin...

Matthew Percival
G'Day,

        Thanks for the replies.  I figured it was unlikely there would already
be something in Lua, but I thought it best to check.  I took a look at
LuaCurses, but that does not look like it would fit my needs too well,
so I have decided to make a simple (OS-dependant) extension to io.read()
--- io.read("*check") or something.

        -- Matthew