3 Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
5 Written by Christopher Faylor of Cygnus Solutions
8 This file is part of Cygwin.
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
15 * The following line means that the BSD socket
16 * definitions for fd_set, FD_ISSET etc. are used in this
20 #define __INSIDE_CYGWIN_NET__
24 #include <sys/socket.h>
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.
42 #define NBBY 8 /* number of bits in a byte */
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).
53 #define UNIX_NFDBITS (sizeof (fd_mask) * NBBY) /* bits per mask */
55 #define unix_howmany(x,y) (((x)+((y)-1))/(y))
58 #define unix_fd_set fd_set
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)))
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));
75 /* Make a fhandler_foo::ready_for_ready method.
76 Assumption: The "ready_for_read" methods are called with one level of
78 #define MAKEready(what) \
80 fhandler_##what::ready_for_read (int fd, DWORD howlong, int ignra) \
82 select_record me (this); \
84 (void) select_read (&me); \
85 while (!peek_##what (&me, ignra) && howlong == INFINITE) \
86 if (fd >= 0 && dtable.not_open (fd)) \
88 else if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0) \
90 return me.read_ready; \
93 #define set_handle_or_return_if_not_open(h, s) \
94 h = (s)->fh->get_handle (); \
95 if (dtable.not_open ((s)->fd)) \
97 (s)->saw_error = TRUE; \
102 /* The main select code.
106 cygwin_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
110 fd_set *dummy_readfds = allocfd_set (n);
111 fd_set *dummy_writefds = allocfd_set (n);
112 fd_set *dummy_exceptfds = allocfd_set (n);
122 select_printf ("%d, %p, %p, %p, %p", n, readfds, writefds, exceptfds, to);
124 memset (&sel, 0, sizeof (sel));
127 UNIX_FD_ZERO (dummy_readfds, n);
128 readfds = dummy_readfds;
132 UNIX_FD_ZERO (dummy_writefds, n);
133 writefds = dummy_writefds;
137 UNIX_FD_ZERO (dummy_exceptfds, n);
138 exceptfds = dummy_exceptfds;
141 for (int i = 0; i < n; i++)
142 if (!sel.test_and_set (i, readfds, writefds, exceptfds))
144 select_printf ("aborting due to test_and_set error");
145 return -1; /* Invalid fd, maybe? */
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 */
154 select_printf ("to->tv_sec %d, to->tv_usec %d, ms %d", to->tv_sec, to->tv_usec, ms);
156 select_printf ("to NULL, ms %x", ms);
158 select_printf ("sel.total %d, sel.always_ready %d", sel.total, sel.always_ready);
160 /* Degenerate case. No fds to wait for. Just wait. */
163 if (WaitForSingleObject (signal_arrived, ms) == WAIT_OBJECT_0)
165 select_printf ("signal received");
166 set_sig_errno (EINTR);
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)
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);
182 /* Wait for an fd to come alive */
183 return sel.wait (readfds, writefds, exceptfds, ms);
187 select_stuff::~select_stuff ()
189 select_record *s = &start;
191 select_printf ("calling cleanup routines");
192 while ((s = s->next))
194 s->cleanup (s, this);
196 select_record *snext = start.next;
198 select_printf ("deleting select records");
206 /* Add a record to the select chain */
208 select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
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 */
219 return 1; /* nothing to do */
221 if (s->read_ready || s->write_ready || s->except_ready)
224 if (s->windows_handle || s->windows_handle || s->windows_handle)
227 s->next = start.next;
233 /* Poll every fd in the select chain. Set appropriate fd in mask. */
235 select_stuff::poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
238 select_record *s = &start;
239 while ((s = s->next))
240 n += s->poll (s, readfds, writefds, exceptfds);
241 select_printf ("returning %d", n);
245 /* The heart of select. Waits for an fd to do something interesting. */
247 select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
251 HANDLE w4[total + 1];
252 select_record *s = &start;
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))
260 if (!s->startup (s, this))
267 for (int i = 1; i < m; i++)
276 DWORD start_time = GetTickCount (); /* Record the current time for later use. */
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);
285 debug_printf ("n %d, ms %u", n, ms);
289 wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
291 wait_ret = MsgWaitForMultipleObjects (m, w4, FALSE, ms, QS_ALLINPUT);
296 select_printf ("signal received");
297 set_sig_errno (EINTR);
300 select_printf ("WaitForMultipleObjects failed");
304 select_printf ("timed out");
308 select_printf ("woke up. wait_ret %d. verifying", wait_ret);
311 while ((s = s->next))
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))
318 select_printf ("gotone %d", gotone);
324 select_printf ("looping");
327 select_printf ("recalculating ms");
329 DWORD now = GetTickCount ();
330 if (now > (start_time + ms))
332 select_printf ("timed out after verification");
335 ms -= (now - start_time);
337 select_printf ("ms now %u", ms);
341 copyfd_set (readfds, r, n);
342 copyfd_set (writefds, w, n);
343 copyfd_set (exceptfds, e, n);
345 return poll (readfds, writefds, exceptfds);
349 set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
353 select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
354 if (me->read_selected && me->read_ready)
356 UNIX_FD_SET (me->fd, readfds);
359 if (me->write_selected && me->write_ready)
361 UNIX_FD_SET (me->fd, writefds);
364 if (me->except_ready && me->except_ready)
366 UNIX_FD_SET (me->fd, exceptfds);
369 select_printf ("ready %d", ready);
374 verify_true (select_record *, fd_set *, fd_set *, fd_set *)
380 verify_ok (select_record *me, fd_set *readfds, fd_set *writefds,
383 return set_bits (me, readfds, writefds, exceptfds);
387 no_startup (select_record *, select_stuff *)
393 no_verify (select_record *, fd_set *, fd_set *, fd_set *)
399 peek_pipe (select_record *s, int ignra)
403 fhandler_base *fh = s->fh;
406 set_handle_or_return_if_not_open (h, s);
408 /* Don't perform complicated tests if we don't need to. */
409 if (!s->read_selected && !s->except_selected)
412 if (s->read_selected)
414 if (fh->bg_check (SIGTTIN) <= 0)
416 gotone = s->read_ready = 1;
420 if (!ignra && fh->get_device () != FH_PTYM && fh->get_device () != FH_TTYM &&
421 fh->get_readahead_valid ())
423 select_printf ("readahead");
424 gotone = s->read_ready = 1;
429 if (!PeekNamedPipe (h, NULL, 0, NULL, (DWORD *) &n, NULL))
431 select_printf ("%s, PeekNamedPipe failed, %E", fh->get_name ());
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;
443 if (n > 0 && s->read_selected)
445 select_printf ("%s, ready for read", fh->get_name ());
446 gotone += s->read_ready = TRUE;
448 if (!gotone && s->fh->hit_eof ())
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;
458 return gotone || s->write_ready;
462 poll_pipe (select_record *me, fd_set *readfds, fd_set *writefds,
465 return peek_pipe (me, 0) ?
466 set_bits (me, readfds, writefds, exceptfds) :
472 static int start_thread_pipe (select_record *me, select_stuff *stuff);
477 BOOL stop_thread_pipe;
478 select_record *start;
482 thread_pipe (void *arg)
484 pipeinf *pi = (pipeinf *)arg;
489 select_record *s = pi->start;
490 while ((s = s->next))
491 if (s->startup == start_thread_pipe)
493 if (peek_pipe (s, 0))
495 if (pi->stop_thread_pipe)
497 select_printf ("stopping");
510 start_thread_pipe (select_record *me, select_stuff *stuff)
512 if (stuff->device_specific[FHDEVN(FH_PIPE)])
514 me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_PIPE)])->thread;
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");
523 stuff->device_specific[FHDEVN(FH_PIPE)] = (void *)pi;
528 pipe_cleanup (select_record *, select_stuff *stuff)
530 pipeinf *pi = (pipeinf *)stuff->device_specific[FHDEVN(FH_PIPE)];
531 if (pi && pi->thread)
533 pi->stop_thread_pipe = TRUE;
534 WaitForSingleObject (pi->thread, INFINITE);
535 CloseHandle (pi->thread);
537 stuff->device_specific[FHDEVN(FH_PIPE)] = NULL;
542 fhandler_pipe::select_read (select_record *s)
545 s = new select_record;
546 s->startup = start_thread_pipe;
548 s->verify = verify_ok;
549 s->read_selected = TRUE;
550 s->cleanup = pipe_cleanup;
555 fhandler_pipe::select_write (select_record *s)
559 s = new select_record;
560 s->startup = no_startup;
562 s->verify = no_verify;
564 s->write_selected = TRUE;
565 s->write_ready = TRUE;
570 fhandler_pipe::select_except (select_record *s)
573 s = new select_record;
574 s->startup = start_thread_pipe;
576 s->verify = verify_ok;
577 s->cleanup = pipe_cleanup;
578 s->except_selected = TRUE;
583 peek_console (select_record *me, int ignra)
585 extern const char * get_nonascii_key (INPUT_RECORD& input_rec);
586 fhandler_console *fh = (fhandler_console *)me->fh;
588 if (!me->read_selected)
589 return me->write_ready;
591 if (!ignra && fh->get_readahead_valid ())
593 select_printf ("readahead");
594 return me->read_ready = 1;
600 set_handle_or_return_if_not_open (h, me);
603 if (fh->bg_check (SIGTTIN) <= 0)
604 return me->read_ready = 1;
605 else if (!PeekConsoleInput (h, &irec, 1, &events_read) || !events_read)
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;
615 /* Read and discard the event */
616 ReadConsoleInput (h, &irec, 1, &events_read);
619 return me->write_ready;
623 poll_console (select_record *me, fd_set *readfds, fd_set *writefds,
626 return peek_console (me, 0) ?
627 set_bits (me, readfds, writefds, exceptfds) :
634 fhandler_console::select_read (select_record *s)
638 s = new select_record;
639 s->startup = no_startup;
640 s->poll = poll_console;
641 s->verify = poll_console;
644 s->h = get_handle ();
645 s->read_selected = TRUE;
650 fhandler_console::select_write (select_record *s)
654 s = new select_record;
655 s->startup = no_startup;
656 s->poll = poll_console;
657 s->verify = no_verify;
660 s->write_selected = TRUE;
661 s->write_ready = TRUE;
666 fhandler_console::select_except (select_record *s)
670 s = new select_record;
671 s->startup = no_startup;
672 s->poll = poll_console;
673 s->verify = no_verify;
676 s->except_selected = TRUE;
681 fhandler_tty_common::ready_for_read (int fd, DWORD howlong, int ignra)
684 if (myself->pgid && get_ttyp ()->getpgid () != myself->pgid &&
685 myself->ctty == ttynum) // background process?
686 return 1; // Yes. Let read return an error
688 return ((fhandler_pipe*)this)->fhandler_pipe::ready_for_read (fd, howlong, ignra);
692 fhandler_tty_common::select_read (select_record *s)
694 return ((fhandler_pipe*)this)->fhandler_pipe::select_read (s);
698 fhandler_tty_common::select_write (select_record *s)
700 return ((fhandler_pipe *)this)->fhandler_pipe::select_write (s);
704 fhandler_tty_common::select_except (select_record *s)
706 return ((fhandler_pipe *)this)->fhandler_pipe::select_except (s);
710 fhandler_dev_null::select_read (select_record *s)
714 s = new select_record;
715 s->startup = no_startup;
717 s->verify = no_verify;
719 s->h = get_handle ();
720 s->read_selected = TRUE;
725 fhandler_dev_null::select_write (select_record *s)
729 s = new select_record;
730 s->startup = no_startup;
732 s->verify = no_verify;
734 s->h = get_handle ();
735 s->write_selected = TRUE;
740 fhandler_dev_null::select_except (select_record *s)
744 s = new select_record;
745 s->startup = no_startup;
747 s->verify = no_verify;
749 s->h = get_handle ();
750 s->except_selected = TRUE;
751 s->except_ready = TRUE;
755 static int start_thread_serial (select_record *me, select_stuff *stuff);
760 BOOL stop_thread_serial;
761 select_record *start;
765 peek_serial (select_record *s, int)
770 fhandler_serial *fh = (fhandler_serial *)s->fh;
772 if (fh->get_readahead_valid () || fh->overlapped_armed < 0)
773 return s->read_ready = 1;
775 select_printf ("fh->overlapped_armed %d", fh->overlapped_armed);
778 set_handle_or_return_if_not_open (h, s);
780 (void) SetCommMask (h, EV_RXCHAR);
782 if (!fh->overlapped_armed)
787 ResetEvent (fh->io_status.hEvent);
789 if (!ClearCommError (h, &ev, &st))
791 debug_printf ("ClearCommError");
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;
802 debug_printf ("WaitCommEvent");
810 w4[0] = fh->io_status.hEvent;
811 w4[1] = signal_arrived;
814 switch (WaitForMultipleObjects (2, w4, FALSE, to))
817 if (!ClearCommError (h, &ev, &st))
819 debug_printf ("ClearCommError");
822 else if (!st.cbInQue)
826 return s->read_ready = 1;
827 select_printf ("got something");
829 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
831 case WAIT_OBJECT_0 + 1:
832 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
833 select_printf ("interrupt");
834 set_sig_errno (EINTR);
838 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
841 PurgeComm (h, PURGE_TXABORT | PURGE_RXABORT);
842 debug_printf ("WaitForMultipleObjects");
849 if (GetLastError () == ERROR_OPERATION_ABORTED)
851 select_printf ("operation aborted");
857 select_printf ("error %E");
862 thread_serial (void *arg)
864 serialinf *si = (serialinf *)arg;
869 select_record *s = si->start;
870 while ((s = s->next))
871 if (s->startup == start_thread_serial)
873 if (peek_serial (s, 0))
876 if (si->stop_thread_serial)
878 select_printf ("stopping");
885 select_printf ("exiting");
890 start_thread_serial (select_record *me, select_stuff *stuff)
892 if (stuff->device_specific[FHDEVN(FH_SERIAL)])
894 me->h = ((pipeinf *) stuff->device_specific[FHDEVN(FH_SERIAL)])->thread;
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");
903 stuff->device_specific[FHDEVN(FH_SERIAL)] = (void *)si;
908 serial_cleanup (select_record *, select_stuff *stuff)
910 serialinf *si = (serialinf *)stuff->device_specific[FHDEVN(FH_SERIAL)];
911 if (si && si->thread)
913 si->stop_thread_serial = TRUE;
914 WaitForSingleObject (si->thread, INFINITE);
915 CloseHandle (si->thread);
917 stuff->device_specific[FHDEVN(FH_SERIAL)] = NULL;
922 poll_serial (select_record *me, fd_set *readfds, fd_set *writefds,
926 return peek_serial (me, 0) ?
927 set_bits (me, readfds, writefds, exceptfds) :
934 fhandler_serial::select_read (select_record *s)
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;
944 s->read_selected = TRUE;
949 fhandler_serial::select_write (select_record *s)
953 s = new select_record;
954 s->startup = no_startup;
956 s->verify = verify_ok;
958 s->h = get_handle ();
959 s->write_selected = TRUE;
960 s->write_ready = TRUE;
965 fhandler_serial::select_except (select_record *s)
969 s = new select_record;
970 s->startup = no_startup;
972 s->verify = verify_ok;
975 s->except_selected = FALSE; // Can't do this
980 fhandler_base::ready_for_read (int, DWORD, int)
986 fhandler_base::select_read (select_record *s)
990 s = new select_record;
991 s->startup = no_startup;
993 s->verify = verify_ok;
995 s->h = get_handle ();
996 s->read_selected = TRUE;
997 s->read_ready = TRUE;
1002 fhandler_base::select_write (select_record *s)
1006 s = new select_record;
1007 s->startup = no_startup;
1009 s->verify = verify_ok;
1011 s->h = get_handle ();
1012 s->write_selected = TRUE;
1013 s->write_ready = TRUE;
1018 fhandler_base::select_except (select_record *s)
1022 s = new select_record;
1023 s->startup = no_startup;
1025 s->verify = verify_ok;
1028 s->write_selected = TRUE;
1035 winsock_fd_set readfds, writefds, exceptfds;
1037 struct sockaddr_in sin;
1038 select_record *start;
1042 peek_socket (select_record *me, int)
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);
1052 set_handle_or_return_if_not_open (h, me);
1053 select_printf ("considering handle %p", h);
1055 if (me->read_selected)
1057 select_printf ("adding read fd_set %s, fd %d", me->fh->get_name (),
1059 WINSOCK_FD_SET (h, &ws_readfds);
1061 if (me->write_selected)
1063 select_printf ("adding write fd_set %s, fd %d", me->fh->get_name (),
1065 WINSOCK_FD_SET (h, &ws_writefds);
1067 if (me->except_selected)
1069 select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (),
1071 WINSOCK_FD_SET (h, &ws_exceptfds);
1073 int r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv);
1074 select_printf ("WINSOCK_SELECT returned %d", r);
1077 select_printf ("error %d", WSAGetLastError ());
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;
1091 poll_socket (select_record *me, fd_set *readfds, fd_set *writefds,
1094 return peek_socket (me, 0) ?
1095 set_bits (me, readfds, writefds, exceptfds) :
1101 static int start_thread_socket (select_record *, select_stuff *);
1104 thread_socket (void *arg)
1106 socketinf *si = (socketinf *)arg;
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);
1112 select_printf ("error %d", WSAGetLastError ());
1113 select_record *s = si->start;
1114 while ((s = s->next))
1115 if (s->startup == start_thread_socket)
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))
1121 select_printf ("read_ready");
1122 s->read_ready = TRUE;
1124 if (WINSOCK_FD_ISSET (h, &si->writefds))
1126 select_printf ("write_ready");
1127 s->write_ready = TRUE;
1129 if (WINSOCK_FD_ISSET (h, &si->exceptfds))
1131 select_printf ("except_ready");
1132 s->except_ready = TRUE;
1136 if (WINSOCK_FD_ISSET (si->exitsock, &si->readfds))
1137 select_printf ("saw exitsock read");
1142 extern "C" unsigned long htonl (unsigned long);
1145 start_thread_socket (select_record *me, select_stuff *stuff)
1149 if ((si = (socketinf *)stuff->device_specific[FHDEVN(FH_SOCKET)]))
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)
1163 HANDLE h = s->fh->get_handle ();
1164 select_printf ("Handle %p", h);
1165 if (s->read_selected)
1167 WINSOCK_FD_SET (h, &si->readfds);
1168 select_printf ("Added to readfds");
1170 if (s->write_selected)
1172 WINSOCK_FD_SET (h, &si->writefds);
1173 select_printf ("Added to writefds");
1175 if (s->except_selected)
1177 WINSOCK_FD_SET (h, &si->exceptfds);
1178 select_printf ("Added to exceptfds");
1182 if ((si->exitsock = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
1184 set_winsock_errno ();
1185 select_printf ("cannot create socket, %E");
1188 /* Allow rapid reuse of the port. */
1190 (void) setsockopt (si->exitsock, SOL_SOCKET, SO_REUSEADDR, (char *) &tmp, sizeof (tmp));
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)
1198 select_printf ("cannot bind socket, %E");
1202 if (getsockname (si->exitsock, (struct sockaddr *) &si->sin, &sin_len) < 0)
1204 select_printf ("getsockname error");
1208 if (listen (si->exitsock, 1))
1210 select_printf ("listen failed, %E");
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,
1225 set_winsock_errno ();
1226 closesocket (si->exitsock);
1231 socket_cleanup (select_record *, select_stuff *stuff)
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)
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)
1244 set_winsock_errno ();
1245 select_printf ("connect failed");
1246 /* FIXME: now what? */
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;
1257 select_printf ("returning");
1261 fhandler_socket::select_read (select_record *s)
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;
1271 s->read_selected = TRUE;
1276 fhandler_socket::select_write (select_record *s)
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;
1286 s->write_selected = TRUE;
1291 fhandler_socket::select_except (select_record *s)
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;
1301 s->except_selected = TRUE;
1306 peek_windows (select_record *me, int)
1310 set_handle_or_return_if_not_open (h, me);
1311 if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE))
1313 me->read_ready = TRUE;
1314 select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
1318 select_printf ("window %d(%p) not ready", me->fd, me->fh->get_handle ());
1319 return me->write_ready;
1323 poll_windows (select_record *me, fd_set *readfds, fd_set *writefds,
1327 return peek_windows (me, 0) ?
1328 set_bits (me, readfds, writefds, exceptfds) :
1335 fhandler_windows::select_read (select_record *s)
1339 s = new select_record;
1340 s->startup = no_startup;
1341 s->poll = poll_windows;
1342 s->verify = poll_windows;
1344 s->h = get_handle ();
1345 s->read_selected = TRUE;
1346 s->h = get_handle ();
1347 s->windows_handle = TRUE;
1352 fhandler_windows::select_write (select_record *s)
1356 s = new select_record;
1357 s->startup = no_startup;
1359 s->verify = verify_ok;
1361 s->h = get_handle ();
1362 s->write_selected = TRUE;
1363 s->write_ready = TRUE;
1364 s->windows_handle = TRUE;
1369 fhandler_windows::select_except (select_record *s)
1373 s = new select_record;
1374 s->startup = no_startup;
1376 s->verify = verify_ok;
1378 s->h = get_handle ();
1379 s->except_selected = TRUE;
1380 s->except_ready = TRUE;
1381 s->windows_handle = TRUE;