select() on terminal

bridged with qdn.public.porting
Post Reply
Norton Allen

select() on terminal

Post by Norton Allen » Thu May 08, 2003 8:11 pm

The following program demonstrates what appears to
be a bug in the implementation of select() (or the
select handler) within the terminal driver(s).
I have tested this both in a pterm window and without
photon on 6.2.0.

The program is supposed to read a character at a time
from STDIN_FILENO while using select with a timeout
value. (There is probably a better way to do this,
but the code is taken from someone else's software
(sudo) and appears to be legal.)

When you execute the program, it displays a prompt.

If you take no action for 5 seconds, it times out,
which is good.

If you type a single character other than 'Enter',
then wait, it will not timeout, which is bad.

If you type a few characters followed by 'Enter',
it will read one character, then block. select()
is apparently not returning even though there are
more characters available for reading. If you hit
'Enter' again, all of the characters are read -
select() has now recognizes that there are more
characters available. [This behaviour is independent
of the use of a timeout value.]

[Because the console is in edited mode, it is
reasonable to expect select() to wait until the
newline is entered before returning.]

-Norton Allen

#include <stdio.h>
#include <unistd.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <stdlib.h>
#include <errno.h>

int main( int argc, char **argv ) {
int c, n;
fd_set *readfds = NULL;
struct timeval tv;
int fd = STDIN_FILENO;
int timeout = 5;

printf( "Enter Text: " );
fflush(stdout);

readfds = (fd_set *) malloc(sizeof(fd_set));
FD_ZERO(readfds);


for (;;) {
FD_SET(fd, readfds);

/* Set timeout for select */
tv.tv_sec = timeout;
tv.tv_usec = 0;
/* Make sure there is something to read (or timeout) */
while ((n = select(fd + 1, readfds, 0, 0, &tv)) == -1 &&
errno == EAGAIN) {
tv.tv_sec = timeout;
tv.tv_usec = 0;
}
if (n <= 0) {
free(readfds);
printf( "select returned %d (timeout or interrupt)\n", n );
return(0); /* timeout or interrupt */
}
n = read( fd, &c, 1 );
if ( n != 1 || c == '\n' || c == '\r' )
break;
printf("read c=%d\n", c );
}
free(readfds);
if ( n != 1 ) printf("read n=%d\n", n );
else printf("read c=%d\n", c );
return 0;
}

Chris McKillop

Re: select() on terminal

Post by Chris McKillop » Thu May 08, 2003 10:04 pm

Norton Allen <allen@huarp.harvard.edu> wrote:
The following program demonstrates what appears to
be a bug in the implementation of select() (or the
select handler) within the terminal driver(s).
I have tested this both in a pterm window and without
photon on 6.2.0.
It is documented at the end of the help page on select(). You can only call
select() on terminals in RAW mode.

chris

--
Chris McKillop <cdm@qnx.com> "The faster I go, the behinder I get."
Software Engineer, QSSL -- Lewis Carroll --
http://qnx.wox.org/

David Gibbs

Re: select() on terminal

Post by David Gibbs » Thu May 08, 2003 10:29 pm

Norton Allen <allen@huarp.harvard.edu> wrote:
[Because the console is in edited mode, it is
reasonable to expect select() to wait until the
newline is entered before returning.]
From the select() docs:

Caveats:
The select() function only works with raw file descriptors; it doesn't
work with file descriptors in edited mode. See the ICANON flag in
the description of the tcgetattr() function.

-David
--
QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Norton Allen

Re: select() on terminal

Post by Norton Allen » Fri May 09, 2003 1:16 pm

David Gibbs wrote:
Norton Allen <allen@huarp.harvard.edu> wrote:


[Because the console is in edited mode, it is
reasonable to expect select() to wait until the
newline is entered before returning.]


From the select() docs:

Caveats:
The select() function only works with raw file descriptors; it doesn't
work with file descriptors in edited mode. See the ICANON flag in
the description of the tcgetattr() function.

-David
Thanks, I obviously missed that. It's nice that it's
documented. Do you consider this to be a non-standard
limitation, or is this a common limitation of select
with terminals on other operating systems?

