]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ser-mingw.c
Switch the license of all .c files to GPLv3.
[thirdparty/binutils-gdb.git] / gdb / ser-mingw.c
CommitLineData
0ea3f30e
DJ
1/* Serial interface for local (hardwired) serial ports on Windows systems
2
6aba47ca 3 Copyright (C) 2006, 2007 Free Software Foundation, Inc.
0ea3f30e
DJ
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
0ea3f30e
DJ
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0ea3f30e
DJ
19
20#include "defs.h"
21#include "serial.h"
22#include "ser-base.h"
23#include "ser-tcp.h"
24
25#include <windows.h>
c3e2b812 26#include <conio.h>
0ea3f30e
DJ
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
35void _initialize_ser_windows (void);
36
37struct 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
47static int
48ser_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
109static int
110ser_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
117static int
118ser_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
125static int
126ser_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
133static int
134ser_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
150static void
151ser_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
177static int
178ser_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
204static int
205ser_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
218static void
219ser_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
238static void
239ser_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
290static int
291ser_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
322static int
323ser_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
344struct ser_console_state
345{
346 HANDLE read_event;
347 HANDLE except_event;
348
349 HANDLE start_select;
350 HANDLE stop_select;
c3e2b812
DJ
351 HANDLE exit_select;
352 HANDLE have_stopped;
353
354 HANDLE thread;
0ea3f30e
DJ
355};
356
357static DWORD WINAPI
358console_select_thread (void *arg)
359{
360 struct serial *scb = arg;
c3e2b812
DJ
361 struct ser_console_state *state;
362 int event_index;
0ea3f30e
DJ
363 HANDLE h;
364
c3e2b812
DJ
365 state = scb->state;
366 h = (HANDLE) _get_osfhandle (scb->fd);
0ea3f30e
DJ
367
368 while (1)
369 {
370 HANDLE wait_events[2];
371 INPUT_RECORD record;
372 DWORD n_records;
373
c3e2b812
DJ
374 SetEvent (state->have_stopped);
375
0ea3f30e 376 wait_events[0] = state->start_select;
c3e2b812 377 wait_events[1] = state->exit_select;
0ea3f30e
DJ
378
379 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
c3e2b812
DJ
380 return 0;
381
382 ResetEvent (state->have_stopped);
0ea3f30e
DJ
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)
c3e2b812 392 continue;
0ea3f30e
DJ
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 {
c3e2b812
DJ
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 }
0ea3f30e
DJ
437 }
438
439 /* Otherwise discard it and wait again. */
440 ReadConsoleInput (h, &record, 1, &n_records);
441 goto retry;
442 }
443}
444
445static int
446fd_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
7e71daaa
JG
454static int
455fd_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
0ea3f30e
DJ
463static DWORD WINAPI
464pipe_select_thread (void *arg)
465{
466 struct serial *scb = arg;
c3e2b812
DJ
467 struct ser_console_state *state;
468 int event_index;
0ea3f30e
DJ
469 HANDLE h;
470
c3e2b812
DJ
471 state = scb->state;
472 h = (HANDLE) _get_osfhandle (scb->fd);
0ea3f30e
DJ
473
474 while (1)
475 {
476 HANDLE wait_events[2];
477 DWORD n_avail;
478
c3e2b812
DJ
479 SetEvent (state->have_stopped);
480
0ea3f30e 481 wait_events[0] = state->start_select;
c3e2b812 482 wait_events[1] = state->exit_select;
0ea3f30e
DJ
483
484 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
c3e2b812
DJ
485 return 0;
486
487 ResetEvent (state->have_stopped);
0ea3f30e
DJ
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
c3e2b812
DJ
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;
0ea3f30e 506
0ea3f30e
DJ
507 goto retry;
508 }
509}
510
7e71daaa
JG
511static DWORD WINAPI
512file_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
0ea3f30e
DJ
547static void
548ser_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);
7e71daaa 558 if (!is_tty && !fd_is_file (scb->fd) && !fd_is_pipe (scb->fd))
0ea3f30e
DJ
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
c3e2b812
DJ
569 /* Create auto reset events to wake, stop, and exit the select
570 thread. */
0ea3f30e
DJ
571 state->start_select = CreateEvent (0, FALSE, FALSE, 0);
572 state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
c3e2b812 573 state->exit_select = CreateEvent (0, FALSE, FALSE, 0);
0ea3f30e 574
c3e2b812
DJ
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. */
0ea3f30e
DJ
581 state->read_event = CreateEvent (0, FALSE, FALSE, 0);
582 state->except_event = CreateEvent (0, FALSE, FALSE, 0);
583
0ea3f30e 584 if (is_tty)
c3e2b812
DJ
585 state->thread = CreateThread (NULL, 0, console_select_thread, scb, 0,
586 &threadId);
7e71daaa 587 else if (fd_is_pipe (scb->fd))
c3e2b812
DJ
588 state->thread = CreateThread (NULL, 0, pipe_select_thread, scb, 0,
589 &threadId);
7e71daaa
JG
590 else
591 state->thread = CreateThread (NULL, 0, file_select_thread, scb, 0,
592 &threadId);
0ea3f30e
DJ
593 }
594
c3e2b812
DJ
595 *read = state->read_event;
596 *except = state->except_event;
597
598 /* Start from a blank state. */
0ea3f30e
DJ
599 ResetEvent (state->read_event);
600 ResetEvent (state->except_event);
c3e2b812
DJ
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 }
0ea3f30e 613
c3e2b812 614 /* Otherwise, start the select thread. */
0ea3f30e 615 SetEvent (state->start_select);
c3e2b812 616}
0ea3f30e 617
c3e2b812
DJ
618static void
619ser_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);
0ea3f30e
DJ
628}
629
630static void
631ser_console_close (struct serial *scb)
632{
633 struct ser_console_state *state = scb->state;
634
635 if (scb->state)
636 {
c3e2b812
DJ
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);
0ea3f30e
DJ
645
646 CloseHandle (state->read_event);
647 CloseHandle (state->except_event);
648
649 xfree (scb->state);
650 }
651}
652
653struct ser_console_ttystate
654{
655 int is_a_tty;
656};
657
658static serial_ttystate
659ser_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
5f1fb6dc
JB
672struct 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
686static struct pipe_state *
687make_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
700static void
701free_pipe_state (struct pipe_state *ps)
702{
703 int saved_errno = errno;
704
705 if (ps->wait.read_event != INVALID_HANDLE_VALUE)
774a49c0
DJ
706 {
707 SetEvent (ps->wait.exit_select);
708
709 WaitForSingleObject (ps->wait.thread, INFINITE);
5f1fb6dc 710
774a49c0
DJ
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 }
5f1fb6dc
JB
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
734static void
735cleanup_pipe_state (void *untyped)
736{
737 struct pipe_state *ps = untyped;
738
739 free_pipe_state (ps);
740}
741
742static int
743pipe_windows_open (struct serial *scb, const char *name)
744{
ef7723eb 745 struct pipe_state *ps;
65cc4390 746 FILE *pex_stderr;
ef7723eb 747
5f1fb6dc
JB
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
ef7723eb
VP
753
754 ps = make_pipe_state ();
5f1fb6dc
JB
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
65cc4390
VP
767 = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
768 | PEX_STDERR_TO_PIPE,
5f1fb6dc
JB
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;
5f1fb6dc 790 scb->fd = fileno (ps->output);
65cc4390
VP
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
5f1fb6dc
JB
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
808static void
809pipe_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
821static int
822pipe_windows_read (struct serial *scb, size_t count)
823{
4998c1df 824 HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
ef7723eb
VP
825 DWORD available;
826 DWORD bytes_read;
827
5f1fb6dc
JB
828 if (pipeline_out == INVALID_HANDLE_VALUE)
829 return -1;
830
5f1fb6dc
JB
831 if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
832 return -1;
833
834 if (count > available)
835 count = available;
836
5f1fb6dc
JB
837 if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
838 return -1;
839
840 return bytes_read;
841}
842
843
844static int
845pipe_windows_write (struct serial *scb, const void *buf, size_t count)
846{
847 struct pipe_state *ps = scb->state;
ef7723eb
VP
848 HANDLE pipeline_in;
849 DWORD written;
850
5f1fb6dc
JB
851 int pipeline_in_fd = fileno (ps->input);
852 if (pipeline_in_fd < 0)
853 return -1;
854
ef7723eb 855 pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
5f1fb6dc
JB
856 if (pipeline_in == INVALID_HANDLE_VALUE)
857 return -1;
858
5f1fb6dc
JB
859 if (! WriteFile (pipeline_in, buf, count, &written, NULL))
860 return -1;
861
862 return written;
863}
864
865
866static void
867pipe_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
774a49c0
DJ
876 /* Create auto reset events to wake, stop, and exit the select
877 thread. */
5f1fb6dc
JB
878 ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0);
879 ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0);
774a49c0
DJ
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);
5f1fb6dc
JB
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
774a49c0
DJ
896 *read = ps->wait.read_event;
897 *except = ps->wait.except_event;
898
899 /* Start from a blank state. */
5f1fb6dc
JB
900 ResetEvent (ps->wait.read_event);
901 ResetEvent (ps->wait.except_event);
774a49c0 902 ResetEvent (ps->wait.stop_select);
5f1fb6dc 903
774a49c0 904 /* Start the select thread. */
5f1fb6dc 905 SetEvent (ps->wait.start_select);
5f1fb6dc
JB
906}
907
774a49c0
DJ
908static void
909pipe_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}
5f1fb6dc 920
65cc4390
VP
921static int
922pipe_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
0ea3f30e
DJ
932struct net_windows_state
933{
934 HANDLE read_event;
935 HANDLE except_event;
936
937 HANDLE start_select;
938 HANDLE stop_select;
c3e2b812
DJ
939 HANDLE exit_select;
940 HANDLE have_stopped;
941
0ea3f30e 942 HANDLE sock_event;
c3e2b812
DJ
943
944 HANDLE thread;
0ea3f30e
DJ
945};
946
947static DWORD WINAPI
948net_windows_select_thread (void *arg)
949{
950 struct serial *scb = arg;
951 struct net_windows_state *state, state_copy;
c3e2b812 952 int event_index;
0ea3f30e 953
c3e2b812 954 state = scb->state;
0ea3f30e
DJ
955
956 while (1)
957 {
958 HANDLE wait_events[2];
959 WSANETWORKEVENTS events;
960
c3e2b812
DJ
961 SetEvent (state->have_stopped);
962
0ea3f30e 963 wait_events[0] = state->start_select;
c3e2b812 964 wait_events[1] = state->exit_select;
0ea3f30e
DJ
965
966 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
c3e2b812
DJ
967 return 0;
968
969 ResetEvent (state->have_stopped);
0ea3f30e
DJ
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)
c3e2b812 978 continue;
0ea3f30e
DJ
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. */
c3e2b812
DJ
990 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
991
992 gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE));
0ea3f30e
DJ
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
1002static void
1003net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
1004{
1005 struct net_windows_state *state = scb->state;
1006
c3e2b812 1007 /* Start from a clean slate. */
0ea3f30e
DJ
1008 ResetEvent (state->read_event);
1009 ResetEvent (state->except_event);
c3e2b812 1010 ResetEvent (state->stop_select);
0ea3f30e
DJ
1011
1012 *read = state->read_event;
1013 *except = state->except_event;
c3e2b812
DJ
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
1072static void
1073net_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);
0ea3f30e
DJ
1079}
1080
1081static int
1082net_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
c3e2b812
DJ
1096 /* Create auto reset events to wake, stop, and exit the select
1097 thread. */
0ea3f30e
DJ
1098 state->start_select = CreateEvent (0, FALSE, FALSE, 0);
1099 state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
c3e2b812
DJ
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);
0ea3f30e
DJ
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. */
c3e2b812
DJ
1116 state->thread = CreateThread (NULL, 0, net_windows_select_thread, scb, 0,
1117 &threadId);
0ea3f30e
DJ
1118
1119 return 0;
1120}
1121
1122
1123static void
1124net_windows_close (struct serial *scb)
1125{
1126 struct net_windows_state *state = scb->state;
1127
c3e2b812
DJ
1128 SetEvent (state->exit_select);
1129 WaitForSingleObject (state->thread, INFINITE);
0ea3f30e
DJ
1130
1131 CloseHandle (state->read_event);
1132 CloseHandle (state->except_event);
c3e2b812 1133
0ea3f30e 1134 CloseHandle (state->start_select);
c3e2b812
DJ
1135 CloseHandle (state->stop_select);
1136 CloseHandle (state->exit_select);
1137 CloseHandle (state->have_stopped);
1138
0ea3f30e
DJ
1139 CloseHandle (state->sock_event);
1140
1141 xfree (scb->state);
1142
1143 net_close (scb);
1144}
1145
1146void
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;
c3e2b812 1201 ops->done_wait_handle = ser_console_done_wait_handle;
0ea3f30e
DJ
1202
1203 serial_add_interface (ops);
1204
5f1fb6dc
JB
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;
774a49c0 1230 ops->done_wait_handle = pipe_done_wait_handle;
65cc4390 1231 ops->avail = pipe_avail;
5f1fb6dc
JB
1232
1233 serial_add_interface (ops);
1234
0ea3f30e
DJ
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;
c3e2b812 1264 ops->done_wait_handle = net_windows_done_wait_handle;
0ea3f30e
DJ
1265 serial_add_interface (ops);
1266}