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