* configure.ac: Switch license to GPLv3.
[deliverable/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
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>
c3e2b812 28#include <conio.h>
0ea3f30e
DJ
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
37void _initialize_ser_windows (void);
38
39struct 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
49static int
50ser_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
111static int
112ser_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
119static int
120ser_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
127static int
128ser_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
135static int
136ser_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
152static void
153ser_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
179static int
180ser_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
206static int
207ser_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
220static void
221ser_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
240static void
241ser_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
292static int
293ser_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
324static int
325ser_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
346struct ser_console_state
347{
348 HANDLE read_event;
349 HANDLE except_event;
350
351 HANDLE start_select;
352 HANDLE stop_select;
c3e2b812
DJ
353 HANDLE exit_select;
354 HANDLE have_stopped;
355
356 HANDLE thread;
0ea3f30e
DJ
357};
358
359static DWORD WINAPI
360console_select_thread (void *arg)
361{
362 struct serial *scb = arg;
c3e2b812
DJ
363 struct ser_console_state *state;
364 int event_index;
0ea3f30e
DJ
365 HANDLE h;
366
c3e2b812
DJ
367 state = scb->state;
368 h = (HANDLE) _get_osfhandle (scb->fd);
0ea3f30e
DJ
369
370 while (1)
371 {
372 HANDLE wait_events[2];
373 INPUT_RECORD record;
374 DWORD n_records;
375
c3e2b812
DJ
376 SetEvent (state->have_stopped);
377
0ea3f30e 378 wait_events[0] = state->start_select;
c3e2b812 379 wait_events[1] = state->exit_select;
0ea3f30e
DJ
380
381 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
c3e2b812
DJ
382 return 0;
383
384 ResetEvent (state->have_stopped);
0ea3f30e
DJ
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)
c3e2b812 394 continue;
0ea3f30e
DJ
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 {
c3e2b812
DJ
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 }
0ea3f30e
DJ
439 }
440
441 /* Otherwise discard it and wait again. */
442 ReadConsoleInput (h, &record, 1, &n_records);
443 goto retry;
444 }
445}
446
447static int
448fd_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
7e71daaa
JG
456static int
457fd_is_file (int fd)
458{
459 if (GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_DISK)
460 return 1;
461 else
462 return 0;
463}
464
0ea3f30e
DJ
465static DWORD WINAPI
466pipe_select_thread (void *arg)
467{
468 struct serial *scb = arg;
c3e2b812
DJ
469 struct ser_console_state *state;
470 int event_index;
0ea3f30e
DJ
471 HANDLE h;
472
c3e2b812
DJ
473 state = scb->state;
474 h = (HANDLE) _get_osfhandle (scb->fd);
0ea3f30e
DJ
475
476 while (1)
477 {
478 HANDLE wait_events[2];
479 DWORD n_avail;
480
c3e2b812
DJ
481 SetEvent (state->have_stopped);
482
0ea3f30e 483 wait_events[0] = state->start_select;
c3e2b812 484 wait_events[1] = state->exit_select;
0ea3f30e
DJ
485
486 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
c3e2b812
DJ
487 return 0;
488
489 ResetEvent (state->have_stopped);
0ea3f30e
DJ
490
491 retry:
492 if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
493 {
494 SetEvent (state->except_event);
495 continue;
496 }
497
498 if (n_avail > 0)
499 {
500 SetEvent (state->read_event);
501 continue;
502 }
503
c3e2b812
DJ
504 /* Delay 10ms before checking again, but allow the stop event
505 to wake us. */
506 if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0)
507 continue;
0ea3f30e 508
0ea3f30e
DJ
509 goto retry;
510 }
511}
512
7e71daaa
JG
513static DWORD WINAPI
514file_select_thread (void *arg)
515{
516 struct serial *scb = arg;
517 struct ser_console_state *state;
518 int event_index;
519 HANDLE h;
520
521 state = scb->state;
522 h = (HANDLE) _get_osfhandle (scb->fd);
523
524 while (1)
525 {
526 HANDLE wait_events[2];
527 DWORD n_avail;
528
529 SetEvent (state->have_stopped);
530
531 wait_events[0] = state->start_select;
532 wait_events[1] = state->exit_select;
533
534 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
535 return 0;
536
537 ResetEvent (state->have_stopped);
538
539 if (SetFilePointer (h, 0, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
540 {
541 SetEvent (state->except_event);
542 continue;
543 }
544
545 SetEvent (state->read_event);
546 }
547}
548
0ea3f30e
DJ
549static void
550ser_console_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
551{
552 struct ser_console_state *state = scb->state;
553
554 if (state == NULL)
555 {
556 DWORD threadId;
557 int is_tty;
558
559 is_tty = isatty (scb->fd);
7e71daaa 560 if (!is_tty && !fd_is_file (scb->fd) && !fd_is_pipe (scb->fd))
0ea3f30e
DJ
561 {
562 *read = NULL;
563 *except = NULL;
564 return;
565 }
566
567 state = xmalloc (sizeof (struct ser_console_state));
568 memset (state, 0, sizeof (struct ser_console_state));
569 scb->state = state;
570
c3e2b812
DJ
571 /* Create auto reset events to wake, stop, and exit the select
572 thread. */
0ea3f30e
DJ
573 state->start_select = CreateEvent (0, FALSE, FALSE, 0);
574 state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
c3e2b812 575 state->exit_select = CreateEvent (0, FALSE, FALSE, 0);
0ea3f30e 576
c3e2b812
DJ
577 /* Create a manual reset event to signal whether the thread is
578 stopped. This must be manual reset, because we may wait on
579 it multiple times without ever starting the thread. */
580 state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);
581
582 /* Create our own events to report read and exceptions separately. */
0ea3f30e
DJ
583 state->read_event = CreateEvent (0, FALSE, FALSE, 0);
584 state->except_event = CreateEvent (0, FALSE, FALSE, 0);
585
0ea3f30e 586 if (is_tty)
c3e2b812
DJ
587 state->thread = CreateThread (NULL, 0, console_select_thread, scb, 0,
588 &threadId);
7e71daaa 589 else if (fd_is_pipe (scb->fd))
c3e2b812
DJ
590 state->thread = CreateThread (NULL, 0, pipe_select_thread, scb, 0,
591 &threadId);
7e71daaa
JG
592 else
593 state->thread = CreateThread (NULL, 0, file_select_thread, scb, 0,
594 &threadId);
0ea3f30e
DJ
595 }
596
c3e2b812
DJ
597 *read = state->read_event;
598 *except = state->except_event;
599
600 /* Start from a blank state. */
0ea3f30e
DJ
601 ResetEvent (state->read_event);
602 ResetEvent (state->except_event);
c3e2b812
DJ
603 ResetEvent (state->stop_select);
604
605 /* First check for a key already in the buffer. If there is one,
606 we don't need a thread. This also catches the second key of
607 multi-character returns from getch, for instance for arrow
608 keys. The second half is in a C library internal buffer,
609 and PeekConsoleInput will not find it. */
610 if (_kbhit ())
611 {
612 SetEvent (state->read_event);
613 return;
614 }
0ea3f30e 615
c3e2b812 616 /* Otherwise, start the select thread. */
0ea3f30e 617 SetEvent (state->start_select);
c3e2b812 618}
0ea3f30e 619
c3e2b812
DJ
620static void
621ser_console_done_wait_handle (struct serial *scb)
622{
623 struct ser_console_state *state = scb->state;
624
625 if (state == NULL)
626 return;
627
628 SetEvent (state->stop_select);
629 WaitForSingleObject (state->have_stopped, INFINITE);
0ea3f30e
DJ
630}
631
632static void
633ser_console_close (struct serial *scb)
634{
635 struct ser_console_state *state = scb->state;
636
637 if (scb->state)
638 {
c3e2b812
DJ
639 SetEvent (state->exit_select);
640
641 WaitForSingleObject (state->thread, INFINITE);
642
643 CloseHandle (state->start_select);
644 CloseHandle (state->stop_select);
645 CloseHandle (state->exit_select);
646 CloseHandle (state->have_stopped);
0ea3f30e
DJ
647
648 CloseHandle (state->read_event);
649 CloseHandle (state->except_event);
650
651 xfree (scb->state);
652 }
653}
654
655struct ser_console_ttystate
656{
657 int is_a_tty;
658};
659
660static serial_ttystate
661ser_console_get_tty_state (struct serial *scb)
662{
663 if (isatty (scb->fd))
664 {
665 struct ser_console_ttystate *state;
666 state = (struct ser_console_ttystate *) xmalloc (sizeof *state);
667 state->is_a_tty = 1;
668 return state;
669 }
670 else
671 return NULL;
672}
673
5f1fb6dc
JB
674struct pipe_state
675{
676 /* Since we use the pipe_select_thread for our select emulation,
677 we need to place the state structure it requires at the front
678 of our state. */
679 struct ser_console_state wait;
680
681 /* The pex obj for our (one-stage) pipeline. */
682 struct pex_obj *pex;
683
684 /* Streams for the pipeline's input and output. */
685 FILE *input, *output;
686};
687
688static struct pipe_state *
689make_pipe_state (void)
690{
691 struct pipe_state *ps = XMALLOC (struct pipe_state);
692
693 memset (ps, 0, sizeof (*ps));
694 ps->wait.read_event = INVALID_HANDLE_VALUE;
695 ps->wait.except_event = INVALID_HANDLE_VALUE;
696 ps->wait.start_select = INVALID_HANDLE_VALUE;
697 ps->wait.stop_select = INVALID_HANDLE_VALUE;
698
699 return ps;
700}
701
702static void
703free_pipe_state (struct pipe_state *ps)
704{
705 int saved_errno = errno;
706
707 if (ps->wait.read_event != INVALID_HANDLE_VALUE)
774a49c0
DJ
708 {
709 SetEvent (ps->wait.exit_select);
710
711 WaitForSingleObject (ps->wait.thread, INFINITE);
5f1fb6dc 712
774a49c0
DJ
713 CloseHandle (ps->wait.start_select);
714 CloseHandle (ps->wait.stop_select);
715 CloseHandle (ps->wait.exit_select);
716 CloseHandle (ps->wait.have_stopped);
717
718 CloseHandle (ps->wait.read_event);
719 CloseHandle (ps->wait.except_event);
720 }
5f1fb6dc
JB
721
722 /* Close the pipe to the child. We must close the pipe before
723 calling pex_free because pex_free will wait for the child to exit
724 and the child will not exit until the pipe is closed. */
725 if (ps->input)
726 fclose (ps->input);
727 if (ps->pex)
728 pex_free (ps->pex);
729 /* pex_free closes ps->output. */
730
731 xfree (ps);
732
733 errno = saved_errno;
734}
735
736static void
737cleanup_pipe_state (void *untyped)
738{
739 struct pipe_state *ps = untyped;
740
741 free_pipe_state (ps);
742}
743
744static int
745pipe_windows_open (struct serial *scb, const char *name)
746{
ef7723eb 747 struct pipe_state *ps;
65cc4390 748 FILE *pex_stderr;
ef7723eb 749
5f1fb6dc
JB
750 char **argv = buildargv (name);
751 struct cleanup *back_to = make_cleanup_freeargv (argv);
752 if (! argv[0] || argv[0][0] == '\0')
753 error ("missing child command");
754
ef7723eb
VP
755
756 ps = make_pipe_state ();
5f1fb6dc
JB
757 make_cleanup (cleanup_pipe_state, ps);
758
759 ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
760 if (! ps->pex)
761 goto fail;
762 ps->input = pex_input_pipe (ps->pex, 1);
763 if (! ps->input)
764 goto fail;
765
766 {
767 int err;
768 const char *err_msg
65cc4390
VP
769 = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
770 | PEX_STDERR_TO_PIPE,
5f1fb6dc
JB
771 argv[0], argv, NULL, NULL,
772 &err);
773
774 if (err_msg)
775 {
776 /* Our caller expects us to return -1, but all they'll do with
777 it generally is print the message based on errno. We have
778 all the same information here, plus err_msg provided by
779 pex_run, so we just raise the error here. */
780 if (err)
781 error ("error starting child process '%s': %s: %s",
782 name, err_msg, safe_strerror (err));
783 else
784 error ("error starting child process '%s': %s",
785 name, err_msg);
786 }
787 }
788
789 ps->output = pex_read_output (ps->pex, 1);
790 if (! ps->output)
791 goto fail;
5f1fb6dc 792 scb->fd = fileno (ps->output);
65cc4390
VP
793
794 pex_stderr = pex_read_err (ps->pex, 1);
795 if (! pex_stderr)
796 goto fail;
797 scb->error_fd = fileno (pex_stderr);
798
5f1fb6dc
JB
799 scb->state = (void *) ps;
800
801 discard_cleanups (back_to);
802 return 0;
803
804 fail:
805 do_cleanups (back_to);
806 return -1;
807}
808
809
810static void
811pipe_windows_close (struct serial *scb)
812{
813 struct pipe_state *ps = scb->state;
814
815 /* In theory, we should try to kill the subprocess here, but the pex
816 interface doesn't give us enough information to do that. Usually
817 closing the input pipe will get the message across. */
818
819 free_pipe_state (ps);
820}
821
822
823static int
824pipe_windows_read (struct serial *scb, size_t count)
825{
4998c1df 826 HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
ef7723eb
VP
827 DWORD available;
828 DWORD bytes_read;
829
5f1fb6dc
JB
830 if (pipeline_out == INVALID_HANDLE_VALUE)
831 return -1;
832
5f1fb6dc
JB
833 if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
834 return -1;
835
836 if (count > available)
837 count = available;
838
5f1fb6dc
JB
839 if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
840 return -1;
841
842 return bytes_read;
843}
844
845
846static int
847pipe_windows_write (struct serial *scb, const void *buf, size_t count)
848{
849 struct pipe_state *ps = scb->state;
ef7723eb
VP
850 HANDLE pipeline_in;
851 DWORD written;
852
5f1fb6dc
JB
853 int pipeline_in_fd = fileno (ps->input);
854 if (pipeline_in_fd < 0)
855 return -1;
856
ef7723eb 857 pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
5f1fb6dc
JB
858 if (pipeline_in == INVALID_HANDLE_VALUE)
859 return -1;
860
5f1fb6dc
JB
861 if (! WriteFile (pipeline_in, buf, count, &written, NULL))
862 return -1;
863
864 return written;
865}
866
867
868static void
869pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
870{
871 struct pipe_state *ps = scb->state;
872
873 /* Have we allocated our events yet? */
874 if (ps->wait.read_event == INVALID_HANDLE_VALUE)
875 {
876 DWORD threadId;
877
774a49c0
DJ
878 /* Create auto reset events to wake, stop, and exit the select
879 thread. */
5f1fb6dc
JB
880 ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0);
881 ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0);
774a49c0
DJ
882 ps->wait.exit_select = CreateEvent (0, FALSE, FALSE, 0);
883
884 /* Create a manual reset event to signal whether the thread is
885 stopped. This must be manual reset, because we may wait on
886 it multiple times without ever starting the thread. */
887 ps->wait.have_stopped = CreateEvent (0, TRUE, FALSE, 0);
5f1fb6dc
JB
888
889 /* Create our own events to report read and exceptions separately.
890 The exception event is currently never used. */
891 ps->wait.read_event = CreateEvent (0, FALSE, FALSE, 0);
892 ps->wait.except_event = CreateEvent (0, FALSE, FALSE, 0);
893
894 /* Start the select thread. */
895 CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId);
896 }
897
774a49c0
DJ
898 *read = ps->wait.read_event;
899 *except = ps->wait.except_event;
900
901 /* Start from a blank state. */
5f1fb6dc
JB
902 ResetEvent (ps->wait.read_event);
903 ResetEvent (ps->wait.except_event);
774a49c0 904 ResetEvent (ps->wait.stop_select);
5f1fb6dc 905
774a49c0 906 /* Start the select thread. */
5f1fb6dc 907 SetEvent (ps->wait.start_select);
5f1fb6dc
JB
908}
909
774a49c0
DJ
910static void
911pipe_done_wait_handle (struct serial *scb)
912{
913 struct pipe_state *ps = scb->state;
914
915 /* Have we allocated our events yet? */
916 if (ps->wait.read_event == INVALID_HANDLE_VALUE)
917 return;
918
919 SetEvent (ps->wait.stop_select);
920 WaitForSingleObject (ps->wait.have_stopped, INFINITE);
921}
5f1fb6dc 922
65cc4390
VP
923static int
924pipe_avail (struct serial *scb, int fd)
925{
926 HANDLE h = (HANDLE) _get_osfhandle (fd);
927 DWORD numBytes;
928 BOOL r = PeekNamedPipe (h, NULL, 0, NULL, &numBytes, NULL);
929 if (r == FALSE)
930 numBytes = 0;
931 return numBytes;
932}
933
0ea3f30e
DJ
934struct net_windows_state
935{
936 HANDLE read_event;
937 HANDLE except_event;
938
939 HANDLE start_select;
940 HANDLE stop_select;
c3e2b812
DJ
941 HANDLE exit_select;
942 HANDLE have_stopped;
943
0ea3f30e 944 HANDLE sock_event;
c3e2b812
DJ
945
946 HANDLE thread;
0ea3f30e
DJ
947};
948
949static DWORD WINAPI
950net_windows_select_thread (void *arg)
951{
952 struct serial *scb = arg;
953 struct net_windows_state *state, state_copy;
c3e2b812 954 int event_index;
0ea3f30e 955
c3e2b812 956 state = scb->state;
0ea3f30e
DJ
957
958 while (1)
959 {
960 HANDLE wait_events[2];
961 WSANETWORKEVENTS events;
962
c3e2b812
DJ
963 SetEvent (state->have_stopped);
964
0ea3f30e 965 wait_events[0] = state->start_select;
c3e2b812 966 wait_events[1] = state->exit_select;
0ea3f30e
DJ
967
968 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
c3e2b812
DJ
969 return 0;
970
971 ResetEvent (state->have_stopped);
0ea3f30e
DJ
972
973 wait_events[0] = state->stop_select;
974 wait_events[1] = state->sock_event;
975
976 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
977
978 if (event_index == WAIT_OBJECT_0
979 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
c3e2b812 980 continue;
0ea3f30e
DJ
981
982 if (event_index != WAIT_OBJECT_0 + 1)
983 {
984 /* Some error has occured. Assume that this is an error
985 condition. */
986 SetEvent (state->except_event);
987 continue;
988 }
989
990 /* Enumerate the internal network events, and reset the object that
991 signalled us to catch the next event. */
c3e2b812
DJ
992 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
993
994 gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE));
0ea3f30e
DJ
995
996 if (events.lNetworkEvents & FD_READ)
997 SetEvent (state->read_event);
998
999 if (events.lNetworkEvents & FD_CLOSE)
1000 SetEvent (state->except_event);
1001 }
1002}
1003
1004static void
1005net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
1006{
1007 struct net_windows_state *state = scb->state;
1008
c3e2b812 1009 /* Start from a clean slate. */
0ea3f30e
DJ
1010 ResetEvent (state->read_event);
1011 ResetEvent (state->except_event);
c3e2b812 1012 ResetEvent (state->stop_select);
0ea3f30e
DJ
1013
1014 *read = state->read_event;
1015 *except = state->except_event;
c3e2b812
DJ
1016
1017 /* Check any pending events. This both avoids starting the thread
1018 unnecessarily, and handles stray FD_READ events (see below). */
1019 if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0)
1020 {
1021 WSANETWORKEVENTS events;
1022 int any = 0;
1023
1024 /* Enumerate the internal network events, and reset the object that
1025 signalled us to catch the next event. */
1026 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
1027
1028 /* You'd think that FD_READ or FD_CLOSE would be set here. But,
1029 sometimes, neither is. I suspect that the FD_READ is set and
1030 the corresponding event signalled while recv is running, and
1031 the FD_READ is then lowered when recv consumes all the data,
1032 but there's no way to un-signal the event. This isn't a
1033 problem for the call in net_select_thread, since any new
1034 events after this point will not have been drained by recv.
1035 It just means that we can't have the obvious assert here. */
1036
1037 /* If there is a read event, it might be still valid, or it might
1038 not be - it may have been signalled before we last called
1039 recv. Double-check that there is data. */
1040 if (events.lNetworkEvents & FD_READ)
1041 {
1042 unsigned long available;
1043
1044 if (ioctlsocket (scb->fd, FIONREAD, &available) == 0
1045 && available > 0)
1046 {
1047 SetEvent (state->read_event);
1048 any = 1;
1049 }
1050 else
1051 /* Oops, no data. This call to recv will cause future
1052 data to retrigger the event, e.g. while we are
1053 in net_select_thread. */
1054 recv (scb->fd, NULL, 0, 0);
1055 }
1056
1057 /* If there's a close event, then record it - it is obviously
1058 still valid, and it will not be resignalled. */
1059 if (events.lNetworkEvents & FD_CLOSE)
1060 {
1061 SetEvent (state->except_event);
1062 any = 1;
1063 }
1064
1065 /* If we set either handle, there's no need to wake the thread. */
1066 if (any)
1067 return;
1068 }
1069
1070 /* Start the select thread. */
1071 SetEvent (state->start_select);
1072}
1073
1074static void
1075net_windows_done_wait_handle (struct serial *scb)
1076{
1077 struct net_windows_state *state = scb->state;
1078
1079 SetEvent (state->stop_select);
1080 WaitForSingleObject (state->have_stopped, INFINITE);
0ea3f30e
DJ
1081}
1082
1083static int
1084net_windows_open (struct serial *scb, const char *name)
1085{
1086 struct net_windows_state *state;
1087 int ret;
1088 DWORD threadId;
1089
1090 ret = net_open (scb, name);
1091 if (ret != 0)
1092 return ret;
1093
1094 state = xmalloc (sizeof (struct net_windows_state));
1095 memset (state, 0, sizeof (struct net_windows_state));
1096 scb->state = state;
1097
c3e2b812
DJ
1098 /* Create auto reset events to wake, stop, and exit the select
1099 thread. */
0ea3f30e
DJ
1100 state->start_select = CreateEvent (0, FALSE, FALSE, 0);
1101 state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
c3e2b812
DJ
1102 state->exit_select = CreateEvent (0, FALSE, FALSE, 0);
1103
1104 /* Create a manual reset event to signal whether the thread is
1105 stopped. This must be manual reset, because we may wait on
1106 it multiple times without ever starting the thread. */
1107 state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);
0ea3f30e
DJ
1108
1109 /* Associate an event with the socket. */
1110 state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
1111 WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);
1112
1113 /* Create our own events to report read and close separately. */
1114 state->read_event = CreateEvent (0, FALSE, FALSE, 0);
1115 state->except_event = CreateEvent (0, FALSE, FALSE, 0);
1116
1117 /* And finally start the select thread. */
c3e2b812
DJ
1118 state->thread = CreateThread (NULL, 0, net_windows_select_thread, scb, 0,
1119 &threadId);
0ea3f30e
DJ
1120
1121 return 0;
1122}
1123
1124
1125static void
1126net_windows_close (struct serial *scb)
1127{
1128 struct net_windows_state *state = scb->state;
1129
c3e2b812
DJ
1130 SetEvent (state->exit_select);
1131 WaitForSingleObject (state->thread, INFINITE);
0ea3f30e
DJ
1132
1133 CloseHandle (state->read_event);
1134 CloseHandle (state->except_event);
c3e2b812 1135
0ea3f30e 1136 CloseHandle (state->start_select);
c3e2b812
DJ
1137 CloseHandle (state->stop_select);
1138 CloseHandle (state->exit_select);
1139 CloseHandle (state->have_stopped);
1140
0ea3f30e
DJ
1141 CloseHandle (state->sock_event);
1142
1143 xfree (scb->state);
1144
1145 net_close (scb);
1146}
1147
1148void
1149_initialize_ser_windows (void)
1150{
1151 WSADATA wsa_data;
1152 struct serial_ops *ops;
1153
1154 /* First register the serial port driver. */
1155
1156 ops = XMALLOC (struct serial_ops);
1157 memset (ops, 0, sizeof (struct serial_ops));
1158 ops->name = "hardwire";
1159 ops->next = 0;
1160 ops->open = ser_windows_open;
1161 ops->close = ser_windows_close;
1162
1163 ops->flush_output = ser_windows_flush_output;
1164 ops->flush_input = ser_windows_flush_input;
1165 ops->send_break = ser_windows_send_break;
1166
1167 /* These are only used for stdin; we do not need them for serial
1168 ports, so supply the standard dummies. */
1169 ops->get_tty_state = ser_base_get_tty_state;
1170 ops->set_tty_state = ser_base_set_tty_state;
1171 ops->print_tty_state = ser_base_print_tty_state;
1172 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1173
1174 ops->go_raw = ser_windows_raw;
1175 ops->setbaudrate = ser_windows_setbaudrate;
1176 ops->setstopbits = ser_windows_setstopbits;
1177 ops->drain_output = ser_windows_drain_output;
1178 ops->readchar = ser_base_readchar;
1179 ops->write = ser_base_write;
1180 ops->async = ser_base_async;
1181 ops->read_prim = ser_windows_read_prim;
1182 ops->write_prim = ser_windows_write_prim;
1183 ops->wait_handle = ser_windows_wait_handle;
1184
1185 serial_add_interface (ops);
1186
1187 /* Next create the dummy serial driver used for terminals. We only
1188 provide the TTY-related methods. */
1189
1190 ops = XMALLOC (struct serial_ops);
1191 memset (ops, 0, sizeof (struct serial_ops));
1192
1193 ops->name = "terminal";
1194 ops->next = 0;
1195
1196 ops->close = ser_console_close;
1197 ops->get_tty_state = ser_console_get_tty_state;
1198 ops->set_tty_state = ser_base_set_tty_state;
1199 ops->print_tty_state = ser_base_print_tty_state;
1200 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1201 ops->drain_output = ser_base_drain_output;
1202 ops->wait_handle = ser_console_wait_handle;
c3e2b812 1203 ops->done_wait_handle = ser_console_done_wait_handle;
0ea3f30e
DJ
1204
1205 serial_add_interface (ops);
1206
5f1fb6dc
JB
1207 /* The pipe interface. */
1208
1209 ops = XMALLOC (struct serial_ops);
1210 memset (ops, 0, sizeof (struct serial_ops));
1211 ops->name = "pipe";
1212 ops->next = 0;
1213 ops->open = pipe_windows_open;
1214 ops->close = pipe_windows_close;
1215 ops->readchar = ser_base_readchar;
1216 ops->write = ser_base_write;
1217 ops->flush_output = ser_base_flush_output;
1218 ops->flush_input = ser_base_flush_input;
1219 ops->send_break = ser_base_send_break;
1220 ops->go_raw = ser_base_raw;
1221 ops->get_tty_state = ser_base_get_tty_state;
1222 ops->set_tty_state = ser_base_set_tty_state;
1223 ops->print_tty_state = ser_base_print_tty_state;
1224 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1225 ops->setbaudrate = ser_base_setbaudrate;
1226 ops->setstopbits = ser_base_setstopbits;
1227 ops->drain_output = ser_base_drain_output;
1228 ops->async = ser_base_async;
1229 ops->read_prim = pipe_windows_read;
1230 ops->write_prim = pipe_windows_write;
1231 ops->wait_handle = pipe_wait_handle;
774a49c0 1232 ops->done_wait_handle = pipe_done_wait_handle;
65cc4390 1233 ops->avail = pipe_avail;
5f1fb6dc
JB
1234
1235 serial_add_interface (ops);
1236
0ea3f30e
DJ
1237 /* If WinSock works, register the TCP/UDP socket driver. */
1238
1239 if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
1240 /* WinSock is unavailable. */
1241 return;
1242
1243 ops = XMALLOC (struct serial_ops);
1244 memset (ops, 0, sizeof (struct serial_ops));
1245 ops->name = "tcp";
1246 ops->next = 0;
1247 ops->open = net_windows_open;
1248 ops->close = net_windows_close;
1249 ops->readchar = ser_base_readchar;
1250 ops->write = ser_base_write;
1251 ops->flush_output = ser_base_flush_output;
1252 ops->flush_input = ser_base_flush_input;
1253 ops->send_break = ser_base_send_break;
1254 ops->go_raw = ser_base_raw;
1255 ops->get_tty_state = ser_base_get_tty_state;
1256 ops->set_tty_state = ser_base_set_tty_state;
1257 ops->print_tty_state = ser_base_print_tty_state;
1258 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1259 ops->setbaudrate = ser_base_setbaudrate;
1260 ops->setstopbits = ser_base_setstopbits;
1261 ops->drain_output = ser_base_drain_output;
1262 ops->async = ser_base_async;
1263 ops->read_prim = net_read_prim;
1264 ops->write_prim = net_write_prim;
1265 ops->wait_handle = net_windows_wait_handle;
c3e2b812 1266 ops->done_wait_handle = net_windows_done_wait_handle;
0ea3f30e
DJ
1267 serial_add_interface (ops);
1268}
This page took 0.203227 seconds and 4 git commands to generate.