public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Problem with select() on console
@ 2010-07-15  5:50 Cliff Hones
  2010-07-15  7:54 ` Christopher Faylor
  0 siblings, 1 reply; 8+ messages in thread
From: Cliff Hones @ 2010-07-15  5:50 UTC (permalink / raw)
  To: cygwin

When select() is used to test for input availability on the standard
cygwin console in normal (cooked) mode, it indicates input is available
as soon as any key is pressed.  However, a call to read(0,...)
will (correctly) block until a terminating RETURN is entered.

select() should only indicate input is available when a call
to read would *not* block - ie when a read call will immediately
return at least one character or an error such as EOF.

The behaviour of the following test case illustrates this.  When run
in a console window typing a single key causes the program to wait
for the whole line.  When run under mintty or on Linux the
select() calls will continue to return no input until RETURN is
entered.

#include <stdio.h>
#include <stdlib.h>
#include <sys/io.h>
#include <sys/time.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>

int main(void)
{
  fd_set rs;
  struct timeval tv;
  char buff[100];
  while (1)
  {
    sleep(1);
    printf("Calling select\n");
    FD_ZERO(&rs);
    FD_SET(0, &rs);
    tv.tv_sec = tv.tv_usec = 0;
    int k = select(1, &rs, NULL, NULL, &tv);
    if (k < 0)
      perror("Error calling select");
    else if (FD_ISSET(0, &rs))
    {
      printf("Input available\n");
      int n = read(0, buff, sizeof(buff));
      printf("read returned %d\n", n);
    }
  }
  return 0;
}

-- Cliff

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Problem with select() on console
  2010-07-15  5:50 Problem with select() on console Cliff Hones
@ 2010-07-15  7:54 ` Christopher Faylor
  2010-07-15  8:19   ` Matthias Andree
  2010-07-15 12:14   ` Cliff Hones
  0 siblings, 2 replies; 8+ messages in thread
From: Christopher Faylor @ 2010-07-15  7:54 UTC (permalink / raw)
  To: cygwin

On Thu, Jul 15, 2010 at 01:44:19AM +0100, Cliff Hones wrote:
>When select() is used to test for input availability on the standard
>cygwin console in normal (cooked) mode, it indicates input is available
>as soon as any key is pressed.  However, a call to read(0,...)
>will (correctly) block until a terminating RETURN is entered.
>
>select() should only indicate input is available when a call
>to read would *not* block - ie when a read call will immediately
>return at least one character or an error such as EOF.
>
>The behaviour of the following test case illustrates this.  When run
>in a console window typing a single key causes the program to wait
>for the whole line.  When run under mintty or on Linux the
>select() calls will continue to return no input until RETURN is
>entered.

Since, AFAIK, Windows has no way to do this, I don't see how it could be
done easily.  You could, I guess, pull characters into a buffer until a
newline was found but that would be pretty error-prone and any use of
select() would potentially invalidate console i/o for subprocesses.

So, I don't see this changing anytime soon.

cgf

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Problem with select() on console
  2010-07-15  7:54 ` Christopher Faylor
@ 2010-07-15  8:19   ` Matthias Andree
  2010-07-15 14:54     ` Christopher Faylor
  2010-07-15 12:14   ` Cliff Hones
  1 sibling, 1 reply; 8+ messages in thread
From: Matthias Andree @ 2010-07-15  8:19 UTC (permalink / raw)
  To: cygwin

Am 15.07.2010, 07:49 Uhr, schrieb Christopher Faylor:

> On Thu, Jul 15, 2010 at 01:44:19AM +0100, Cliff Hones wrote:
>> When select() is used to test for input availability on the standard
>> cygwin console in normal (cooked) mode, it indicates input is available
>> as soon as any key is pressed.  However, a call to read(0,...)
>> will (correctly) block until a terminating RETURN is entered.
>>
>> select() should only indicate input is available when a call
>> to read would *not* block - ie when a read call will immediately
>> return at least one character or an error such as EOF.
>>
>> The behaviour of the following test case illustrates this.  When run
>> in a console window typing a single key causes the program to wait
>> for the whole line.  When run under mintty or on Linux the
>> select() calls will continue to return no input until RETURN is
>> entered.
>
> Since, AFAIK, Windows has no way to do this, I don't see how it could be
> done easily.  You could, I guess, pull characters into a buffer until a
> newline was found but that would be pretty error-prone and any use of
> select() would potentially invalidate console i/o for subprocesses.
>
> So, I don't see this changing anytime soon.

Is there a way to detect that the application is run from a Windows  
console rather than mintty?

