For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > May 2004 > readline() with select() on STDIN









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author readline() with select() on STDIN
luc wastiaux

2004-05-22, 12:34 pm

Hello,
I have a program that needs to monitor different sockets for data
available for reading. I use select for this. I would like to be able to
type commands in the program, I figure I need to monitor STDIN as well.
Is it possible to use the GNU readline library in conjunction with this ?
--
luc wastiaux
Viktor Lofgren

2004-05-22, 2:38 pm

luc wastiaux <dustpuppy@airpost.net> wrote:
> Hello,
> I have a program that needs to monitor different sockets for data
> available for reading. I use select for this. I would like to be able to
> type commands in the program, I figure I need to monitor STDIN as well.
> Is it possible to use the GNU readline library in conjunction with this ?


I would set STDIN in asynchronous mode instead. That will give you a signal
when you receive input from STDIN.

Something like this would do the trick
-------------------------------------------
if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
if(fcntl(0, F_SETOWN, getpid())<0) abort();
/* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
instead of SIGIO */
signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)

int your_sighandler(int p) {
/* readline(...) */
}
-------------------------------------------
If you are monitoring the same socket constantly i would
advise you set it to async mode as well.
luc wastiaux

2004-05-22, 3:31 pm

Viktor Lofgren wrote:
>
> I would set STDIN in asynchronous mode instead. That will give you a signal
> when you receive input from STDIN.
>
> Something like this would do the trick
> -------------------------------------------
> if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
> if(fcntl(0, F_SETOWN, getpid())<0) abort();
> /* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
> instead of SIGIO */
> signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
>
> int your_sighandler(int p) {
> /* readline(...) */
> }
> -------------------------------------------
> If you are monitoring the same socket constantly i would
> advise you set it to async mode as well.


I assume this is a better alternative to the while(1) loop I currently
use around select. So can I set up a signal handler for each of the
sockets (there is a large number of them), and have the signal handler
run select to determine which socket has data available ?

My question about readline was whether I can use the command-line
editing library GNU readline (it gives you keyboard shorcuts and various
editing functions).

--
luc wastiaux
Viktor Lofgren

2004-05-22, 4:31 pm

luc wastiaux <dustpuppy@airpost.net> wrote:
> Viktor Lofgren wrote:
> I assume this is a better alternative to the while(1) loop I currently
> use around select. So can I set up a signal handler for each of the
> sockets (there is a large number of them), and have the signal handler
> run select to determine which socket has data available ?


If you have many sockets the async approach is not a very good idea;
if that's the case i would place them in a loop and select() them one
by one.

>
> My question about readline was whether I can use the command-line
> editing library GNU readline (it gives you keyboard shorcuts and various
> editing functions).
>


Since the readline manual does not mention not working with that setup
it should be safe to assume it does work problem-free.
Barry Margolin

2004-05-22, 6:31 pm

In article <c8nqjv014j0@news1.newsguy.com>,
luc wastiaux <dustpuppy@airpost.net> wrote:

> Hello,
> I have a program that needs to monitor different sockets for data
> available for reading. I use select for this. I would like to be able to
> type commands in the program, I figure I need to monitor STDIN as well.
> Is it possible to use the GNU readline library in conjunction with this ?


I'm not an expert on readline(), but I doubt that it can work
asynchronously like this -- I expect it doesn't return until it has read
a complete line.

I suggest you call readline() in a separate thread or process that
communicates with the main thread/process via a pipe, which the main
thread/process includes in its select(). When readline() returns, the
entire input line can be written to the pipe.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
luc wastiaux

2004-05-22, 11:31 pm

Barry Margolin wrote:
> In article <c8nqjv014j0@news1.newsguy.com>,
> luc wastiaux <dustpuppy@airpost.net> wrote:
>
>
>
>
> I'm not an expert on readline(), but I doubt that it can work
> asynchronously like this -- I expect it doesn't return until it has read
> a complete line.
>
> I suggest you call readline() in a separate thread or process that
> communicates with the main thread/process via a pipe, which the main
> thread/process includes in its select(). When readline() returns, the
> entire input line can be written to the pipe.



Ok this sounds like a good idea and not too hard to implement.

--
luc wastiaux
luc wastiaux

2004-05-23, 6:35 am

Viktor Lofgren wrote:
> luc wastiaux <dustpuppy@airpost.net> wrote:
>
>
>
> If you have many sockets the async approach is not a very good idea;
> if that's the case i would place them in a loop and select() them one
> by one.


But how do I prevent my process from taking up 99% CPU ? This is what
happens currently with the while(1) loop.



--
luc wastiaux
luc wastiaux

2004-05-23, 6:35 am

luc wastiaux wrote:
>
>
> But how do I prevent my process from taking up 99% CPU ? This is what
> happens currently with the while(1) loop.


I set a timeout value when I didn't need one. With no timeout value,
select will hang when there is no data available, which suits me fine.

Thanks for your help Viktor and Barry.

--
luc wastiaux
Viktor Lofgren

2004-05-23, 9:31 am

luc wastiaux <dustpuppy@airpost.net> wrote:
> Viktor Lofgren wrote:
>
> But how do I prevent my process from taking up 99% CPU ? This is what
> happens currently with the while(1) loop.
>
>
>


Set your select timeout to 1 usecond timeout. Having 0 timeout
will eat all CPU, but having a minimal timeout won't :-)
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com