/* select.cc
- Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
Written by Christopher Faylor of Cygnus Solutions
cgf@cygnus.com
#include <stdio.h>
#include <winsock.h>
#include "select.h"
+#include "cygerrno.h"
+#include "fhandler.h"
+#include "dtable.h"
+#include "sync.h"
+#include "sigproc.h"
+#include "perthread.h"
+#include "tty.h"
/*
* All these defines below should be in sys/types.h
#define UNIX_FD_ZERO(p, n) \
bzero ((caddr_t)(p), sizeof_fd_set ((n)))
-#define allocfd_set(n) ((fd_set *) alloca (sizeof_fd_set (n)))
+#define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n)))
#define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
/* Make a fhandler_foo::ready_for_ready method.
me.fd = fd; \
(void) select_read (&me); \
while (!peek_##what (&me, ignra) && howlong == INFINITE) \
- if (fd >= 0 && dtable.not_open (fd)) \
+ if (fd >= 0 && fdtab.not_open (fd)) \
break; \
else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) \
break; \
#define set_handle_or_return_if_not_open(h, s) \
h = (s)->fh->get_handle (); \
- if (dtable.not_open ((s)->fd)) \
+ if (fdtab.not_open ((s)->fd)) \
{ \
(s)->saw_error = TRUE; \
set_errno (EBADF); \
*/
extern "C"
int
-cygwin_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- struct timeval *to)
+cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ struct timeval *to)
{
select_stuff sel;
- fd_set *dummy_readfds = allocfd_set (n);
- fd_set *dummy_writefds = allocfd_set (n);
- fd_set *dummy_exceptfds = allocfd_set (n);
- sigframe thisframe (mainthread, 0);
+ fd_set *dummy_readfds = allocfd_set (maxfds);
+ fd_set *dummy_writefds = allocfd_set (maxfds);
+ fd_set *dummy_exceptfds = allocfd_set (maxfds);
+ sigframe thisframe (mainthread);
#if 0
if (n > FD_SETSIZE)
}
#endif
- select_printf ("%d, %p, %p, %p, %p", n, readfds, writefds, exceptfds, to);
+ select_printf ("%d, %p, %p, %p, %p", maxfds, readfds, writefds, exceptfds, to);
if (!readfds)
- {
- UNIX_FD_ZERO (dummy_readfds, n);
- readfds = dummy_readfds;
- }
+ readfds = dummy_readfds;
if (!writefds)
- {
- UNIX_FD_ZERO (dummy_writefds, n);
- writefds = dummy_writefds;
- }
+ writefds = dummy_writefds;
if (!exceptfds)
- {
- UNIX_FD_ZERO (dummy_exceptfds, n);
- exceptfds = dummy_exceptfds;
- }
+ exceptfds = dummy_exceptfds;
- for (int i = 0; i < n; i++)
+ for (int i = 0; i < maxfds; i++)
if (!sel.test_and_set (i, readfds, writefds, exceptfds))
{
select_printf ("aborting due to test_and_set error");
return 0;
}
- /* If one of the selected fds is "always ready" just poll everything and return
- the result. There is no need to wait. */
- if (sel.always_ready || ms == 0)
- {
- UNIX_FD_ZERO (readfds, n);
- UNIX_FD_ZERO (writefds, n);
- UNIX_FD_ZERO (exceptfds, n);
- return sel.poll (readfds, writefds, exceptfds);
- }
+ /* Allocate some fd_set structures using the number of fds as a guide. */
+ fd_set *r = allocfd_set (maxfds);
+ fd_set *w = allocfd_set (maxfds);
+ fd_set *e = allocfd_set (maxfds);
- /* Wait for an fd to come alive */
- return sel.wait (readfds, writefds, exceptfds, ms);
+ if (sel.always_ready || ms == 0)
+ /* Don't bother waiting. */;
+ else if (sel.wait (r, w, e, ms))
+ return -1; /* some kind of error */
+
+ copyfd_set (readfds, r, maxfds);
+ copyfd_set (writefds, w, maxfds);
+ copyfd_set (exceptfds, e, maxfds);
+ return sel.poll (readfds, writefds, exceptfds);
}
/* Cleanup */
fd_set *exceptfds)
{
select_record *s = NULL;
- if (UNIX_FD_ISSET (i, readfds) && (s = dtable.select_read (i, s)) == NULL)
+ if (UNIX_FD_ISSET (i, readfds) && (s = fdtab.select_read (i, s)) == NULL)
return 0; /* error */
- if (UNIX_FD_ISSET (i, writefds) && (s = dtable.select_write (i, s)) == NULL)
+ if (UNIX_FD_ISSET (i, writefds) && (s = fdtab.select_write (i, s)) == NULL)
return 0; /* error */
- if (UNIX_FD_ISSET (i, exceptfds) && (s = dtable.select_except (i, s)) == NULL)
+ if (UNIX_FD_ISSET (i, exceptfds) && (s = fdtab.select_except (i, s)) == NULL)
return 0; /* error */
if (s == NULL)
return 1; /* nothing to do */
counting the number of active fds. */
while ((s = s->next))
{
+ if (m > MAXIMUM_WAIT_OBJECTS)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
if (!s->startup (s, this))
{
__seterrno ();
continue;
}
- int n = m - 1;
DWORD start_time = GetTickCount (); /* Record the current time for later use. */
- /* Allocate some fd_set structures using the number of fds as a guide. */
- fd_set *r = allocfd_set (n);
- fd_set *w = allocfd_set (n);
- fd_set *e = allocfd_set (n);
- UNIX_FD_ZERO (r, n);
- UNIX_FD_ZERO (w, n);
- UNIX_FD_ZERO (e, n);
- debug_printf ("n %d, ms %u", n, ms);
+ debug_printf ("m %d, ms %u", m, ms);
for (;;)
{
if (!windows_used)
if (s->saw_error)
return -1; /* Somebody detected an error */
else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) &&
- s->verify (s, r, w, e))
+ s->verify (s, readfds, writefds, exceptfds))
gotone = TRUE;
select_printf ("gotone %d", gotone);
}
out:
- copyfd_set (readfds, r, n);
- copyfd_set (writefds, w, n);
- copyfd_set (exceptfds, e, n);
-
- return poll (readfds, writefds, exceptfds);
+ select_printf ("returning 0");
+ return 0;
}
static int
gotone = 1;
goto out;
}
- if (fh->bg_check (SIGTTIN) <= 0)
+ if (fh->bg_check (SIGTTIN) <= bg_eof)
{
gotone = s->read_ready = 1;
goto out;
}
- if (!ignra && fh->get_device () != FH_PTYM && fh->get_device () != FH_TTYM &&
- fh->get_readahead_valid ())
+ switch (fh->get_device ())
{
- select_printf ("readahead");
- gotone = s->read_ready = 1;
- goto out;
+ case FH_PTYM:
+ case FH_TTYM:
+ if (((fhandler_pty_master *)fh)->need_nl)
+ {
+ gotone = s->read_ready = 1;
+ goto out;
+ }
+ break;
+ default:
+ if (!ignra && fh->get_readahead_valid ())
+ {
+ select_printf ("readahead");
+ gotone = s->read_ready = 1;
+ goto out;
+ }
}
}
set_handle_or_return_if_not_open (h, me);
for (;;)
- if (fh->bg_check (SIGTTIN) <= 0)
+ if (fh->bg_check (SIGTTIN) <= bg_eof)
return me->read_ready = 1;
else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
break;
{
if (irec.EventType == WINDOW_BUFFER_SIZE_EVENT)
kill_pgrp (fh->tc->getpgid (), SIGWINCH);
+ else if (irec.EventType == MOUSE_EVENT &&
+ (irec.Event.MouseEvent.dwEventFlags == 0 ||
+ irec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))
+ {
+ if (fh->mouse_aware ())
+ return me->read_ready = 1;
+ }
else if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown == TRUE &&
(irec.Event.KeyEvent.uChar.AsciiChar || get_nonascii_key (irec, tmpbuf)))
return me->read_ready = 1;
s->startup = no_startup;
s->poll = poll_console;
s->verify = poll_console;
+ set_cursor_maybe ();
}
s->h = get_handle ();
s->startup = no_startup;
s->poll = poll_console;
s->verify = no_verify;
+ set_cursor_maybe ();
}
s->write_selected = TRUE;
s->startup = no_startup;
s->poll = poll_console;
s->verify = no_verify;
+ set_cursor_maybe ();
}
s->except_selected = TRUE;
return ((fhandler_pipe *)this)->fhandler_pipe::select_except (s);
}
+static int
+verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds)
+{
+ if (WaitForSingleObject (me->h, 0) == WAIT_OBJECT_0)
+ me->read_ready = 1;
+ return set_bits (me, readfds, writefds, exceptfds);
+}
+
+select_record *
+fhandler_tty_slave::select_read (select_record *s)
+{
+ if (!s)
+ s = new select_record;
+ s->h = input_available_event;
+ s->startup = no_startup;
+ s->poll = poll_pipe;
+ s->verify = verify_tty_slave;
+ s->read_selected = TRUE;
+ s->cleanup = NULL;
+ return s;
+}
+
+int
+fhandler_tty_slave::ready_for_read (int fd, DWORD howlong, int ignra)
+{
+ HANDLE w4[2];
+ if (!ignra && get_readahead_valid ())
+ {
+ select_printf ("readahead");
+ return 1;
+ }
+ w4[0] = signal_arrived;
+ w4[1] = input_available_event;
+ switch (WaitForMultipleObjects (2, w4, FALSE, howlong))
+ {
+ case WAIT_OBJECT_0 + 1:
+ return 1;
+ case WAIT_FAILED:
+ select_printf ( "wait failed %E" );
+ case WAIT_OBJECT_0:
+ case WAIT_TIMEOUT:
+ default:
+ return 0;
+ }
+}
+
select_record *
fhandler_dev_null::select_read (select_record *s)
{
{
case WAIT_OBJECT_0:
if (!ClearCommError (h, &ev, &st))
- {
- debug_printf ("ClearCommError");
- goto err;
- }
+ {
+ debug_printf ("ClearCommError");
+ goto err;
+ }
else if (!st.cbInQue)
Sleep (to);
else