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