A related question: is there any particular reason
why it couldn't be made to work? (not counting time
and money) (This may be an academic question, but
heck, I work at Harvard!)

I ask because this code is used within the sudo
package, which clearly expects select() to work
on a file descriptor in editted mode, and I'm wondering
what I should say to the maintainer.

-Norton

Xiaodan Tang

Re: select() on terminal

Post by Xiaodan Tang » Fri May 09, 2003 1:29 pm

Norton Allen <allen@huarp.harvard.edu> wrote in message
news:b9g8oq$sd0$1@inn.qnx.com...
David Gibbs wrote:
From the select() docs:

Caveats:
The select() function only works with raw file descriptors; it doesn't
work with file descriptors in edited mode. See the ICANON flag in
the description of the tcgetattr() function.

-David

Thanks, I obviously missed that. It's nice that it's
documented. Do you consider this to be a non-standard
limitation, or is this a common limitation of select
with terminals on other operating systems?

A related question: is there any particular reason
why it couldn't be made to work? (not counting time
and money) (This may be an academic question, but
heck, I work at Harvard!)

I ask because this code is used within the sudo
package, which clearly expects select() to work
on a file descriptor in editted mode, and I'm wondering
what I should say to the maintainer.
Hm... Say we are in EDIT mode.

The user type "A", your select() return, you read out the
character.

The user then press <BACKSPACE>, what is the terminal
suppose to do? It want to earse the "A", but the character
is no longer there!

-xtang

Norton Allen

Re: select() on terminal

Post by Norton Allen » Fri May 09, 2003 1:43 pm

Xiaodan Tang wrote:
Norton Allen <allen@huarp.harvard.edu> wrote in message
news:b9g8oq$sd0$1@inn.qnx.com...

David Gibbs wrote:

From the select() docs:

Caveats:
The select() function only works with raw file descriptors; it doesn't
work with file descriptors in edited mode. See the ICANON flag in
the description of the tcgetattr() function.

-David

Thanks, I obviously missed that. It's nice that it's
documented. Do you consider this to be a non-standard
limitation, or is this a common limitation of select
with terminals on other operating systems?

A related question: is there any particular reason
why it couldn't be made to work? (not counting time
and money) (This may be an academic question, but
heck, I work at Harvard!)

I ask because this code is used within the sudo
package, which clearly expects select() to work
on a file descriptor in editted mode, and I'm wondering
what I should say to the maintainer.


Hm... Say we are in EDIT mode.

The user type "A", your select() return, you read out the
character.
I would consider that incorrect behaviour for select()
(see below).
The user then press <BACKSPACE>, what is the terminal
suppose to do? It want to earse the "A", but the character
is no longer there!

-xtang
Since you're in edit mode, it is entirely reasonable
to assume that select would not indicate that characters
are available for reading until you hit 'Enter'. But once
you have hit 'Enter', you would expect select() to report
that there are characters to read until you have read up
to that newline character. This seems logically self-
consistent to me. Am I missing something.

David Bacon

Re: select() on terminal

Post by David Bacon » Sun May 25, 2003 4:01 am

I agree (assuming you mean *through* the newline, of course).

dB

"Norton Allen" <allen@huarp.harvard.edu> wrote in message
news:b9ga7p$17m$1@inn.qnx.com...
<snip>
Since you're in edit mode, it is entirely reasonable
to assume that select would not indicate that characters
are available for reading until you hit 'Enter'. But once
you have hit 'Enter', you would expect select() to report
that there are characters to read until you have read up
to that newline character. This seems logically self-
consistent to me. Am I missing something.

Norton Allen

Re: select() on terminal

Post by Norton Allen » Mon Jun 02, 2003 12:35 pm

David Bacon wrote:
I agree (assuming you mean *through* the newline, of course).
Of course! -N
dB

"Norton Allen" <allen@huarp.harvard.edu> wrote in message
news:b9ga7p$17m$1@inn.qnx.com...
snip

Since you're in edit mode, it is entirely reasonable
to assume that select would not indicate that characters
are available for reading until you hit 'Enter'. But once
you have hit 'Enter', you would expect select() to report
that there are characters to read until you have read up
to that newline character. This seems logically self-
consistent to me. Am I missing something.



Post Reply

Return to “qdn.public.porting”