* ser-mingw.c: Include <conio.h>.
[external/binutils.git] / gdb / ser-mingw.c
1 /* Serial interface for local (hardwired) serial ports on Windows systems
2
3    Copyright (C) 2006
4    Free Software Foundation, Inc.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.  */
22
23 #include "defs.h"
24 #include "serial.h"
25 #include "ser-base.h"
26 #include "ser-tcp.h"
27
28 #include <windows.h>
29 #include <conio.h>
30
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <sys/types.h>
34
35 #include "gdb_assert.h"
36 #include "gdb_string.h"
37
38 void _initialize_ser_windows (void);
39
40 struct ser_windows_state
41 {
42   int in_progress;
43   OVERLAPPED ov;
44   DWORD lastCommMask;
45   HANDLE except_event;
46 };
47
48 /* Open up a real live device for serial I/O.  */
49
50 static int
51 ser_windows_open (struct serial *scb, const char *name)
52 {
53   HANDLE h;
54   struct ser_windows_state *state;
55   COMMTIMEOUTS timeouts;
56
57   /* Only allow COM ports.  */
58   if (strncmp (name, "COM", 3) != 0)
59     {
60       errno = ENOENT;
61       return -1;
62     }
63
64   h = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
65                   OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
66   if (h == INVALID_HANDLE_VALUE)
67     {
68       errno = ENOENT;
69       return -1;
70     }
71
72   scb->fd = _open_osfhandle ((long) h, O_RDWR);
73   if (scb->fd < 0)
74     {
75       errno = ENOENT;
76       return -1;
77     }
78
79   if (!SetCommMask (h, EV_RXCHAR))
80     {
81       errno = EINVAL;
82       return -1;
83     }
84
85   timeouts.ReadIntervalTimeout = MAXDWORD;
86   timeouts.ReadTotalTimeoutConstant = 0;
87   timeouts.ReadTotalTimeoutMultiplier = 0;
88   timeouts.WriteTotalTimeoutConstant = 0;
89   timeouts.WriteTotalTimeoutMultiplier = 0;
90   if (!SetCommTimeouts (h, &timeouts))
91     {
92       errno = EINVAL;
93       return -1;
94     }
95
96   state = xmalloc (sizeof (struct ser_windows_state));
97   memset (state, 0, sizeof (struct ser_windows_state));
98   scb->state = state;
99
100   /* Create a manual reset event to watch the input buffer.  */
101   state->ov.hEvent = CreateEvent (0, TRUE, FALSE, 0);
102
103   /* Create a (currently unused) handle to record exceptions.  */
104   state->except_event = CreateEvent (0, TRUE, FALSE, 0);
105
106   return 0;
107 }
108
109 /* Wait for the output to drain away, as opposed to flushing (discarding)
110    it.  */
111
112 static int
113 ser_windows_drain_output (struct serial *scb)
114 {
115   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
116
117   return (FlushFileBuffers (h) != 0) ? 0 : -1;
118 }
119
120 static int
121 ser_windows_flush_output (struct serial *scb)
122 {
123   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
124
125   return (PurgeComm (h, PURGE_TXCLEAR) != 0) ? 0 : -1;
126 }
127
128 static int
129 ser_windows_flush_input (struct serial *scb)
130 {
131   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
132
133   return (PurgeComm (h, PURGE_RXCLEAR) != 0) ? 0 : -1;
134 }
135
136 static int
137 ser_windows_send_break (struct serial *scb)
138 {
139   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
140
141   if (SetCommBreak (h) == 0)
142     return -1;
143
144   /* Delay for 250 milliseconds.  */
145   Sleep (250);
146
147   if (ClearCommBreak (h))
148     return -1;
149
150   return 0;
151 }
152
153 static void
154 ser_windows_raw (struct serial *scb)
155 {
156   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
157   DCB state;
158
159   if (GetCommState (h, &state) == 0)
160     return;
161
162   state.fParity = FALSE;
163   state.fOutxCtsFlow = FALSE;
164   state.fOutxDsrFlow = FALSE;
165   state.fDtrControl = DTR_CONTROL_ENABLE;
166   state.fDsrSensitivity = FALSE;
167   state.fOutX = FALSE;
168   state.fInX = FALSE;
169   state.fNull = FALSE;
170   state.fAbortOnError = FALSE;
171   state.ByteSize = 8;
172   state.Parity = NOPARITY;
173
174   scb->current_timeout = 0;
175
176   if (SetCommState (h, &state) == 0)
177     warning (_("SetCommState failed\n"));
178 }
179
180 static int
181 ser_windows_setstopbits (struct serial *scb, int num)
182 {
183   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
184   DCB state;
185
186   if (GetCommState (h, &state) == 0)
187     return -1;
188
189   switch (num)
190     {
191     case SERIAL_1_STOPBITS:
192       state.StopBits = ONESTOPBIT;
193       break;
194     case SERIAL_1_AND_A_HALF_STOPBITS:
195       state.StopBits = ONE5STOPBITS;
196       break;
197     case SERIAL_2_STOPBITS:
198       state.StopBits = TWOSTOPBITS;
199       break;
200     default:
201       return 1;
202     }
203
204   return (SetCommState (h, &state) != 0) ? 0 : -1;
205 }
206
207 static int
208 ser_windows_setbaudrate (struct serial *scb, int rate)
209 {
210   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
211   DCB state;
212
213   if (GetCommState (h, &state) == 0)
214     return -1;
215
216   state.BaudRate = rate;
217
218   return (SetCommState (h, &state) != 0) ? 0 : -1;
219 }
220
221 static void
222 ser_windows_close (struct serial *scb)
223 {
224   struct ser_windows_state *state;
225
226   /* Stop any pending selects.  */
227   CancelIo ((HANDLE) _get_osfhandle (scb->fd));
228   state = scb->state;
229   CloseHandle (state->ov.hEvent);
230   CloseHandle (state->except_event);
231
232   if (scb->fd < 0)
233     return;
234
235   close (scb->fd);
236   scb->fd = -1;
237
238   xfree (scb->state);
239 }
240
241 static void
242 ser_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
243 {
244   struct ser_windows_state *state;
245   COMSTAT status;
246   DWORD errors;
247   HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
248
249   state = scb->state;
250
251   *except = state->except_event;
252   *read = state->ov.hEvent;
253
254   if (state->in_progress)
255     return;
256
257   /* Reset the mask - we are only interested in any characters which
258      arrive after this point, not characters which might have arrived
259      and already been read.  */
260
261   /* This really, really shouldn't be necessary - just the second one.
262      But otherwise an internal flag for EV_RXCHAR does not get
263      cleared, and we get a duplicated event, if the last batch
264      of characters included at least two arriving close together.  */
265   if (!SetCommMask (h, 0))
266     warning (_("ser_windows_wait_handle: reseting mask failed"));
267
268   if (!SetCommMask (h, EV_RXCHAR))
269     warning (_("ser_windows_wait_handle: reseting mask failed (2)"));
270
271   /* There's a potential race condition here; we must check cbInQue
272      and not wait if that's nonzero.  */
273
274   ClearCommError (h, &errors, &status);
275   if (status.cbInQue > 0)
276     {
277       SetEvent (state->ov.hEvent);
278       return;
279     }
280
281   state->in_progress = 1;
282   ResetEvent (state->ov.hEvent);
283   state->lastCommMask = -2;
284   if (WaitCommEvent (h, &state->lastCommMask, &state->ov))
285     {
286       gdb_assert (state->lastCommMask & EV_RXCHAR);
287       SetEvent (state->ov.hEvent);
288     }
289   else
290     gdb_assert (GetLastError () == ERROR_IO_PENDING);
291 }
292
293 static int
294 ser_windows_read_prim (struct serial *scb, size_t count)
295 {
296   struct ser_windows_state *state;
297   OVERLAPPED ov;
298   DWORD bytes_read, bytes_read_tmp;
299   HANDLE h;
300   gdb_byte *p;
301
302   state = scb->state;
303   if (state->in_progress)
304     {
305       WaitForSingleObject (state->ov.hEvent, INFINITE);
306       state->in_progress = 0;
307       ResetEvent (state->ov.hEvent);
308     }
309
310   memset (&ov, 0, sizeof (OVERLAPPED));
311   ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
312   h = (HANDLE) _get_osfhandle (scb->fd);
313
314   if (!ReadFile (h, scb->buf, /* count */ 1, &bytes_read, &ov))
315     {
316       if (GetLastError () != ERROR_IO_PENDING
317           || !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
318         bytes_read = -1;
319     }
320
321   CloseHandle (ov.hEvent);
322   return bytes_read;
323 }
324
325 static int
326 ser_windows_write_prim (struct serial *scb, const void *buf, size_t len)
327 {
328   struct ser_windows_state *state;
329   OVERLAPPED ov;
330   DWORD bytes_written;
331   HANDLE h;
332
333   memset (&ov, 0, sizeof (OVERLAPPED));
334   ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
335   h = (HANDLE) _get_osfhandle (scb->fd);
336   if (!WriteFile (h, buf, len, &bytes_written, &ov))
337     {
338       if (GetLastError () != ERROR_IO_PENDING
339           || !GetOverlappedResult (h, &ov, &bytes_written, TRUE))
340         bytes_written = -1;
341     }
342
343   CloseHandle (ov.hEvent);
344   return bytes_written;
345 }
346
347 struct ser_console_state
348 {
349   HANDLE read_event;
350   HANDLE except_event;
351
352   HANDLE start_select;
353   HANDLE stop_select;
354   HANDLE exit_select;
355   HANDLE have_stopped;
356
357   HANDLE thread;
358 };
359
360 static DWORD WINAPI
361 console_select_thread (void *arg)
362 {
363   struct serial *scb = arg;
364   struct ser_console_state *state;
365   int event_index;
366   HANDLE h;
367
368   state = scb->state;
369   h = (HANDLE) _get_osfhandle (scb->fd);
370
371   while (1)
372     {
373       HANDLE wait_events[2];
374       INPUT_RECORD record;
375       DWORD n_records;
376
377       SetEvent (state->have_stopped);
378
379       wait_events[0] = state->start_select;
380       wait_events[1] = state->exit_select;
381
382       if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
383         return 0;
384
385       ResetEvent (state->have_stopped);
386
387     retry:
388       wait_events[0] = state->stop_select;
389       wait_events[1] = h;
390
391       event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
392
393       if (event_index == WAIT_OBJECT_0
394           || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
395         continue;
396
397       if (event_index != WAIT_OBJECT_0 + 1)
398         {
399           /* Wait must have failed; assume an error has occured, e.g.
400              the handle has been closed.  */
401           SetEvent (state->except_event);
402           continue;
403         }
404
405       /* We've got a pending event on the console.  See if it's
406          of interest.  */
407       if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1)
408         {
409           /* Something went wrong.  Maybe the console is gone.  */
410           SetEvent (state->except_event);
411           continue;
412         }
413
414       if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
415         {
416           WORD keycode = record.Event.KeyEvent.wVirtualKeyCode;
417
418           /* Ignore events containing only control keys.  We must
419              recognize "enhanced" keys which we are interested in
420              reading via getch, if they do not map to ASCII.  But we
421              do not want to report input available for e.g. the
422              control key alone.  */
423
424           if (record.Event.KeyEvent.uChar.AsciiChar != 0
425               || keycode == VK_PRIOR
426               || keycode == VK_NEXT
427               || keycode == VK_END
428               || keycode == VK_HOME
429               || keycode == VK_LEFT
430               || keycode == VK_UP
431               || keycode == VK_RIGHT
432               || keycode == VK_DOWN
433               || keycode == VK_INSERT
434               || keycode == VK_DELETE)
435             {
436               /* This is really a keypress.  */
437               SetEvent (state->read_event);
438               continue;
439             }
440         }
441
442       /* Otherwise discard it and wait again.  */
443       ReadConsoleInput (h, &record, 1, &n_records);
444       goto retry;
445     }
446 }
447
448 static int
449 fd_is_pipe (int fd)
450 {
451   if (PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, NULL, NULL))
452     return 1;
453   else
454     return 0;
455 }
456
457 static DWORD WINAPI
458 pipe_select_thread (void *arg)
459 {
460   struct serial *scb = arg;
461   struct ser_console_state *state;
462   int event_index;
463   HANDLE h;
464
465   state = scb->state;
466   h = (HANDLE) _get_osfhandle (scb->fd);
467
468   while (1)
469     {
470       HANDLE wait_events[2];
471       DWORD n_avail;
472
473       SetEvent (state->have_stopped);
474
475       wait_events[0] = state->start_select;
476       wait_events[1] = state->exit_select;
477
478       if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
479         return 0;
480
481       ResetEvent (state->have_stopped);
482
483     retry:
484       if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
485         {
486           SetEvent (state->except_event);
487           continue;
488         }
489
490       if (n_avail > 0)
491         {
492           SetEvent (state->read_event);
493           continue;
494         }
495
496       /* Delay 10ms before checking again, but allow the stop event
497          to wake us.  */
498       if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0)
499         continue;
500
501       goto retry;
502     }
503 }
504
505 static void
506 ser_console_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
507 {
508   struct ser_console_state *state = scb->state;
509
510   if (state == NULL)
511     {
512       DWORD threadId;
513       int is_tty;
514
515       is_tty = isatty (scb->fd);
516       if (!is_tty && !fd_is_pipe (scb->fd))
517         {
518           *read = NULL;
519           *except = NULL;
520           return;
521         }
522
523       state = xmalloc (sizeof (struct ser_console_state));
524       memset (state, 0, sizeof (struct ser_console_state));
525       scb->state = state;
526
527       /* Create auto reset events to wake, stop, and exit the select
528          thread.  */
529       state->start_select = CreateEvent (0, FALSE, FALSE, 0);
530       state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
531       state->exit_select = CreateEvent (0, FALSE, FALSE, 0);
532
533       /* Create a manual reset event to signal whether the thread is
534          stopped.  This must be manual reset, because we may wait on
535          it multiple times without ever starting the thread.  */
536       state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);
537
538       /* Create our own events to report read and exceptions separately.  */
539       state->read_event = CreateEvent (0, FALSE, FALSE, 0);
540       state->except_event = CreateEvent (0, FALSE, FALSE, 0);
541
542       if (is_tty)
543         state->thread = CreateThread (NULL, 0, console_select_thread, scb, 0,
544                                       &threadId);
545       else
546         state->thread = CreateThread (NULL, 0, pipe_select_thread, scb, 0,
547                                       &threadId);
548     }
549
550   *read = state->read_event;
551   *except = state->except_event;
552
553   /* Start from a blank state.  */
554   ResetEvent (state->read_event);
555   ResetEvent (state->except_event);
556   ResetEvent (state->stop_select);
557
558   /* First check for a key already in the buffer.  If there is one,
559      we don't need a thread.  This also catches the second key of
560      multi-character returns from getch, for instance for arrow
561      keys.  The second half is in a C library internal buffer,
562      and PeekConsoleInput will not find it.  */
563   if (_kbhit ())
564     {
565       SetEvent (state->read_event);
566       return;
567     }
568
569   /* Otherwise, start the select thread.  */
570   SetEvent (state->start_select);
571 }
572
573 static void
574 ser_console_done_wait_handle (struct serial *scb)
575 {
576   struct ser_console_state *state = scb->state;
577
578   if (state == NULL)
579     return;
580
581   SetEvent (state->stop_select);
582   WaitForSingleObject (state->have_stopped, INFINITE);
583 }
584
585 static void
586 ser_console_close (struct serial *scb)
587 {
588   struct ser_console_state *state = scb->state;
589
590   if (scb->state)
591     {
592       SetEvent (state->exit_select);
593
594       WaitForSingleObject (state->thread, INFINITE);
595
596       CloseHandle (state->start_select);
597       CloseHandle (state->stop_select);
598       CloseHandle (state->exit_select);
599       CloseHandle (state->have_stopped);
600
601       CloseHandle (state->read_event);
602       CloseHandle (state->except_event);
603
604       xfree (scb->state);
605     }
606 }
607
608 struct ser_console_ttystate
609 {
610   int is_a_tty;
611 };
612
613 static serial_ttystate
614 ser_console_get_tty_state (struct serial *scb)
615 {
616   if (isatty (scb->fd))
617     {
618       struct ser_console_ttystate *state;
619       state = (struct ser_console_ttystate *) xmalloc (sizeof *state);
620       state->is_a_tty = 1;
621       return state;
622     }
623   else
624     return NULL;
625 }
626
627 struct net_windows_state
628 {
629   HANDLE read_event;
630   HANDLE except_event;
631
632   HANDLE start_select;
633   HANDLE stop_select;
634   HANDLE exit_select;
635   HANDLE have_stopped;
636
637   HANDLE sock_event;
638
639   HANDLE thread;
640 };
641
642 static DWORD WINAPI
643 net_windows_select_thread (void *arg)
644 {
645   struct serial *scb = arg;
646   struct net_windows_state *state, state_copy;
647   int event_index;
648
649   state = scb->state;
650
651   while (1)
652     {
653       HANDLE wait_events[2];
654       WSANETWORKEVENTS events;
655
656       SetEvent (state->have_stopped);
657
658       wait_events[0] = state->start_select;
659       wait_events[1] = state->exit_select;
660
661       if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
662         return 0;
663
664       ResetEvent (state->have_stopped);
665
666       wait_events[0] = state->stop_select;
667       wait_events[1] = state->sock_event;
668
669       event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
670
671       if (event_index == WAIT_OBJECT_0
672           || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
673         continue;
674
675       if (event_index != WAIT_OBJECT_0 + 1)
676         {
677           /* Some error has occured.  Assume that this is an error
678              condition.  */
679           SetEvent (state->except_event);
680           continue;
681         }
682
683       /* Enumerate the internal network events, and reset the object that
684          signalled us to catch the next event.  */
685       WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
686
687       gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE));
688
689       if (events.lNetworkEvents & FD_READ)
690         SetEvent (state->read_event);
691
692       if (events.lNetworkEvents & FD_CLOSE)
693         SetEvent (state->except_event);
694     }
695 }
696
697 static void
698 net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
699 {
700   struct net_windows_state *state = scb->state;
701
702   /* Start from a clean slate.  */
703   ResetEvent (state->read_event);
704   ResetEvent (state->except_event);
705   ResetEvent (state->stop_select);
706
707   *read = state->read_event;
708   *except = state->except_event;
709
710   /* Check any pending events.  This both avoids starting the thread
711      unnecessarily, and handles stray FD_READ events (see below).  */
712   if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0)
713     {
714       WSANETWORKEVENTS events;
715       int any = 0;
716
717       /* Enumerate the internal network events, and reset the object that
718          signalled us to catch the next event.  */
719       WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
720
721       /* You'd think that FD_READ or FD_CLOSE would be set here.  But,
722          sometimes, neither is.  I suspect that the FD_READ is set and
723          the corresponding event signalled while recv is running, and
724          the FD_READ is then lowered when recv consumes all the data,
725          but there's no way to un-signal the event.  This isn't a
726          problem for the call in net_select_thread, since any new
727          events after this point will not have been drained by recv.
728          It just means that we can't have the obvious assert here.  */
729
730       /* If there is a read event, it might be still valid, or it might
731          not be - it may have been signalled before we last called
732          recv.  Double-check that there is data.  */
733       if (events.lNetworkEvents & FD_READ)
734         {
735           unsigned long available;
736
737           if (ioctlsocket (scb->fd, FIONREAD, &available) == 0
738               && available > 0)
739             {
740               SetEvent (state->read_event);
741               any = 1;
742             }
743           else
744             /* Oops, no data.  This call to recv will cause future
745                data to retrigger the event, e.g. while we are
746                in net_select_thread.  */
747             recv (scb->fd, NULL, 0, 0);
748         }
749
750       /* If there's a close event, then record it - it is obviously
751          still valid, and it will not be resignalled.  */
752       if (events.lNetworkEvents & FD_CLOSE)
753         {
754           SetEvent (state->except_event);
755           any = 1;
756         }
757
758       /* If we set either handle, there's no need to wake the thread.  */
759       if (any)
760         return;
761     }
762
763   /* Start the select thread.  */
764   SetEvent (state->start_select);
765 }
766
767 static void
768 net_windows_done_wait_handle (struct serial *scb)
769 {
770   struct net_windows_state *state = scb->state;
771
772   SetEvent (state->stop_select);
773   WaitForSingleObject (state->have_stopped, INFINITE);
774 }
775
776 static int
777 net_windows_open (struct serial *scb, const char *name)
778 {
779   struct net_windows_state *state;
780   int ret;
781   DWORD threadId;
782
783   ret = net_open (scb, name);
784   if (ret != 0)
785     return ret;
786
787   state = xmalloc (sizeof (struct net_windows_state));
788   memset (state, 0, sizeof (struct net_windows_state));
789   scb->state = state;
790
791   /* Create auto reset events to wake, stop, and exit the select
792      thread.  */
793   state->start_select = CreateEvent (0, FALSE, FALSE, 0);
794   state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
795   state->exit_select = CreateEvent (0, FALSE, FALSE, 0);
796
797   /* Create a manual reset event to signal whether the thread is
798      stopped.  This must be manual reset, because we may wait on
799      it multiple times without ever starting the thread.  */
800   state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);
801
802   /* Associate an event with the socket.  */
803   state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
804   WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);
805
806   /* Create our own events to report read and close separately.  */
807   state->read_event = CreateEvent (0, FALSE, FALSE, 0);
808   state->except_event = CreateEvent (0, FALSE, FALSE, 0);
809
810   /* And finally start the select thread.  */
811   state->thread = CreateThread (NULL, 0, net_windows_select_thread, scb, 0,
812                                 &threadId);
813
814   return 0;
815 }
816
817
818 static void
819 net_windows_close (struct serial *scb)
820 {
821   struct net_windows_state *state = scb->state;
822
823   SetEvent (state->exit_select);
824   WaitForSingleObject (state->thread, INFINITE);
825
826   CloseHandle (state->read_event);
827   CloseHandle (state->except_event);
828
829   CloseHandle (state->start_select);
830   CloseHandle (state->stop_select);
831   CloseHandle (state->exit_select);
832   CloseHandle (state->have_stopped);
833
834   CloseHandle (state->sock_event);
835
836   xfree (scb->state);
837
838   net_close (scb);
839 }
840
841 void
842 _initialize_ser_windows (void)
843 {
844   WSADATA wsa_data;
845   struct serial_ops *ops;
846
847   /* First register the serial port driver.  */
848
849   ops = XMALLOC (struct serial_ops);
850   memset (ops, 0, sizeof (struct serial_ops));
851   ops->name = "hardwire";
852   ops->next = 0;
853   ops->open = ser_windows_open;
854   ops->close = ser_windows_close;
855
856   ops->flush_output = ser_windows_flush_output;
857   ops->flush_input = ser_windows_flush_input;
858   ops->send_break = ser_windows_send_break;
859
860   /* These are only used for stdin; we do not need them for serial
861      ports, so supply the standard dummies.  */
862   ops->get_tty_state = ser_base_get_tty_state;
863   ops->set_tty_state = ser_base_set_tty_state;
864   ops->print_tty_state = ser_base_print_tty_state;
865   ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
866
867   ops->go_raw = ser_windows_raw;
868   ops->setbaudrate = ser_windows_setbaudrate;
869   ops->setstopbits = ser_windows_setstopbits;
870   ops->drain_output = ser_windows_drain_output;
871   ops->readchar = ser_base_readchar;
872   ops->write = ser_base_write;
873   ops->async = ser_base_async;
874   ops->read_prim = ser_windows_read_prim;
875   ops->write_prim = ser_windows_write_prim;
876   ops->wait_handle = ser_windows_wait_handle;
877
878   serial_add_interface (ops);
879
880   /* Next create the dummy serial driver used for terminals.  We only
881      provide the TTY-related methods.  */
882
883   ops = XMALLOC (struct serial_ops);
884   memset (ops, 0, sizeof (struct serial_ops));
885
886   ops->name = "terminal";
887   ops->next = 0;
888
889   ops->close = ser_console_close;
890   ops->get_tty_state = ser_console_get_tty_state;
891   ops->set_tty_state = ser_base_set_tty_state;
892   ops->print_tty_state = ser_base_print_tty_state;
893   ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
894   ops->drain_output = ser_base_drain_output;
895   ops->wait_handle = ser_console_wait_handle;
896   ops->done_wait_handle = ser_console_done_wait_handle;
897
898   serial_add_interface (ops);
899
900   /* If WinSock works, register the TCP/UDP socket driver.  */
901
902   if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
903     /* WinSock is unavailable.  */
904     return;
905
906   ops = XMALLOC (struct serial_ops);
907   memset (ops, 0, sizeof (struct serial_ops));
908   ops->name = "tcp";
909   ops->next = 0;
910   ops->open = net_windows_open;
911   ops->close = net_windows_close;
912   ops->readchar = ser_base_readchar;
913   ops->write = ser_base_write;
914   ops->flush_output = ser_base_flush_output;
915   ops->flush_input = ser_base_flush_input;
916   ops->send_break = ser_base_send_break;
917   ops->go_raw = ser_base_raw;
918   ops->get_tty_state = ser_base_get_tty_state;
919   ops->set_tty_state = ser_base_set_tty_state;
920   ops->print_tty_state = ser_base_print_tty_state;
921   ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
922   ops->setbaudrate = ser_base_setbaudrate;
923   ops->setstopbits = ser_base_setstopbits;
924   ops->drain_output = ser_base_drain_output;
925   ops->async = ser_base_async;
926   ops->read_prim = net_read_prim;
927   ops->write_prim = net_write_prim;
928   ops->wait_handle = net_windows_wait_handle;
929   ops->done_wait_handle = net_windows_done_wait_handle;
930   serial_add_interface (ops);
931 }