* config/xtensa-relax.c (widen_spec_list): Use new "WIDE.<opcode>"
[deliverable/binutils-gdb.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 }
This page took 0.049393 seconds and 4 git commands to generate.