If so, cygwin1.dll could print a warning to the console, (something along  
the lines that running the application under some X11 terminal or mintty  
is advised) and return EINVAL, or abort the application, in either case if  
POSIXLY_CORRECT is set in the environment, much like some GNU tools will  
switch to a more POSIX compliant behaviour with that variable.

Just a rough thought...

-- 
Matthias Andree

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Problem with select() on console
  2010-07-15  7:54 ` Christopher Faylor
  2010-07-15  8:19   ` Matthias Andree
@ 2010-07-15 12:14   ` Cliff Hones
  2010-07-15 12:46     ` Cliff Hones
  2010-07-15 13:37     ` Andy Koppe
  1 sibling, 2 replies; 8+ messages in thread
From: Cliff Hones @ 2010-07-15 12:14 UTC (permalink / raw)
  To: cygwin

Christopher Faylor wrote:
> On Thu, Jul 15, 2010 at 01:44:19AM +0100, Cliff Hones wrote:
>> When select() is used to test for input availability on the standard
>> cygwin console in normal (cooked) mode, it indicates input is available
>> as soon as any key is pressed.  However, a call to read(0,...)
>> will (correctly) block until a terminating RETURN is entered.
>>
>> select() should only indicate input is available when a call
>> to read would *not* block - ie when a read call will immediately
>> return at least one character or an error such as EOF.
>> ...
> 
> Since, AFAIK, Windows has no way to do this, I don't see how it could be
> done easily.  You could, I guess, pull characters into a buffer until a
> newline was found but that would be pretty error-prone and any use of
> select() would potentially invalidate console i/o for subprocesses.
> 
> So, I don't see this changing anytime soon.

Hmm.  Having looked further, it's not just select() which is affected.
If you set the NONBLOCK flag on the console, and perform a read(),
you get error EWOULDBLOCK/EAGAIN until a key is hit.  When a key
is hit, the read blocks until RETURN is entered.

I must look at the console source - but it seems from behaviour and what
you are saying that Windows provides a way for the user to determine that
console input has started (since read() and select() behaviour changes
when a key is pressed) but no way to determine in advance that a call
to input a complete line will block because an incomplete line is present.

I'm surprised this hasn't come up more frequently.  In my case, I have an
app which needs to respond to user input line-based commands, but also
does other processing.  I don't want the app to block every time the user
starts to enter a command.  Of course I could use threads, but that's
an unnecessary change (at least unnecessary on Linux etc).  And I could
insist users use mintty, but that's rather presumptuous.

-- Cliff

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Problem with select() on console
  2010-07-15 12:14   ` Cliff Hones
@ 2010-07-15 12:46     ` Cliff Hones
  2010-07-15 14:54       ` Christopher Faylor
  2010-07-15 13:37     ` Andy Koppe
  1 sibling, 1 reply; 8+ messages in thread
From: Cliff Hones @ 2010-07-15 12:46 UTC (permalink / raw)
  To: cygwin

Cliff Hones wrote:
> I must look at the console source...

And now I have, and I see that fhandler_console does its own
line editing, so is perfectly aware of the input line state.
So blocking as soon as any key is typed seems a shortcoming
of cygwin, not windows?

I see there may be a difficulty with storing incomplete lines,
or with synchronizing processing of new console events seen
by different cygwin threads/processes, and it may be deemed
unworthwhile (especially as it doesn't seem to be a frequently
raised question), but to it seems doable.

-- Cliff

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Problem with select() on console
  2010-07-15 12:14   ` Cliff Hones
  2010-07-15 12:46     ` Cliff Hones
@ 2010-07-15 13:37     ` Andy Koppe
  1 sibling, 0 replies; 8+ messages in thread
From: Andy Koppe @ 2010-07-15 13:37 UTC (permalink / raw)
  To: cygwin

On 15 July 2010 12:57, Cliff Hones wrote:
>> On Thu, Jul 15, 2010 at 01:44:19AM +0100, Cliff Hones wrote:
>>> When select() is used to test for input availability on the standard
>>> cygwin console in normal (cooked) mode, it indicates input is available
>>> as soon as any key is pressed.  However, a call to read(0,...)
>>> will (correctly) block until a terminating RETURN is entered.
>>>
>>> select() should only indicate input is available when a call
>>> to read would *not* block - ie when a read call will immediately
>>> return at least one character or an error such as EOF.
>>>
> I'm surprised this hasn't come up more frequently.  In my case, I have an
> app which needs to respond to user input line-based commands, but also
> does other processing. I don't want the app to block every time the user
> starts to enter a command.  Of course I could use threads, but that's
> an unnecessary change (at least unnecessary on Linux etc).

