1/* Serial interface for local (hardwired) serial ports on Windows systems 2 3 Copyright (C) 2006, 2007 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "defs.h" 21#include "serial.h" 22#include "ser-base.h" 23#include "ser-tcp.h" 24 25#include <windows.h> 26#include <conio.h> 27 28#include <fcntl.h> 29#include <unistd.h> 30#include <sys/types.h> 31 32#include "gdb_assert.h" 33#include "gdb_string.h" 34 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; 351 HANDLE exit_select; 352 HANDLE have_stopped; 353 354 HANDLE thread; 355}; 356 357static DWORD WINAPI 358console_select_thread (void *arg) 359{ 360 struct serial *scb = arg; 361 struct ser_console_state *state; 362 int event_index; 363 HANDLE h; 364 365 state = scb->state; 366 h = (HANDLE) _get_osfhandle (scb->fd); 367 368 while (1) 369 { 370 HANDLE wait_events[2]; 371 INPUT_RECORD record; 372 DWORD n_records; 373 374 SetEvent (state->have_stopped); 375 376 wait_events[0] = state->start_select; 377 wait_events[1] = state->exit_select; 378 379 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0) 380 return 0; 381 382 ResetEvent (state->have_stopped); 383 384 retry: 385 wait_events[0] = state->stop_select; 386 wait_events[1] = h; 387 388 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE); 389 390 if (event_index == WAIT_OBJECT_0 391 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0) 392 continue; 393 394 if (event_index != WAIT_OBJECT_0 + 1) 395 { 396 /* Wait must have failed; assume an error has occured, e.g. 397 the handle has been closed. */ 398 SetEvent (state->except_event); 399 continue; 400 } 401 402 /* We've got a pending event on the console. See if it's 403 of interest. */ 404 if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1) 405 { 406 /* Something went wrong. Maybe the console is gone. */ 407 SetEvent (state->except_event); 408 continue; 409 } 410 411 if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown) 412 { 413 WORD keycode = record.Event.KeyEvent.wVirtualKeyCode; 414 415 /* Ignore events containing only control keys. We must 416 recognize "enhanced" keys which we are interested in 417 reading via getch, if they do not map to ASCII. But we 418 do not want to report input available for e.g. the 419 control key alone. */ 420 421 if (record.Event.KeyEvent.uChar.AsciiChar != 0 422 || keycode == VK_PRIOR 423 || keycode == VK_NEXT 424 || keycode == VK_END 425 || keycode == VK_HOME 426 || keycode == VK_LEFT 427 || keycode == VK_UP 428 || keycode == VK_RIGHT 429 || keycode == VK_DOWN 430 || keycode == VK_INSERT 431 || keycode == VK_DELETE) 432 { 433 /* This is really a keypress. */ 434 SetEvent (state->read_event); 435 continue; 436 } 437 } 438 439 /* Otherwise discard it and wait again. */ 440 ReadConsoleInput (h, &record, 1, &n_records); 441 goto retry; 442 } 443} 444 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 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 463static DWORD WINAPI 464pipe_select_thread (void *arg) 465{ 466 struct serial *scb = arg; 467 struct ser_console_state *state; 468 int event_index; 469 HANDLE h; 470 471 state = scb->state; 472 h = (HANDLE) _get_osfhandle (scb->fd); 473 474 while (1) 475 { 476 HANDLE wait_events[2]; 477 DWORD n_avail; 478 479 SetEvent (state->have_stopped); 480 481 wait_events[0] = state->start_select; 482 wait_events[1] = state->exit_select; 483 484 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0) 485 return 0; 486 487 ResetEvent (state->have_stopped); 488 489 retry: 490 if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL)) 491 { 492 SetEvent (state->except_event); 493 continue; 494 } 495 496 if (n_avail > 0) 497 { 498 SetEvent (state->read_event); 499 continue; 500 } 501 502 /* Delay 10ms before checking again, but allow the stop event 503 to wake us. */ 504 if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0) 505 continue; 506 507 goto retry; 508 } 509} 510 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 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); 558 if (!is_tty && !fd_is_file (scb->fd) && !fd_is_pipe (scb->fd)) 559 { 560 *read = NULL; 561 *except = NULL; 562 return; 563 } 564 565 state = xmalloc (sizeof (struct ser_console_state)); 566 memset (state, 0, sizeof (struct ser_console_state)); 567 scb->state = state; 568 569 /* Create auto reset events to wake, stop, and exit the select 570 thread. */ 571 state->start_select = CreateEvent (0, FALSE, FALSE, 0); 572 state->stop_select = CreateEvent (0, FALSE, FALSE, 0); 573 state->exit_select = CreateEvent (0, FALSE, FALSE, 0); 574 575 /* Create a manual reset event to signal whether the thread is 576 stopped. This must be manual reset, because we may wait on 577 it multiple times without ever starting the thread. */ 578 state->have_stopped = CreateEvent (0, TRUE, FALSE, 0); 579 580 /* Create our own events to report read and exceptions separately. */ 581 state->read_event = CreateEvent (0, FALSE, FALSE, 0); 582 state->except_event = CreateEvent (0, FALSE, FALSE, 0); 583 584 if (is_tty) 585 state->thread = CreateThread (NULL, 0, console_select_thread, scb, 0, 586 &threadId); 587 else if (fd_is_pipe (scb->fd)) 588 state->thread = CreateThread (NULL, 0, pipe_select_thread, scb, 0, 589 &threadId); 590 else 591 state->thread = CreateThread (NULL, 0, file_select_thread, scb, 0, 592 &threadId); 593 } 594 595 *read = state->read_event; 596 *except = state->except_event; 597 598 /* Start from a blank state. */ 599 ResetEvent (state->read_event); 600 ResetEvent (state->except_event); 601 ResetEvent (state->stop_select); 602 603 /* First check for a key already in the buffer. If there is one, 604 we don't need a thread. This also catches the second key of 605 multi-character returns from getch, for instance for arrow 606 keys. The second half is in a C library internal buffer, 607 and PeekConsoleInput will not find it. */ 608 if (_kbhit ()) 609 { 610 SetEvent (state->read_event); 611 return; 612 } 613 614 /* Otherwise, start the select thread. */ 615 SetEvent (state->start_select); 616} 617 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); 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 { 637 SetEvent (state->exit_select); 638 639 WaitForSingleObject (state->thread, INFINITE); 640 641 CloseHandle (state->start_select); 642 CloseHandle (state->stop_select); 643 CloseHandle (state->exit_select); 644 CloseHandle (state->have_stopped); 645 646 CloseHandle (state->read_event); 647 CloseHandle (state->except_event); 648 649 xfree (scb->state); 650 } 651} 652 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 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) 706 { 707 SetEvent (ps->wait.exit_select); 708 709 WaitForSingleObject (ps->wait.thread, INFINITE); 710 711 CloseHandle (ps->wait.start_select); 712 CloseHandle (ps->wait.stop_select); 713 CloseHandle (ps->wait.exit_select); 714 CloseHandle (ps->wait.have_stopped); 715 716 CloseHandle (ps->wait.read_event); 717 CloseHandle (ps->wait.except_event); 718 } 719 720 /* Close the pipe to the child. We must close the pipe before 721 calling pex_free because pex_free will wait for the child to exit 722 and the child will not exit until the pipe is closed. */ 723 if (ps->input) 724 fclose (ps->input); 725 if (ps->pex) 726 pex_free (ps->pex); 727 /* pex_free closes ps->output. */ 728 729 xfree (ps); 730 731 errno = saved_errno; 732} 733 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{ 745 struct pipe_state *ps; 746 FILE *pex_stderr; 747 748 char **argv = buildargv (name); 749 struct cleanup *back_to = make_cleanup_freeargv (argv); 750 if (! argv[0] || argv[0][0] == '\0') 751 error ("missing child command"); 752 753 754 ps = make_pipe_state (); 755 make_cleanup (cleanup_pipe_state, ps); 756 757 ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL); 758 if (! ps->pex) 759 goto fail; 760 ps->input = pex_input_pipe (ps->pex, 1); 761 if (! ps->input) 762 goto fail; 763 764 { 765 int err; 766 const char *err_msg 767 = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT 768 | PEX_STDERR_TO_PIPE, 769 argv[0], argv, NULL, NULL, 770 &err); 771 772 if (err_msg) 773 { 774 /* Our caller expects us to return -1, but all they'll do with 775 it generally is print the message based on errno. We have 776 all the same information here, plus err_msg provided by 777 pex_run, so we just raise the error here. */ 778 if (err) 779 error ("error starting child process '%s': %s: %s", 780 name, err_msg, safe_strerror (err)); 781 else 782 error ("error starting child process '%s': %s", 783 name, err_msg); 784 } 785 } 786 787 ps->output = pex_read_output (ps->pex, 1); 788 if (! ps->output) 789 goto fail; 790 scb->fd = fileno (ps->output); 791 792 pex_stderr = pex_read_err (ps->pex, 1); 793 if (! pex_stderr) 794 goto fail; 795 scb->error_fd = fileno (pex_stderr); 796 797 scb->state = (void *) ps; 798 799 discard_cleanups (back_to); 800 return 0; 801 802 fail: 803 do_cleanups (back_to); 804 return -1; 805} 806 807 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{ 824 HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd); 825 DWORD available; 826 DWORD bytes_read; 827 828 if (pipeline_out == INVALID_HANDLE_VALUE) 829 return -1; 830 831 if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL)) 832 return -1; 833 834 if (count > available) 835 count = available; 836 837 if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL)) 838 return -1; 839 840 return bytes_read; 841} 842 843 844static int 845pipe_windows_write (struct serial *scb, const void *buf, size_t count) 846{ 847 struct pipe_state *ps = scb->state; 848 HANDLE pipeline_in; 849 DWORD written; 850 851 int pipeline_in_fd = fileno (ps->input); 852 if (pipeline_in_fd < 0) 853 return -1; 854 855 pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd); 856 if (pipeline_in == INVALID_HANDLE_VALUE) 857 return -1; 858 859 if (! WriteFile (pipeline_in, buf, count, &written, NULL)) 860 return -1; 861 862 return written; 863} 864 865 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 876 /* Create auto reset events to wake, stop, and exit the select 877 thread. */ 878 ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0); 879 ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0); 880 ps->wait.exit_select = CreateEvent (0, FALSE, FALSE, 0); 881 882 /* Create a manual reset event to signal whether the thread is 883 stopped. This must be manual reset, because we may wait on 884 it multiple times without ever starting the thread. */ 885 ps->wait.have_stopped = CreateEvent (0, TRUE, FALSE, 0); 886 887 /* Create our own events to report read and exceptions separately. 888 The exception event is currently never used. */ 889 ps->wait.read_event = CreateEvent (0, FALSE, FALSE, 0); 890 ps->wait.except_event = CreateEvent (0, FALSE, FALSE, 0); 891 892 /* Start the select thread. */ 893 CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId); 894 } 895 896 *read = ps->wait.read_event; 897 *except = ps->wait.except_event; 898 899 /* Start from a blank state. */ 900 ResetEvent (ps->wait.read_event); 901 ResetEvent (ps->wait.except_event); 902 ResetEvent (ps->wait.stop_select); 903 904 /* Start the select thread. */ 905 SetEvent (ps->wait.start_select); 906} 907 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} 920 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 932struct net_windows_state 933{ 934 HANDLE read_event; 935 HANDLE except_event; 936 937 HANDLE start_select; 938 HANDLE stop_select; 939 HANDLE exit_select; 940 HANDLE have_stopped; 941 942 HANDLE sock_event; 943 944 HANDLE thread; 945}; 946 947static DWORD WINAPI 948net_windows_select_thread (void *arg) 949{ 950 struct serial *scb = arg; 951 struct net_windows_state *state, state_copy; 952 int event_index; 953 954 state = scb->state; 955 956 while (1) 957 { 958 HANDLE wait_events[2]; 959 WSANETWORKEVENTS events; 960 961 SetEvent (state->have_stopped); 962 963 wait_events[0] = state->start_select; 964 wait_events[1] = state->exit_select; 965 966 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0) 967 return 0; 968 969 ResetEvent (state->have_stopped); 970 971 wait_events[0] = state->stop_select; 972 wait_events[1] = state->sock_event; 973 974 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE); 975 976 if (event_index == WAIT_OBJECT_0 977 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0) 978 continue; 979 980 if (event_index != WAIT_OBJECT_0 + 1) 981 { 982 /* Some error has occured. Assume that this is an error 983 condition. */ 984 SetEvent (state->except_event); 985 continue; 986 } 987 988 /* Enumerate the internal network events, and reset the object that 989 signalled us to catch the next event. */ 990 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events); 991 992 gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE)); 993 994 if (events.lNetworkEvents & FD_READ) 995 SetEvent (state->read_event); 996 997 if (events.lNetworkEvents & FD_CLOSE) 998 SetEvent (state->except_event); 999 } 1000} 1001 1002static void 1003net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) 1004{ 1005 struct net_windows_state *state = scb->state; 1006 1007 /* Start from a clean slate. */ 1008 ResetEvent (state->read_event); 1009 ResetEvent (state->except_event); 1010 ResetEvent (state->stop_select); 1011 1012 *read = state->read_event; 1013 *except = state->except_event; 1014 1015 /* Check any pending events. This both avoids starting the thread 1016 unnecessarily, and handles stray FD_READ events (see below). */ 1017 if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0) 1018 { 1019 WSANETWORKEVENTS events; 1020 int any = 0; 1021 1022 /* Enumerate the internal network events, and reset the object that 1023 signalled us to catch the next event. */ 1024 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events); 1025 1026 /* You'd think that FD_READ or FD_CLOSE would be set here. But, 1027 sometimes, neither is. I suspect that the FD_READ is set and 1028 the corresponding event signalled while recv is running, and 1029 the FD_READ is then lowered when recv consumes all the data, 1030 but there's no way to un-signal the event. This isn't a 1031 problem for the call in net_select_thread, since any new 1032 events after this point will not have been drained by recv. 1033 It just means that we can't have the obvious assert here. */ 1034 1035 /* If there is a read event, it might be still valid, or it might 1036 not be - it may have been signalled before we last called 1037 recv. Double-check that there is data. */ 1038 if (events.lNetworkEvents & FD_READ) 1039 { 1040 unsigned long available; 1041 1042 if (ioctlsocket (scb->fd, FIONREAD, &available) == 0 1043 && available > 0) 1044 { 1045 SetEvent (state->read_event); 1046 any = 1; 1047 } 1048 else 1049 /* Oops, no data. This call to recv will cause future 1050 data to retrigger the event, e.g. while we are 1051 in net_select_thread. */ 1052 recv (scb->fd, NULL, 0, 0); 1053 } 1054 1055 /* If there's a close event, then record it - it is obviously 1056 still valid, and it will not be resignalled. */ 1057 if (events.lNetworkEvents & FD_CLOSE) 1058 { 1059 SetEvent (state->except_event); 1060 any = 1; 1061 } 1062 1063 /* If we set either handle, there's no need to wake the thread. */ 1064 if (any) 1065 return; 1066 } 1067 1068 /* Start the select thread. */ 1069 SetEvent (state->start_select); 1070} 1071 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); 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 1096 /* Create auto reset events to wake, stop, and exit the select 1097 thread. */ 1098 state->start_select = CreateEvent (0, FALSE, FALSE, 0); 1099 state->stop_select = CreateEvent (0, FALSE, FALSE, 0); 1100 state->exit_select = CreateEvent (0, FALSE, FALSE, 0); 1101 1102 /* Create a manual reset event to signal whether the thread is 1103 stopped. This must be manual reset, because we may wait on 1104 it multiple times without ever starting the thread. */ 1105 state->have_stopped = CreateEvent (0, TRUE, FALSE, 0); 1106 1107 /* Associate an event with the socket. */ 1108 state->sock_event = CreateEvent (0, TRUE, FALSE, 0); 1109 WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE); 1110 1111 /* Create our own events to report read and close separately. */ 1112 state->read_event = CreateEvent (0, FALSE, FALSE, 0); 1113 state->except_event = CreateEvent (0, FALSE, FALSE, 0); 1114 1115 /* And finally start the select thread. */ 1116 state->thread = CreateThread (NULL, 0, net_windows_select_thread, scb, 0, 1117 &threadId); 1118 1119 return 0; 1120} 1121 1122 1123static void 1124net_windows_close (struct serial *scb) 1125{ 1126 struct net_windows_state *state = scb->state; 1127 1128 SetEvent (state->exit_select); 1129 WaitForSingleObject (state->thread, INFINITE); 1130 1131 CloseHandle (state->read_event); 1132 CloseHandle (state->except_event); 1133 1134 CloseHandle (state->start_select); 1135 CloseHandle (state->stop_select); 1136 CloseHandle (state->exit_select); 1137 CloseHandle (state->have_stopped); 1138 1139 CloseHandle (state->sock_event); 1140 1141 xfree (scb->state); 1142 1143 net_close (scb); 1144} 1145 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; 1201 ops->done_wait_handle = ser_console_done_wait_handle; 1202 1203 serial_add_interface (ops); 1204 1205 /* The pipe interface. */ 1206 1207 ops = XMALLOC (struct serial_ops); 1208 memset (ops, 0, sizeof (struct serial_ops)); 1209 ops->name = "pipe"; 1210 ops->next = 0; 1211 ops->open = pipe_windows_open; 1212 ops->close = pipe_windows_close; 1213 ops->readchar = ser_base_readchar; 1214 ops->write = ser_base_write; 1215 ops->flush_output = ser_base_flush_output; 1216 ops->flush_input = ser_base_flush_input; 1217 ops->send_break = ser_base_send_break; 1218 ops->go_raw = ser_base_raw; 1219 ops->get_tty_state = ser_base_get_tty_state; 1220 ops->set_tty_state = ser_base_set_tty_state; 1221 ops->print_tty_state = ser_base_print_tty_state; 1222 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; 1223 ops->setbaudrate = ser_base_setbaudrate; 1224 ops->setstopbits = ser_base_setstopbits; 1225 ops->drain_output = ser_base_drain_output; 1226 ops->async = ser_base_async; 1227 ops->read_prim = pipe_windows_read; 1228 ops->write_prim = pipe_windows_write; 1229 ops->wait_handle = pipe_wait_handle; 1230 ops->done_wait_handle = pipe_done_wait_handle; 1231 ops->avail = pipe_avail; 1232 1233 serial_add_interface (ops); 1234 1235 /* If WinSock works, register the TCP/UDP socket driver. */ 1236 1237 if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0) 1238 /* WinSock is unavailable. */ 1239 return; 1240 1241 ops = XMALLOC (struct serial_ops); 1242 memset (ops, 0, sizeof (struct serial_ops)); 1243 ops->name = "tcp"; 1244 ops->next = 0; 1245 ops->open = net_windows_open; 1246 ops->close = net_windows_close; 1247 ops->readchar = ser_base_readchar; 1248 ops->write = ser_base_write; 1249 ops->flush_output = ser_base_flush_output; 1250 ops->flush_input = ser_base_flush_input; 1251 ops->send_break = ser_base_send_break; 1252 ops->go_raw = ser_base_raw; 1253 ops->get_tty_state = ser_base_get_tty_state; 1254 ops->set_tty_state = ser_base_set_tty_state; 1255 ops->print_tty_state = ser_base_print_tty_state; 1256 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; 1257 ops->setbaudrate = ser_base_setbaudrate; 1258 ops->setstopbits = ser_base_setstopbits; 1259 ops->drain_output = ser_base_drain_output; 1260 ops->async = ser_base_async; 1261 ops->read_prim = net_read_prim; 1262 ops->write_prim = net_write_prim; 1263 ops->wait_handle = net_windows_wait_handle; 1264 ops->done_wait_handle = net_windows_done_wait_handle; 1265 serial_add_interface (ops); 1266} 1267