OSDN Git Service

* fhandler_console.cc: Remove VK_DIVIDE detection.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / select.cc
1 /* select.cc
2
3    Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
4
5    Written by Christopher Faylor of Cygnus Solutions
6    cgf@cygnus.com
7
8 This file is part of Cygwin.
9
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
12 details. */
13
14 /*
15  * The following line means that the BSD socket
16  * definitions for fd_set, FD_ISSET etc. are used in this
17  * file.
18  */
19
20 #define  __INSIDE_CYGWIN_NET__
21 #define Win32_Winsock
22
23 #include <errno.h>
24 #include <sys/socket.h>
25 #include <stdlib.h>
26 #include <sys/time.h>
27
28 #include <netdb.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include "winsup.h"
32 #include <wingdi.h>
33 #include <winuser.h>
34 #include <winsock.h>
35 #include "select.h"
36
37 /*
38  * All these defines below should be in sys/types.h
39  * but because of the includes above, they may not have
40  * been included. We create special UNIX_xxxx versions here.
41  */
42
43 #ifndef NBBY
44 #define NBBY 8    /* number of bits in a byte */
45 #endif /* NBBY */
46
47 /*
48  * Select uses bit masks of file descriptors in longs.
49  * These macros manipulate such bit fields (the filesystem macros use chars).
50  * FD_SETSIZE may be defined by the user, but the default here
51  * should be >= NOFILE (param.h).
52  */
53
54 typedef long fd_mask;
55 #define UNIX_NFDBITS (sizeof (fd_mask) * NBBY)       /* bits per mask */
56 #ifndef unix_howmany
57 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
58 #endif
59
60 #define unix_fd_set fd_set
61
62 #define NULL_fd_set ((fd_set *)NULL)
63 #define sizeof_fd_set(n) \
64   ((unsigned) (NULL_fd_set->fds_bits + unix_howmany((n), UNIX_NFDBITS)))
65 #define UNIX_FD_SET(n, p) \
66   ((p)->fds_bits[(n)/UNIX_NFDBITS] |= (1L << ((n) % UNIX_NFDBITS)))
67 #define UNIX_FD_CLR(n, p) \
68   ((p)->fds_bits[(n)/UNIX_NFDBITS] &= ~(1L << ((n) % UNIX_NFDBITS)))
69 #define UNIX_FD_ISSET(n, p) \
70   ((p)->fds_bits[(n)/UNIX_NFDBITS] & (1L << ((n) % UNIX_NFDBITS)))
71 #define UNIX_FD_ZERO(p, n) \
72   bzero ((caddr_t)(p), sizeof_fd_set ((n)))
73
74 #define allocfd_set(n) ((fd_set *) alloca (sizeof_fd_set (n)))
75 #define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
76
77 /* Make a fhandler_foo::ready_for_ready method.
78    Assumption: The "ready_for_read" methods are called with one level of
79    signal blocking. */
80 #define MAKEready(what) \
81 int \
82 fhandler_##what::ready_for_read (int fd, DWORD howlong, int ignra) \
83 { \
84   select_record me (this); \
85   me.fd = fd; \
86   (void) select_read (&me); \
87   while (!peek_##what (&me, ignra) && howlong == INFINITE) \
88     if (fd >= 0 && dtable.not_open (fd)) \
89       break; \
90     else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) \
91       break; \
92   return me.read_ready; \
93 }
94
95 #define set_handle_or_return_if_not_open(h, s) \
96   h = (s)->fh->get_handle (); \
97   if (dtable.not_open ((s)->fd)) \
98     { \
99       (s)->saw_error = TRUE; \
100       set_errno (EBADF); \
101       return -1; \
102     } \
103
104 /* The main select code.
105  */
106 extern "C"
107 int
108 cygwin_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
109                      struct timeval *to)
110 {
111   select_stuff sel;
112   fd_set *dummy_readfds = allocfd_set (n);
113   fd_set *dummy_writefds = allocfd_set (n);
114   fd_set *dummy_exceptfds = allocfd_set (n);
115   sigframe thisframe (mainthread, 0);
116
117 #if 0
118   if (n > FD_SETSIZE)
119     {
120       set_errno (EINVAL);
121       return -1;
122     }
123 #endif
124
125   select_printf ("%d, %p, %p, %p, %p", n, readfds, writefds, exceptfds, to);
126
127   if (!readfds)
128     {
129       UNIX_FD_ZERO (dummy_readfds, n);
130       readfds = dummy_readfds;
131     }
132   if (!writefds)
133     {
134       UNIX_FD_ZERO (dummy_writefds, n);
135       writefds = dummy_writefds;
136     }
137   if (!exceptfds)
138     {
139       UNIX_FD_ZERO (dummy_exceptfds, n);
140       exceptfds = dummy_exceptfds;
141     }
142
143   for (int i = 0; i < n; i++)
144     if (!sel.test_and_set (i, readfds, writefds, exceptfds))
145       {
146         select_printf ("aborting due to test_and_set error");
147         return -1;      /* Invalid fd, maybe? */
148       }
149
150   /* Convert to milliseconds or INFINITE if to == NULL */
151   DWORD ms = to ? (to->tv_sec * 1000) + (to->tv_usec / 1000) : INFINITE;
152   if (ms == 0 && to->tv_usec)
153     ms = 1;                     /* At least 1 ms granularity */
154
155   if (to)
156     select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
157   else
158     select_printf ("to NULL, ms %x", ms);
159
160   select_printf ("sel.always_ready %d", sel.always_ready);
161
162   /* Degenerate case.  No fds to wait for.  Just wait. */
163   if (sel.start.next == NULL)
164     {
165       if (WaitForSingleObject (signal_arrived, ms) == WAIT_OBJECT_0)
166         {
167           select_printf ("signal received");
168           set_sig_errno (EINTR);
169           return -1;
170         }
171       return 0;
172     }
173
174   /* If one of the selected fds is "always ready" just poll everything and return
175      the result.  There is no need to wait. */
176   if (sel.always_ready || ms == 0)
177     {
178       UNIX_FD_ZERO (readfds, n);
179       UNIX_FD_ZERO (writefds, n);
180       UNIX_FD_ZERO (exceptfds, n);
181       return sel.poll (readfds, writefds, exceptfds);
182     }
183
184   /* Wait for an fd to come alive */
185   return sel.wait (readfds, writefds, exceptfds, ms);
186 }
187
188 /* Cleanup */
189 select_stuff::~select_stuff ()
190 {
191   select_record *s = &start;
192
193   select_printf ("calling cleanup routines");
194   while ((s = s->next))
195     if (s->cleanup)
196       s->cleanup (s, this);
197
198   select_record *snext = start.next;
199
200   select_printf ("deleting select records");
201   while ((s = snext))
202     {
203       snext = s->next;
204       delete s;
205     }
206 }
207
208 /* Add a record to the select chain */
209 int
210 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
211                             fd_set *exceptfds)
212 {
213   select_record *s = NULL;
214   if (UNIX_FD_ISSET (i, readfds) && (s = dtable.select_read (i, s)) == NULL)
215     return 0; /* error */
216   if (UNIX_FD_ISSET (i, writefds) && (s = dtable.select_write (i, s)) == NULL)
217     return 0; /* error */
218   if (UNIX_FD_ISSET (i, exceptfds) && (s = dtable.select_except (i, s)) == NULL)
219     return 0; /* error */
220   if (s == NULL)
221     return 1; /* nothing to do */
222
223   if (s->read_ready || s->write_ready || s->except_ready)
224     always_ready = TRUE;
225
226   if (s->windows_handle || s->windows_handle || s->windows_handle)
227     windows_used = TRUE;
228
229   s->next = start.next;
230   start.next = s;
231   return 1;
232 }
233
234 /* Poll every fd in the select chain.  Set appropriate fd in mask. */
235 int
236 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
237 {
238   int n = 0;
239   select_record *s = &start;
240   while ((s = s->next))
241     n += s->poll (s, readfds, writefds, exceptfds);
242   select_printf ("returning %d", n);
243   return n;
244 }
245
246 /* The heart of select.  Waits for an fd to do something interesting. */
247 int
248 select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
249                     DWORD ms)
250 {
251   int wait_ret;
252   HANDLE w4[MAXIMUM_WAIT_OBJECTS];
253   select_record *s = &start;
254   int m = 0;
255
256   w4[m++] = signal_arrived;  /* Always wait for the arrival of a signal. */
257   /* Loop through the select chain, starting up anything appropriate and
258      counting the number of active fds. */
259   while ((s = s->next))
260     {
261       if (!s->startup (s, this))
262         {
263           __seterrno ();
264           return -1;
265         }
266       if (s->h == NULL)
267         continue;
268       for (int i = 1; i < m; i++)
269         if (w4[i] == s->h)
270           goto next_while;
271       w4[m++] = s->h;
272   next_while:
273       continue;
274     }
275
276   int n = m - 1;
277   DWORD start_time = GetTickCount ();   /* Record the current time for later use. */
278
279   /* Allocate some fd_set structures using the number of fds as a guide. */
280   fd_set *r = allocfd_set (n);
281   fd_set *w = allocfd_set (n);
282   fd_set *e = allocfd_set (n);
283   UNIX_FD_ZERO (r, n);
284   UNIX_FD_ZERO (w, n);
285   UNIX_FD_ZERO (e, n);
286   debug_printf ("n %d, ms %u", n, ms);
287   for (;;)
288     {
289       if (!windows_used)
290         wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
291       else
292         wait_ret = MsgWaitForMultipleObjects (m, w4, FALSE, ms, QS_ALLINPUT);
293
294       switch (wait_ret)
295       {
296         case WAIT_OBJECT_0:
297           select_printf ("signal received");
298           set_sig_errno (EINTR);
299           return -1;
300         case WAIT_FAILED:
301           select_printf ("WaitForMultipleObjects failed");
302           __seterrno ();
303           return -1;
304         case WAIT_TIMEOUT:
305           select_printf ("timed out");
306           goto out;
307       }
308
309       select_printf ("woke up.  wait_ret %d.  verifying", wait_ret);
310       s = &start;
311       int gotone = FALSE;
312       while ((s = s->next))
313         if (s->saw_error)
314           return -1;            /* Somebody detected an error */
315         else if ((((wait_ret >= m && s->windows_handle) || s->h == w4[wait_ret])) &&
316             s->verify (s, r, w, e))
317           gotone = TRUE;
318
319       select_printf ("gotone %d", gotone);
320       if (gotone)
321         goto out;
322
323       if (ms == INFINITE)
324         {
325           select_printf ("looping");
326           continue;
327         }
328       select_printf ("recalculating ms");
329
330       DWORD now = GetTickCount ();
331       if (now > (start_time + ms))
332         {
333           select_printf ("timed out after verification");
334           goto out;
335         }
336       ms -= (now - start_time);
337       start_time = now;
338       select_printf ("ms now %u", ms);
339     }
340
341 out:
342   copyfd_set (readfds, r, n);
343   copyfd_set (writefds, w, n);
344   copyfd_set (exceptfds, e, n);
345
346   return poll (readfds, writefds, exceptfds);
347 }
348
349 static int
350 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
351            fd_set *exceptfds)
352 {
353   int ready = 0;
354   select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
355   if (me->read_selected && me->read_ready)
356     {
357       UNIX_FD_SET (me->fd, readfds);
358       ready++;
359     }
360   if (me->write_selected && me->write_ready)
361     {
362       UNIX_FD_SET (me->fd, writefds);
363       ready++;
364     }
365   if (me->except_ready && me->except_ready)
366     {
367       UNIX_FD_SET (me->fd, exceptfds);
368       ready++;
369     }
370   select_printf ("ready %d", ready);
371   return ready;
372 }
373
374 static int
375 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
376 {
377   return 1;
378 }
379
380 static int
381 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
382            fd_set *exceptfds)
383 {
384   return set_bits (me, readfds, writefds, exceptfds);
385 }
386
387 static int
388 no_startup (select_record *, select_stuff *)
389 {
390   return 1;
391 }
392
393 static int
394 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
395 {
396   return 0;
397 }
398
399 static int
400 peek_pipe (select_record *s, int ignra)
401 {
402   int n = 0;
403   int gotone = 0;
404   fhandler_base *fh = s->fh;
405
406   HANDLE h;
407   set_handle_or_return_if_not_open (h, s);
408
409   /* Don't perform complicated tests if we don't need to. */
410   if (!s->read_selected && !s->except_selected)
411     goto out;
412
413   if (s->read_selected)
414     {
415       if (s->read_ready)
416         {
417           select_printf ("already ready");
418           gotone = 1;
419           goto out;
420         }
421       if (fh->bg_check (SIGTTIN) <= 0)
422         {
423           gotone = s->read_ready = 1;
424           goto out;
425         }
426
427       if (!ignra && fh->get_device () != FH_PTYM && fh->get_device () != FH_TTYM &&
428           fh->get_readahead_valid ())
429         {
430           select_printf ("readahead");
431           gotone = s->read_ready = 1;
432           goto out;
433         }
434     }
435
436   if (fh->get_device() != FH_PIPEW &&
437       !PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
438     {
439       select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
440       n = -1;
441     }
442
443   if (n < 0)
444     {
445       select_printf ("%s, n %d", fh->get_name (), n);
446       if (s->except_selected)
447         gotone += s->except_ready = TRUE;
448       if (s->read_selected)
449         gotone += s->read_ready = TRUE;
450     }
451   if (n > 0 && s->read_selected)
452     {
453       select_printf ("%s, ready for read", fh->get_name ());
454       gotone += s->read_ready = TRUE;
455     }
456   if (!gotone && s->fh->hit_eof ())
457     {
458       select_printf ("%s, saw EOF", fh->get_name ());
459       if (s->except_selected)
460         gotone = s->except_ready = TRUE;
461       if (s->read_selected)
462         gotone += s->read_ready = TRUE;
463       select_printf ("saw eof on '%s'", fh->get_name ());
464     }
465
466 out:
467   return gotone || s->write_ready;
468 }
469
470 static int
471 poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds,
472            fd_set *exceptfds)
473 {
474   return peek_pipe (me, 0) ?
475          set_bits (me, readfds, writefds, exceptfds) :
476          0;
477 }
478
479 MAKEready(pipe)
480
481 static int start_thread_pipe (select_record *me, select_stuff *stuff);
482
483 struct pipeinf
484   {
485     HANDLE thread;
486     BOOL stop_thread_pipe;
487     select_record *start;
488   };
489
490 static DWORD WINAPI
491 thread_pipe (void *arg)
492 {
493   pipeinf *pi = (pipeinf *)arg;
494   BOOL gotone = FALSE;
495
496   for (;;)
497     {
498       select_record *s = pi->start;
499       while ((s = s->next))
500         if (s->startup == start_thread_pipe)
501           {
502             if (peek_pipe (s, 0))
503               gotone = TRUE;
504             if (pi->stop_thread_pipe)
505               {
506                 select_printf ("stopping");
507                 goto out;
508               }
509           }
510       /* Paranoid check */
511       if (pi->stop_thread_pipe)
512         {
513           select_printf ("stopping from outer loop");
514           break;
515         }
516       if (gotone)
517         break;
518       Sleep (10);
519     }
520 out:
521   return 0;
522 }
523
524 static int
525 start_thread_pipe (select_record *me, select_stuff *stuff)
526 {
527   if (stuff->device_specific[FHDEVN(FH_PIPE)])
528     {
529       me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_PIPE)])->thread;
530       return 1;
531     }
532   pipeinf *pi = new pipeinf;
533   pi->start = &stuff->start;
534   pi->stop_thread_pipe = FALSE;
535   pi->thread = me->h = makethread (thread_pipe, (LPVOID)pi, 0, "select_pipe");
536   if (!me->h)
537     return 0;
538   stuff->device_specific[FHDEVN(FH_PIPE)] = (void *)pi;
539   return 1;
540 }
541
542 static void
543 pipe_cleanup (select_record *, select_stuff *stuff)
544 {
545   pipeinf *pi = (pipeinf *)stuff->device_specific[FHDEVN(FH_PIPE)];
546   if (pi && pi->thread)
547     {
548       pi->stop_thread_pipe = TRUE;
549       WaitForSingleObject (pi->thread, INFINITE);
550       CloseHandle (pi->thread);
551       delete pi;
552       stuff->device_specific[FHDEVN(FH_PIPE)] = NULL;
553     }
554 }
555
556 select_record *
557 fhandler_pipe::select_read (select_record *s)
558 {
559   if (!s)
560     s = new select_record;
561   s->startup = start_thread_pipe;
562   s->poll = poll_pipe;
563   s->verify = verify_ok;
564   s->read_selected = TRUE;
565   s->cleanup = pipe_cleanup;
566   return s;
567 }
568
569 select_record *
570 fhandler_pipe::select_write (select_record *s)
571 {
572   if (!s)
573     {
574       s = new select_record;
575       s->startup = no_startup;
576       s->poll = poll_pipe;
577       s->verify = no_verify;
578     }
579   s->write_selected = TRUE;
580   s->write_ready = TRUE;
581   return s;
582 }
583
584 select_record *
585 fhandler_pipe::select_except (select_record *s)
586 {
587   if (!s)
588       s = new select_record;
589   s->startup = start_thread_pipe;
590   s->poll = poll_pipe;
591   s->verify = verify_ok;
592   s->cleanup = pipe_cleanup;
593   s->except_selected = TRUE;
594   return s;
595 }
596
597 static int
598 peek_console (select_record *me, int ignra)
599 {
600   extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *);
601   fhandler_console *fh = (fhandler_console *)me->fh;
602
603   if (!me->read_selected)
604     return me->write_ready;
605
606   if (!ignra && fh->get_readahead_valid ())
607     {
608       select_printf ("readahead");
609       return me->read_ready = 1;
610     }
611
612   if (me->read_ready)
613     {
614       select_printf ("already ready");
615       return 1;
616     }
617
618   INPUT_RECORD irec;
619   DWORD events_read;
620   HANDLE h;
621   char tmpbuf[17];
622   set_handle_or_return_if_not_open (h, me);
623
624   for (;;)
625     if (fh->bg_check (SIGTTIN) <= 0)
626       return me->read_ready = 1;
627     else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
628       break;
629     else
630       {
631         if (irec.EventType == WINDOW_BUFFER_SIZE_EVENT)
632           kill_pgrp (fh->tc->getpgid (), SIGWINCH);
633         else if (irec.EventType == KEY_EVENT && irec.Event.KeyEvent.bKeyDown == TRUE &&
634                  (irec.Event.KeyEvent.uChar.AsciiChar || get_nonascii_key (irec, tmpbuf)))
635           return me->read_ready = 1;
636
637         /* Read and discard the event */
638         ReadConsoleInput (h, &irec, 1, &events_read);
639       }
640
641   return me->write_ready;
642 }
643
644 static int
645 poll_console (select_record *me, fd_set *readfds, fd_set *writefds,
646               fd_set *exceptfds)
647 {
648   return peek_console (me, 0) ?
649          set_bits (me, readfds, writefds, exceptfds) :
650          0;
651 }
652
653 MAKEready (console)
654
655 select_record *
656 fhandler_console::select_read (select_record *s)
657 {
658   if (!s)
659     {
660       s = new select_record;
661       s->startup = no_startup;
662       s->poll = poll_console;
663       s->verify = poll_console;
664     }
665
666   s->h = get_handle ();
667   s->read_selected = TRUE;
668   return s;
669 }
670
671 select_record *
672 fhandler_console::select_write (select_record *s)
673 {
674   if (!s)
675     {
676       s = new select_record;
677       s->startup = no_startup;
678       s->poll = poll_console;
679       s->verify = no_verify;
680     }
681
682   s->write_selected = TRUE;
683   s->write_ready = TRUE;
684   return s;
685 }
686
687 select_record *
688 fhandler_console::select_except (select_record *s)
689 {
690   if (!s)
691     {
692       s = new select_record;
693       s->startup = no_startup;
694       s->poll = poll_console;
695       s->verify = no_verify;
696     }
697
698   s->except_selected = TRUE;
699   return s;
700 }
701
702 int
703 fhandler_tty_common::ready_for_read (int fd, DWORD howlong, int ignra)
704 {
705 #if 0
706   if (myself->pgid && get_ttyp ()->getpgid () != myself->pgid &&
707         myself->ctty == ttynum) // background process?
708     return 1;   // Yes. Let read return an error
709 #endif
710   return ((fhandler_pipe*)this)->fhandler_pipe::ready_for_read (fd, howlong, ignra);
711 }
712
713 select_record *
714 fhandler_tty_common::select_read (select_record *s)
715 {
716   return ((fhandler_pipe*)this)->fhandler_pipe::select_read (s);
717 }
718
719 select_record *
720 fhandler_tty_common::select_write (select_record *s)
721 {
722   return ((fhandler_pipe *)this)->fhandler_pipe::select_write (s);
723 }
724
725 select_record *
726 fhandler_tty_common::select_except (select_record *s)
727 {
728   return ((fhandler_pipe *)this)->fhandler_pipe::select_except (s);
729 }
730
731 select_record *
732 fhandler_dev_null::select_read (select_record *s)
733 {
734   if (!s)
735     {
736       s = new select_record;
737       s->startup = no_startup;
738       s->poll = set_bits;
739       s->verify = no_verify;
740     }
741   s->h = get_handle ();
742   s->read_selected = TRUE;
743   return s;
744 }
745
746 select_record *
747 fhandler_dev_null::select_write (select_record *s)
748 {
749   if (!s)
750     {
751       s = new select_record;
752       s->startup = no_startup;
753       s->poll = set_bits;
754       s->verify = no_verify;
755     }
756   s->h = get_handle ();
757   s->write_selected = TRUE;
758   return s;
759 }
760
761 select_record *
762 fhandler_dev_null::select_except (select_record *s)
763 {
764   if (!s)
765     {
766       s = new select_record;
767       s->startup = no_startup;
768       s->poll = set_bits;
769       s->verify = no_verify;
770     }
771   s->h = get_handle ();
772   s->except_selected = TRUE;
773   s->except_ready = TRUE;
774   return s;
775 }
776
777 static int start_thread_serial (select_record *me, select_stuff *stuff);
778
779 struct serialinf
780   {
781     HANDLE thread;
782     BOOL stop_thread_serial;
783     select_record *start;
784   };
785
786 static int
787 peek_serial (select_record *s, int)
788 {
789   DWORD ev;
790   COMSTAT st;
791
792   fhandler_serial *fh = (fhandler_serial *)s->fh;
793
794   if (fh->get_readahead_valid () || fh->overlapped_armed < 0)
795     return s->read_ready = 1;
796
797   select_printf ("fh->overlapped_armed %d", fh->overlapped_armed);
798
799   HANDLE h;
800   set_handle_or_return_if_not_open (h, s);
801   int ready = 0;
802
803   if (s->read_selected && s->read_ready || (s->write_selected && s->write_ready))
804     {
805       select_printf ("already ready");
806       ready = 1;
807       goto out;
808     }
809
810   (void) SetCommMask (h, EV_RXCHAR);
811
812   if (!fh->overlapped_armed)
813     {
814       DWORD ev;
815       COMSTAT st;
816
817       ResetEvent (fh->io_status.hEvent);
818
819       if (!ClearCommError (h, &ev, &st))
820         {
821           debug_printf ("ClearCommError");
822           goto err;
823         }
824       else if (st.cbInQue)
825         return s->read_ready = 1;
826       else if (WaitCommEvent (h, &ev, &fh->io_status))
827         return s->read_ready = 1;
828       else if (GetLastError () == ERROR_IO_PENDING)
829         fh->overlapped_armed = 1;
830       else
831         {
832           debug_printf ("WaitCommEvent");
833           goto err;
834         }
835     }
836
837   HANDLE w4[2];
838   DWORD to;
839
840   w4[0] = fh->io_status.hEvent;
841   w4[1] = signal_arrived;
842   to = 10;
843
844   switch (WaitForMultipleObjects (2, w4, FALSE, to))
845     {
846     case WAIT_OBJECT_0:
847       if (!ClearCommError (h, &ev, &st))
848         {
849           debug_printf ("ClearCommError");
850           goto err;
851         }
852       else if (!st.cbInQue)
853         Sleep (to);
854       else
855         {
856           return s->read_ready = 1;
857           select_printf ("got something");
858         }
859       PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
860       break;
861     case WAIT_OBJECT_0 + 1:
862       PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
863       select_printf ("interrupt");
864       set_sig_errno (EINTR);
865       ready = -1;
866       break;
867     case WAIT_TIMEOUT:
868       PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
869       break;
870     default:
871       PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
872       debug_printf ("WaitForMultipleObjects");
873       goto err;
874     }
875
876 out:
877   return ready;
878
879 err:
880   if (GetLastError () == ERROR_OPERATION_ABORTED)
881     {
882       select_printf ("operation aborted");
883       return ready;
884     }
885
886   __seterrno ();
887   s->saw_error = TRUE;
888   select_printf ("error %E");
889   return -1;
890 }
891
892 static DWORD WINAPI
893 thread_serial (void *arg)
894 {
895   serialinf *si = (serialinf *)arg;
896   BOOL gotone= FALSE;
897
898   for (;;)
899     {
900       select_record *s = si->start;
901       while ((s = s->next))
902         if (s->startup == start_thread_serial)
903           {
904             if (peek_serial (s, 0))
905               gotone = TRUE;
906           }
907       if (si->stop_thread_serial)
908         {
909           select_printf ("stopping");
910           break;
911         }
912       if (gotone)
913         break;
914     }
915
916   select_printf ("exiting");
917   return 0;
918 }
919
920 static int
921 start_thread_serial (select_record *me, select_stuff *stuff)
922 {
923   if (stuff->device_specific[FHDEVN(FH_SERIAL)])
924     {
925       me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_SERIAL)])->thread;
926       return 1;
927     }
928   serialinf *si = new serialinf;
929   si->start = &stuff->start;
930   si->stop_thread_serial = FALSE;
931   si->thread = me->h = makethread (thread_serial, (LPVOID)si, 0, "select_serial");
932   if (!me->h)
933     return 0;
934   stuff->device_specific[FHDEVN(FH_SERIAL)] = (void *)si;
935   return 1;
936 }
937
938 static void
939 serial_cleanup (select_record *, select_stuff *stuff)
940 {
941   serialinf *si = (serialinf *)stuff->device_specific[FHDEVN(FH_SERIAL)];
942   if (si && si->thread)
943     {
944       si->stop_thread_serial = TRUE;
945       WaitForSingleObject (si->thread, INFINITE);
946       CloseHandle (si->thread);
947       delete si;
948       stuff->device_specific[FHDEVN(FH_SERIAL)] = NULL;
949     }
950 }
951
952 static int
953 poll_serial (select_record *me, fd_set *readfds, fd_set *writefds,
954            fd_set *exceptfds)
955
956 {
957   return peek_serial (me, 0) ?
958          set_bits (me, readfds, writefds, exceptfds) :
959          0;
960 }
961
962 MAKEready (serial)
963
964 select_record *
965 fhandler_serial::select_read (select_record *s)
966 {
967   if (!s)
968     {
969       s = new select_record;
970       s->startup = start_thread_serial;
971       s->poll = poll_serial;
972       s->verify = verify_ok;
973       s->cleanup = serial_cleanup;
974     }
975   s->read_selected = TRUE;
976   return s;
977 }
978
979 select_record *
980 fhandler_serial::select_write (select_record *s)
981 {
982   if (!s)
983     {
984       s = new select_record;
985       s->startup = no_startup;
986       s->poll = set_bits;
987       s->verify = verify_ok;
988     }
989   s->h = get_handle ();
990   s->write_selected = TRUE;
991   s->write_ready = TRUE;
992   return s;
993 }
994
995 select_record *
996 fhandler_serial::select_except (select_record *s)
997 {
998   if (!s)
999     {
1000       s = new select_record;
1001       s->startup = no_startup;
1002       s->poll = set_bits;
1003       s->verify = verify_ok;
1004     }
1005   s->h = NULL;
1006   s->except_selected = FALSE;   // Can't do this
1007   return s;
1008 }
1009
1010 int
1011 fhandler_base::ready_for_read (int, DWORD, int)
1012 {
1013   return 1;
1014 }
1015
1016 select_record *
1017 fhandler_base::select_read (select_record *s)
1018 {
1019   if (!s)
1020     {
1021       s = new select_record;
1022       s->startup = no_startup;
1023       s->poll = set_bits;
1024       s->verify = verify_ok;
1025     }
1026   s->h = get_handle ();
1027   s->read_selected = TRUE;
1028   s->read_ready = TRUE;
1029   return s;
1030 }
1031
1032 select_record *
1033 fhandler_base::select_write (select_record *s)
1034 {
1035   if (!s)
1036     {
1037       s = new select_record;
1038       s->startup = no_startup;
1039       s->poll = set_bits;
1040       s->verify = verify_ok;
1041     }
1042   s->h = get_handle ();
1043   s->write_selected = TRUE;
1044   s->write_ready = TRUE;
1045   return s;
1046 }
1047
1048 select_record *
1049 fhandler_base::select_except (select_record *s)
1050 {
1051   if (!s)
1052     {
1053       s = new select_record;
1054       s->startup = no_startup;
1055       s->poll = set_bits;
1056       s->verify = verify_ok;
1057     }
1058   s->h = NULL;
1059   s->write_selected = TRUE;
1060   return s;
1061 }
1062
1063 struct socketinf
1064   {
1065     HANDLE thread;
1066     winsock_fd_set readfds, writefds, exceptfds;
1067     SOCKET exitsock;
1068     struct sockaddr_in sin;
1069     select_record *start;
1070   };
1071
1072 static int
1073 peek_socket (select_record *me, int)
1074 {
1075   winsock_fd_set ws_readfds, ws_writefds, ws_exceptfds;
1076   struct timeval tv = {0, 0};
1077   WINSOCK_FD_ZERO (&ws_readfds);
1078   WINSOCK_FD_ZERO (&ws_writefds);
1079   WINSOCK_FD_ZERO (&ws_exceptfds);
1080   int gotone = 0;
1081
1082   HANDLE h;
1083   set_handle_or_return_if_not_open (h, me);
1084   select_printf ("considering handle %p", h);
1085
1086   if (me->read_selected)
1087     {
1088       select_printf ("adding read fd_set %s, fd %d", me->fh->get_name (),
1089                      me->fd);
1090       WINSOCK_FD_SET (h, &ws_readfds);
1091     }
1092   if (me->write_selected)
1093     {
1094       select_printf ("adding write fd_set %s, fd %d", me->fh->get_name (),
1095                      me->fd);
1096       WINSOCK_FD_SET (h, &ws_writefds);
1097     }
1098   if (me->except_selected)
1099     {
1100       select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (),
1101                      me->fd);
1102       WINSOCK_FD_SET (h, &ws_exceptfds);
1103     }
1104   int r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv);
1105   select_printf ("WINSOCK_SELECT returned %d", r);
1106   if (r == -1)
1107     {
1108       select_printf ("error %d", WSAGetLastError ());
1109       return 0;
1110     }
1111
1112   if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
1113     gotone = me->read_ready = TRUE;
1114   if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
1115     gotone = me->write_ready = TRUE;
1116   if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || (me->except_selected && me->except_ready))
1117     gotone = me->except_ready = TRUE;
1118   return gotone;
1119 }
1120
1121 static int
1122 poll_socket (select_record *me, fd_set *readfds, fd_set *writefds,
1123            fd_set *exceptfds)
1124 {
1125   return peek_socket (me, 0) ?
1126          set_bits (me, readfds, writefds, exceptfds) :
1127          0;
1128 }
1129
1130 MAKEready (socket)
1131
1132 static int start_thread_socket (select_record *, select_stuff *);
1133
1134 static DWORD WINAPI
1135 thread_socket (void *arg)
1136 {
1137   socketinf *si = (socketinf *)arg;
1138
1139   select_printf ("stuff_start %p", &si->start);
1140   int r = WINSOCK_SELECT (0, &si->readfds, &si->writefds, &si->exceptfds, NULL);
1141   select_printf ("Win32 select returned %d", r);
1142   if (r == -1)
1143     select_printf ("error %d", WSAGetLastError ());
1144   select_record *s = si->start;
1145   while ((s = s->next))
1146     if (s->startup == start_thread_socket)
1147         {
1148           HANDLE h = s->fh->get_handle ();
1149           select_printf ("s %p, testing fd %d (%s)", s, s->fd, s->fh->get_name ());
1150           if (WINSOCK_FD_ISSET (h, &si->readfds))
1151             {
1152               select_printf ("read_ready");
1153               s->read_ready = TRUE;
1154             }
1155           if (WINSOCK_FD_ISSET (h, &si->writefds))
1156             {
1157               select_printf ("write_ready");
1158               s->write_ready = TRUE;
1159             }
1160           if (WINSOCK_FD_ISSET (h, &si->exceptfds))
1161             {
1162               select_printf ("except_ready");
1163               s->except_ready = TRUE;
1164             }
1165         }
1166
1167   if (WINSOCK_FD_ISSET (si->exitsock, &si->readfds))
1168     select_printf ("saw exitsock read");
1169
1170   return 0;
1171 }
1172
1173 extern "C" unsigned long htonl (unsigned long);
1174
1175 static int
1176 start_thread_socket (select_record *me, select_stuff *stuff)
1177 {
1178   socketinf *si;
1179
1180   if ((si = (socketinf *)stuff->device_specific[FHDEVN(FH_SOCKET)]))
1181     {
1182       me->h = si->thread;
1183       return 1;
1184     }
1185
1186   si = new socketinf;
1187   WINSOCK_FD_ZERO (&si->readfds);
1188   WINSOCK_FD_ZERO (&si->writefds);
1189   WINSOCK_FD_ZERO (&si->exceptfds);
1190   select_record *s = &stuff->start;
1191   while ((s = s->next))
1192     if (s->startup == start_thread_socket)
1193       {
1194         HANDLE h = s->fh->get_handle ();
1195         select_printf ("Handle %p", h);
1196         if (s->read_selected)
1197           {
1198             WINSOCK_FD_SET (h, &si->readfds);
1199             select_printf ("Added to readfds");
1200           }
1201         if (s->write_selected)
1202           {
1203             WINSOCK_FD_SET (h, &si->writefds);
1204             select_printf ("Added to writefds");
1205           }
1206         if (s->except_selected)
1207           {
1208             WINSOCK_FD_SET (h, &si->exceptfds);
1209             select_printf ("Added to exceptfds");
1210           }
1211       }
1212
1213   if ((si->exitsock = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
1214     {
1215       set_winsock_errno ();
1216       select_printf ("cannot create socket, %E");
1217       return -1;
1218     }
1219   /* Allow rapid reuse of the port. */
1220   int tmp = 1;
1221   (void) setsockopt (si->exitsock, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
1222
1223   int sin_len = sizeof(si->sin);
1224   memset (&si->sin, 0, sizeof (si->sin));
1225   si->sin.sin_family = AF_INET;
1226   si->sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
1227   if (bind (si->exitsock, (struct sockaddr *) &si->sin, sizeof (si->sin)) < 0)
1228     {
1229       select_printf ("cannot bind socket, %E");
1230       goto err;
1231     }
1232
1233   if (getsockname (si->exitsock, (struct sockaddr *) &si->sin, &sin_len) < 0)
1234     {
1235       select_printf ("getsockname error");
1236       goto err;
1237     }
1238
1239   if (listen (si->exitsock, 1))
1240     {
1241       select_printf ("listen failed, %E");
1242       goto err;
1243     }
1244
1245   select_printf ("exitsock %p", si->exitsock);
1246   WINSOCK_FD_SET ((HANDLE) si->exitsock, &si->readfds);
1247   WINSOCK_FD_SET ((HANDLE) si->exitsock, &si->exceptfds);
1248   stuff->device_specific[FHDEVN(FH_SOCKET)] = (void *) si;
1249   si->start = &stuff->start;
1250   select_printf ("stuff_start %p", &stuff->start);
1251   si->thread = me->h = makethread (thread_socket, (LPVOID)si, 0,
1252                                   "select_socket");
1253   return !!me->h;
1254
1255 err:
1256   set_winsock_errno ();
1257   closesocket (si->exitsock);
1258   return -1;
1259 }
1260
1261 void
1262 socket_cleanup (select_record *, select_stuff *stuff)
1263 {
1264   socketinf *si = (socketinf *)stuff->device_specific[FHDEVN(FH_SOCKET)];
1265   select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
1266   if (si && si->thread)
1267     {
1268       select_printf ("connection to si->exitsock %p", si->exitsock);
1269       SOCKET s = socket (AF_INET, SOCK_STREAM, 0);
1270       /* Connecting to si->exitsock will cause any executing select to wake
1271          up.  When this happens then the exitsock condition will cause the
1272          thread to terminate. */
1273       if (connect (s, (struct sockaddr *) &si->sin, sizeof (si->sin)) < 0)
1274         {
1275           set_winsock_errno ();
1276           select_printf ("connect failed");
1277           /* FIXME: now what? */
1278         }
1279       shutdown (s, 2);
1280       closesocket (s);
1281
1282       /* Wait for thread to go away */
1283       WaitForSingleObject (si->thread, INFINITE);
1284       shutdown (si->exitsock, 2);
1285       closesocket (si->exitsock);
1286       CloseHandle (si->thread);
1287       stuff->device_specific[FHDEVN(FH_SOCKET)] = NULL;
1288       delete si;
1289     }
1290   select_printf ("returning");
1291 }
1292
1293 select_record *
1294 fhandler_socket::select_read (select_record *s)
1295 {
1296   if (!s)
1297     {
1298       s = new select_record;
1299       s->startup = start_thread_socket;
1300       s->poll = poll_socket;
1301       s->verify = verify_true;
1302       s->cleanup = socket_cleanup;
1303     }
1304   s->read_selected = TRUE;
1305   return s;
1306 }
1307
1308 select_record *
1309 fhandler_socket::select_write (select_record *s)
1310 {
1311   if (!s)
1312     {
1313       s = new select_record;
1314       s->startup = start_thread_socket;
1315       s->poll = poll_socket;
1316       s->verify = verify_true;
1317       s->cleanup = socket_cleanup;
1318     }
1319   s->write_selected = TRUE;
1320   return s;
1321 }
1322
1323 select_record *
1324 fhandler_socket::select_except (select_record *s)
1325 {
1326   if (!s)
1327     {
1328       s = new select_record;
1329       s->startup = start_thread_socket;
1330       s->poll = poll_socket;
1331       s->verify = verify_true;
1332       s->cleanup = socket_cleanup;
1333     }
1334   s->except_selected = TRUE;
1335   return s;
1336 }
1337
1338 static int
1339 peek_windows (select_record *me, int)
1340 {
1341   MSG m;
1342   HANDLE h;
1343   set_handle_or_return_if_not_open (h, me);
1344
1345   if (me->read_selected && me->read_ready)
1346     return 1;
1347
1348   if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE))
1349     {
1350       me->read_ready = TRUE;
1351       select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
1352       return 1;
1353     }
1354
1355   select_printf ("window %d(%p) not ready", me->fd, me->fh->get_handle ());
1356   return me->write_ready;
1357 }
1358
1359 static int
1360 poll_windows (select_record *me, fd_set *readfds, fd_set *writefds,
1361               fd_set *exceptfds)
1362 {
1363
1364   return peek_windows (me, 0) ?
1365          set_bits (me, readfds, writefds, exceptfds) :
1366          0;
1367 }
1368
1369 MAKEready (windows)
1370
1371 select_record *
1372 fhandler_windows::select_read (select_record *s)
1373 {
1374   if (!s)
1375     {
1376       s = new select_record;
1377       s->startup = no_startup;
1378       s->poll = poll_windows;
1379       s->verify = poll_windows;
1380     }
1381   s->h = get_handle ();
1382   s->read_selected = TRUE;
1383   s->h = get_handle ();
1384   s->windows_handle = TRUE;
1385   return s;
1386 }
1387
1388 select_record *
1389 fhandler_windows::select_write (select_record *s)
1390 {
1391   if (!s)
1392     {
1393       s = new select_record;
1394       s->startup = no_startup;
1395       s->poll = set_bits;
1396       s->verify = verify_ok;
1397     }
1398   s->h = get_handle ();
1399   s->write_selected = TRUE;
1400   s->write_ready = TRUE;
1401   s->windows_handle = TRUE;
1402   return s;
1403 }
1404
1405 select_record *
1406 fhandler_windows::select_except (select_record *s)
1407 {
1408   if (!s)
1409     {
1410       s = new select_record;
1411       s->startup = no_startup;
1412       s->poll = set_bits;
1413       s->verify = verify_ok;
1414     }
1415   s->h = get_handle ();
1416   s->except_selected = TRUE;
1417   s->except_ready = TRUE;
1418   s->windows_handle = TRUE;
1419   return s;
1420 }