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