You could disable terminal line editing (with tcsetattr) and do the
line processing yourself, or let the readline library do it all for
you, which your users would proabably appreciate anyway. Readline's
"Alternate Interface" allows you to interleave line input with other
I/O. See http://tiswww.case.edu/php/chet/readline/readline.html#SEC41

I suspect readline() is the reason why this hasn't come up more frequently.

Andy

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Problem with select() on console
  2010-07-15  8:19   ` Matthias Andree
@ 2010-07-15 14:54     ` Christopher Faylor
  0 siblings, 0 replies; 8+ messages in thread
From: Christopher Faylor @ 2010-07-15 14:54 UTC (permalink / raw)
  To: cygwin

On Thu, Jul 15, 2010 at 09:54:21AM +0200, Matthias Andree wrote:
>Am 15.07.2010, 07:49 Uhr, schrieb Christopher Faylor:
>
>> On Thu, Jul 15, 2010 at 01:44:19AM +0100, Cliff Hones wrote:
>>> When select() is used to test for input availability on the standard
>>> cygwin console in normal (cooked) mode, it indicates input is available
>>> as soon as any key is pressed.  However, a call to read(0,...)
>>> will (correctly) block until a terminating RETURN is entered.
>>>
>>> select() should only indicate input is available when a call
>>> to read would *not* block - ie when a read call will immediately
>>> return at least one character or an error such as EOF.
>>>
>>> The behaviour of the following test case illustrates this.  When run
>>> in a console window typing a single key causes the program to wait
>>> for the whole line.  When run under mintty or on Linux the
>>> select() calls will continue to return no input until RETURN is
>>> entered.
>>
>> Since, AFAIK, Windows has no way to do this, I don't see how it could be
>> done easily.  You could, I guess, pull characters into a buffer until a
>> newline was found but that would be pretty error-prone and any use of
>> select() would potentially invalidate console i/o for subprocesses.
>>
>> So, I don't see this changing anytime soon.
>
>Is there a way to detect that the application is run from a Windows  
>console rather than mintty?
>
>If so, cygwin1.dll could print a warning to the console, (something along  
>the lines that running the application under some X11 terminal or mintty  
>is advised) and return EINVAL, or abort the application, in either case if  
>POSIXLY_CORRECT is set in the environment, much like some GNU tools will  
>switch to a more POSIX compliant behaviour with that variable.

Print a warning to the console if something uses select???  Nuh uh.

This behavior has been in existence for more than ten years.  I think I'll
opt for explaining it once every ten years instead.

cgf

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Problem with select() on console
  2010-07-15 12:46     ` Cliff Hones
@ 2010-07-15 14:54       ` Christopher Faylor
  0 siblings, 0 replies; 8+ messages in thread
From: Christopher Faylor @ 2010-07-15 14:54 UTC (permalink / raw)
  To: cygwin

On Thu, Jul 15, 2010 at 01:45:43PM +0100, Cliff Hones wrote:
>Cliff Hones wrote:
>> I must look at the console source...
>
>And now I have, and I see that fhandler_console does its own line
>editing, so is perfectly aware of the input line state.  So blocking as
>soon as any key is typed seems a shortcoming of cygwin, not windows?

You could say that about just about everything that Cygwin has problems
with.  For instance, the fact that Cygwin's ptys aren't properly
recognized by pure Windows programs is a limitation of Cygwin too.  It
really isn't an interesting distinction since it boils down to a cost/benefit
situation.

>I see there may be a difficulty with storing incomplete lines, or with
>synchronizing processing of new console events seen by different cygwin
>threads/processes, and it may be deemed unworthwhile (especially as it
>doesn't seem to be a frequently raised question), but to it seems
>doable.

The readahead stuff in fhandler_console.cc (which I wrote) was intended
to be used for small amounts of data.  Extending it to properly handle
cooked mode would be quite an undertaking.

Since, as Andy pointed out, most sophisticated applications used
something like readline, this has not come up previously that I can
recall.  So, this is a PTC case.

cgf

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-07-15 14:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-15  5:50 Problem with select() on console Cliff Hones
2010-07-15  7:54 ` Christopher Faylor
2010-07-15  8:19   ` Matthias Andree
2010-07-15 14:54     ` Christopher Faylor
2010-07-15 12:14   ` Cliff Hones
2010-07-15 12:46     ` Cliff Hones
2010-07-15 14:54       ` Christopher Faylor
2010-07-15 13:37     ` Andy Koppe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).