OSDN Git Service

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