1 /* Serial interface for local (hardwired) serial ports on Windows systems
3 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
30 #include <sys/types.h>
32 #include "gdb_assert.h"
33 #include "gdb_string.h"
35 void _initialize_ser_windows (void);
37 struct ser_windows_state
45 /* Open up a real live device for serial I/O. */
48 ser_windows_open (struct serial *scb, const char *name)
51 struct ser_windows_state *state;
52 COMMTIMEOUTS timeouts;
54 h = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
55 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
56 if (h == INVALID_HANDLE_VALUE)
62 scb->fd = _open_osfhandle ((long) h, O_RDWR);
69 if (!SetCommMask (h, EV_RXCHAR))
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))
86 state = xmalloc (sizeof (struct ser_windows_state));
87 memset (state, 0, sizeof (struct ser_windows_state));
90 /* Create a manual reset event to watch the input buffer. */
91 state->ov.hEvent = CreateEvent (0, TRUE, FALSE, 0);
93 /* Create a (currently unused) handle to record exceptions. */
94 state->except_event = CreateEvent (0, TRUE, FALSE, 0);
99 /* Wait for the output to drain away, as opposed to flushing (discarding)
103 ser_windows_drain_output (struct serial *scb)
105 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
107 return (FlushFileBuffers (h) != 0) ? 0 : -1;
111 ser_windows_flush_output (struct serial *scb)
113 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
115 return (PurgeComm (h, PURGE_TXCLEAR) != 0) ? 0 : -1;
119 ser_windows_flush_input (struct serial *scb)
121 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
123 return (PurgeComm (h, PURGE_RXCLEAR) != 0) ? 0 : -1;
127 ser_windows_send_break (struct serial *scb)
129 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
131 if (SetCommBreak (h) == 0)
134 /* Delay for 250 milliseconds. */
137 if (ClearCommBreak (h))
144 ser_windows_raw (struct serial *scb)
146 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
149 if (GetCommState (h, &state) == 0)
152 state.fParity = FALSE;
153 state.fOutxCtsFlow = FALSE;
154 state.fOutxDsrFlow = FALSE;
155 state.fDtrControl = DTR_CONTROL_ENABLE;
156 state.fDsrSensitivity = FALSE;
160 state.fAbortOnError = FALSE;
162 state.Parity = NOPARITY;
164 scb->current_timeout = 0;
166 if (SetCommState (h, &state) == 0)
167 warning (_("SetCommState failed\n"));
171 ser_windows_setstopbits (struct serial *scb, int num)
173 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
176 if (GetCommState (h, &state) == 0)
181 case SERIAL_1_STOPBITS:
182 state.StopBits = ONESTOPBIT;
184 case SERIAL_1_AND_A_HALF_STOPBITS:
185 state.StopBits = ONE5STOPBITS;
187 case SERIAL_2_STOPBITS:
188 state.StopBits = TWOSTOPBITS;
194 return (SetCommState (h, &state) != 0) ? 0 : -1;
198 ser_windows_setbaudrate (struct serial *scb, int rate)
200 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
203 if (GetCommState (h, &state) == 0)
206 state.BaudRate = rate;
208 return (SetCommState (h, &state) != 0) ? 0 : -1;
212 ser_windows_close (struct serial *scb)
214 struct ser_windows_state *state;
216 /* Stop any pending selects. */
217 CancelIo ((HANDLE) _get_osfhandle (scb->fd));
219 CloseHandle (state->ov.hEvent);
220 CloseHandle (state->except_event);
232 ser_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
234 struct ser_windows_state *state;
237 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
241 *except = state->except_event;
242 *read = state->ov.hEvent;
244 if (state->in_progress)
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. */
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"));
258 if (!SetCommMask (h, EV_RXCHAR))
259 warning (_("ser_windows_wait_handle: reseting mask failed (2)"));
261 /* There's a potential race condition here; we must check cbInQue
262 and not wait if that's nonzero. */
264 ClearCommError (h, &errors, &status);
265 if (status.cbInQue > 0)
267 SetEvent (state->ov.hEvent);
271 state->in_progress = 1;
272 ResetEvent (state->ov.hEvent);
273 state->lastCommMask = -2;
274 if (WaitCommEvent (h, &state->lastCommMask, &state->ov))
276 gdb_assert (state->lastCommMask & EV_RXCHAR);
277 SetEvent (state->ov.hEvent);
280 gdb_assert (GetLastError () == ERROR_IO_PENDING);
284 ser_windows_read_prim (struct serial *scb, size_t count)
286 struct ser_windows_state *state;
288 DWORD bytes_read, bytes_read_tmp;
293 if (state->in_progress)
295 WaitForSingleObject (state->ov.hEvent, INFINITE);
296 state->in_progress = 0;
297 ResetEvent (state->ov.hEvent);
300 memset (&ov, 0, sizeof (OVERLAPPED));
301 ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
302 h = (HANDLE) _get_osfhandle (scb->fd);
304 if (!ReadFile (h, scb->buf, /* count */ 1, &bytes_read, &ov))
306 if (GetLastError () != ERROR_IO_PENDING
307 || !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
311 CloseHandle (ov.hEvent);
316 ser_windows_write_prim (struct serial *scb, const void *buf, size_t len)
318 struct ser_windows_state *state;
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))
328 if (GetLastError () != ERROR_IO_PENDING
329 || !GetOverlappedResult (h, &ov, &bytes_written, TRUE))
333 CloseHandle (ov.hEvent);
334 return bytes_written;
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.
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
353 enum select_thread_state {
358 struct ser_console_state
360 /* Signaled by the select thread to indicate that data is available
361 on the file descriptor. */
363 /* Signaled by the select thread to indicate that an exception has
364 occurred on the file descriptor. */
366 /* Signaled by the select thread to indicate that it has entered the
367 started state. HAVE_STARTED and HAVE_STOPPED are never signaled
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. */
376 /* Signaled by the main program to tell the select thread to enter
377 the started state. */
379 /* Signaled by the main program to tell the select thread to enter
380 the stopped state. */
382 /* Signaled by the main program to tell the select thread to
386 /* The handle for the select thread. */
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;
393 /* Called by a select thread to enter the stopped state. This
394 function does not return until the thread has re-entered the
397 select_thread_wait (struct ser_console_state *state)
399 HANDLE wait_events[2];
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)
407 /* Either the EXIT_SELECT event was signaled (requesting that the
408 thread exit) or an error has occurred. In either case, we exit
412 /* We are now in the started state. */
413 SetEvent (state->have_started);
416 typedef DWORD WINAPI (*thread_fn_type)(void *);
418 /* Create a new select thread for SCB executing THREAD_FN. The STATE
419 will be filled in by this function before return. */
421 create_select_thread (thread_fn_type thread_fn,
423 struct ser_console_state *state)
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);
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;
441 /* Destroy the select thread indicated by STATE. */
443 destroy_select_thread (struct ser_console_state *state)
445 /* Ask the thread to exit. */
446 SetEvent (state->exit_select);
447 /* Wait until it does. */
448 WaitForSingleObject (state->thread, INFINITE);
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);
460 /* Called by gdb_select to start the select thread indicated by STATE.
461 This function does not return until the thread has started. */
463 start_select_thread (struct ser_console_state *state)
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;
473 /* Called by gdb_select to stop the select thread indicated by STATE.
474 This function does not return until the thread has stopped. */
476 stop_select_thread (struct ser_console_state *state)
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)
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;
494 console_select_thread (void *arg)
496 struct serial *scb = arg;
497 struct ser_console_state *state;
502 h = (HANDLE) _get_osfhandle (scb->fd);
506 HANDLE wait_events[2];
510 select_thread_wait (state);
514 wait_events[0] = state->stop_select;
517 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
519 if (event_index == WAIT_OBJECT_0
520 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
523 if (event_index != WAIT_OBJECT_0 + 1)
525 /* Wait must have failed; assume an error has occured, e.g.
526 the handle has been closed. */
527 SetEvent (state->except_event);
531 /* We've got a pending event on the console. See if it's
533 if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1)
535 /* Something went wrong. Maybe the console is gone. */
536 SetEvent (state->except_event);
540 if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
542 WORD keycode = record.Event.KeyEvent.wVirtualKeyCode;
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. */
550 if (record.Event.KeyEvent.uChar.AsciiChar != 0
551 || keycode == VK_PRIOR
552 || keycode == VK_NEXT
554 || keycode == VK_HOME
555 || keycode == VK_LEFT
557 || keycode == VK_RIGHT
558 || keycode == VK_DOWN
559 || keycode == VK_INSERT
560 || keycode == VK_DELETE)
562 /* This is really a keypress. */
563 SetEvent (state->read_event);
568 /* Otherwise discard it and wait again. */
569 ReadConsoleInput (h, &record, 1, &n_records);
572 SetEvent(state->have_stopped);
579 if (PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, NULL, NULL))
588 if (GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_DISK)
595 pipe_select_thread (void *arg)
597 struct serial *scb = arg;
598 struct ser_console_state *state;
603 h = (HANDLE) _get_osfhandle (scb->fd);
609 select_thread_wait (state);
611 /* Wait for something to happen on the pipe. */
614 if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
616 SetEvent (state->except_event);
622 SetEvent (state->read_event);
626 /* Delay 10ms before checking again, but allow the stop
628 if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0)
632 SetEvent (state->have_stopped);
637 file_select_thread (void *arg)
639 struct serial *scb = arg;
640 struct ser_console_state *state;
645 h = (HANDLE) _get_osfhandle (scb->fd);
649 select_thread_wait (state);
651 if (SetFilePointer (h, 0, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER)
652 SetEvent (state->except_event);
654 SetEvent (state->read_event);
656 SetEvent (state->have_stopped);
661 ser_console_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
663 struct ser_console_state *state = scb->state;
667 thread_fn_type thread_fn;
670 is_tty = isatty (scb->fd);
671 if (!is_tty && !fd_is_file (scb->fd) && !fd_is_pipe (scb->fd))
678 state = xmalloc (sizeof (struct ser_console_state));
679 memset (state, 0, sizeof (struct ser_console_state));
683 thread_fn = console_select_thread;
684 else if (fd_is_pipe (scb->fd))
685 thread_fn = pipe_select_thread;
687 thread_fn = file_select_thread;
689 create_select_thread (thread_fn, scb, state);
692 *read = state->read_event;
693 *except = state->except_event;
695 /* Start from a blank state. */
696 ResetEvent (state->read_event);
697 ResetEvent (state->except_event);
698 ResetEvent (state->stop_select);
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. */
707 SetEvent (state->read_event);
711 /* Otherwise, start the select thread. */
712 start_select_thread (state);
716 ser_console_done_wait_handle (struct serial *scb)
718 struct ser_console_state *state = scb->state;
723 stop_select_thread (state);
727 ser_console_close (struct serial *scb)
729 struct ser_console_state *state = scb->state;
733 destroy_select_thread (state);
738 struct ser_console_ttystate
743 static serial_ttystate
744 ser_console_get_tty_state (struct serial *scb)
746 if (isatty (scb->fd))
748 struct ser_console_ttystate *state;
749 state = (struct ser_console_ttystate *) xmalloc (sizeof *state);
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
762 struct ser_console_state wait;
764 /* The pex obj for our (one-stage) pipeline. */
767 /* Streams for the pipeline's input and output. */
768 FILE *input, *output;
771 static struct pipe_state *
772 make_pipe_state (void)
774 struct pipe_state *ps = XMALLOC (struct pipe_state);
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;
786 free_pipe_state (struct pipe_state *ps)
788 int saved_errno = errno;
790 if (ps->wait.read_event != INVALID_HANDLE_VALUE)
791 destroy_select_thread (&ps->wait);
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. */
800 /* pex_free closes ps->output. */
808 cleanup_pipe_state (void *untyped)
810 struct pipe_state *ps = untyped;
812 free_pipe_state (ps);
816 pipe_windows_open (struct serial *scb, const char *name)
818 struct pipe_state *ps;
821 char **argv = buildargv (name);
822 struct cleanup *back_to = make_cleanup_freeargv (argv);
823 if (! argv[0] || argv[0][0] == '\0')
824 error ("missing child command");
827 ps = make_pipe_state ();
828 make_cleanup (cleanup_pipe_state, ps);
830 ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
833 ps->input = pex_input_pipe (ps->pex, 1);
840 = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
841 | PEX_STDERR_TO_PIPE,
842 argv[0], argv, NULL, NULL,
847 /* Our caller expects us to return -1, but all they'll do with
848 it generally is print the message based on errno. We have
849 all the same information here, plus err_msg provided by
850 pex_run, so we just raise the error here. */
852 error ("error starting child process '%s': %s: %s",
853 name, err_msg, safe_strerror (err));
855 error ("error starting child process '%s': %s",
860 ps->output = pex_read_output (ps->pex, 1);
863 scb->fd = fileno (ps->output);
865 pex_stderr = pex_read_err (ps->pex, 1);
868 scb->error_fd = fileno (pex_stderr);
870 scb->state = (void *) ps;
872 discard_cleanups (back_to);
876 do_cleanups (back_to);
882 pipe_windows_close (struct serial *scb)
884 struct pipe_state *ps = scb->state;
886 /* In theory, we should try to kill the subprocess here, but the pex
887 interface doesn't give us enough information to do that. Usually
888 closing the input pipe will get the message across. */
890 free_pipe_state (ps);
895 pipe_windows_read (struct serial *scb, size_t count)
897 HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
901 if (pipeline_out == INVALID_HANDLE_VALUE)
904 if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
907 if (count > available)
910 if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
918 pipe_windows_write (struct serial *scb, const void *buf, size_t count)
920 struct pipe_state *ps = scb->state;
924 int pipeline_in_fd = fileno (ps->input);
925 if (pipeline_in_fd < 0)
928 pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
929 if (pipeline_in == INVALID_HANDLE_VALUE)
932 if (! WriteFile (pipeline_in, buf, count, &written, NULL))
940 pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
942 struct pipe_state *ps = scb->state;
944 /* Have we allocated our events yet? */
945 if (ps->wait.read_event == INVALID_HANDLE_VALUE)
946 /* Start the thread. */
947 create_select_thread (pipe_select_thread, scb, &ps->wait);
949 *read = ps->wait.read_event;
950 *except = ps->wait.except_event;
952 /* Start from a blank state. */
953 ResetEvent (ps->wait.read_event);
954 ResetEvent (ps->wait.except_event);
955 ResetEvent (ps->wait.stop_select);
957 start_select_thread (&ps->wait);
961 pipe_done_wait_handle (struct serial *scb)
963 struct pipe_state *ps = scb->state;
965 /* Have we allocated our events yet? */
966 if (ps->wait.read_event == INVALID_HANDLE_VALUE)
969 stop_select_thread (&ps->wait);
973 pipe_avail (struct serial *scb, int fd)
975 HANDLE h = (HANDLE) _get_osfhandle (fd);
977 BOOL r = PeekNamedPipe (h, NULL, 0, NULL, &numBytes, NULL);
983 struct net_windows_state
985 struct ser_console_state base;
991 net_windows_select_thread (void *arg)
993 struct serial *scb = arg;
994 struct net_windows_state *state;
1001 HANDLE wait_events[2];
1002 WSANETWORKEVENTS events;
1004 select_thread_wait (&state->base);
1006 wait_events[0] = state->base.stop_select;
1007 wait_events[1] = state->sock_event;
1009 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
1011 if (event_index == WAIT_OBJECT_0
1012 || WaitForSingleObject (state->base.stop_select, 0) == WAIT_OBJECT_0)
1013 /* We have been requested to stop. */
1015 else if (event_index != WAIT_OBJECT_0 + 1)
1016 /* Some error has occured. Assume that this is an error
1018 SetEvent (state->base.except_event);
1021 /* Enumerate the internal network events, and reset the
1022 object that signalled us to catch the next event. */
1023 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
1025 gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE));
1027 if (events.lNetworkEvents & FD_READ)
1028 SetEvent (state->base.read_event);
1030 if (events.lNetworkEvents & FD_CLOSE)
1031 SetEvent (state->base.except_event);
1034 SetEvent (state->base.have_stopped);
1039 net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
1041 struct net_windows_state *state = scb->state;
1043 /* Start from a clean slate. */
1044 ResetEvent (state->base.read_event);
1045 ResetEvent (state->base.except_event);
1046 ResetEvent (state->base.stop_select);
1048 *read = state->base.read_event;
1049 *except = state->base.except_event;
1051 /* Check any pending events. This both avoids starting the thread
1052 unnecessarily, and handles stray FD_READ events (see below). */
1053 if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0)
1055 WSANETWORKEVENTS events;
1058 /* Enumerate the internal network events, and reset the object that
1059 signalled us to catch the next event. */
1060 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
1062 /* You'd think that FD_READ or FD_CLOSE would be set here. But,
1063 sometimes, neither is. I suspect that the FD_READ is set and
1064 the corresponding event signalled while recv is running, and
1065 the FD_READ is then lowered when recv consumes all the data,
1066 but there's no way to un-signal the event. This isn't a
1067 problem for the call in net_select_thread, since any new
1068 events after this point will not have been drained by recv.
1069 It just means that we can't have the obvious assert here. */
1071 /* If there is a read event, it might be still valid, or it might
1072 not be - it may have been signalled before we last called
1073 recv. Double-check that there is data. */
1074 if (events.lNetworkEvents & FD_READ)
1076 unsigned long available;
1078 if (ioctlsocket (scb->fd, FIONREAD, &available) == 0
1081 SetEvent (state->base.read_event);
1085 /* Oops, no data. This call to recv will cause future
1086 data to retrigger the event, e.g. while we are
1087 in net_select_thread. */
1088 recv (scb->fd, NULL, 0, 0);
1091 /* If there's a close event, then record it - it is obviously
1092 still valid, and it will not be resignalled. */
1093 if (events.lNetworkEvents & FD_CLOSE)
1095 SetEvent (state->base.except_event);
1099 /* If we set either handle, there's no need to wake the thread. */
1104 start_select_thread (&state->base);
1108 net_windows_done_wait_handle (struct serial *scb)
1110 struct net_windows_state *state = scb->state;
1112 stop_select_thread (&state->base);
1116 net_windows_open (struct serial *scb, const char *name)
1118 struct net_windows_state *state;
1122 ret = net_open (scb, name);
1126 state = xmalloc (sizeof (struct net_windows_state));
1127 memset (state, 0, sizeof (struct net_windows_state));
1130 /* Associate an event with the socket. */
1131 state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
1132 WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);
1134 /* Start the thread. */
1135 create_select_thread (net_windows_select_thread, scb, &state->base);
1142 net_windows_close (struct serial *scb)
1144 struct net_windows_state *state = scb->state;
1146 destroy_select_thread (&state->base);
1147 CloseHandle (state->sock_event);
1155 _initialize_ser_windows (void)
1158 struct serial_ops *ops;
1160 /* First register the serial port driver. */
1162 ops = XMALLOC (struct serial_ops);
1163 memset (ops, 0, sizeof (struct serial_ops));
1164 ops->name = "hardwire";
1166 ops->open = ser_windows_open;
1167 ops->close = ser_windows_close;
1169 ops->flush_output = ser_windows_flush_output;
1170 ops->flush_input = ser_windows_flush_input;
1171 ops->send_break = ser_windows_send_break;
1173 /* These are only used for stdin; we do not need them for serial
1174 ports, so supply the standard dummies. */
1175 ops->get_tty_state = ser_base_get_tty_state;
1176 ops->set_tty_state = ser_base_set_tty_state;
1177 ops->print_tty_state = ser_base_print_tty_state;
1178 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1180 ops->go_raw = ser_windows_raw;
1181 ops->setbaudrate = ser_windows_setbaudrate;
1182 ops->setstopbits = ser_windows_setstopbits;
1183 ops->drain_output = ser_windows_drain_output;
1184 ops->readchar = ser_base_readchar;
1185 ops->write = ser_base_write;
1186 ops->async = ser_base_async;
1187 ops->read_prim = ser_windows_read_prim;
1188 ops->write_prim = ser_windows_write_prim;
1189 ops->wait_handle = ser_windows_wait_handle;
1191 serial_add_interface (ops);
1193 /* Next create the dummy serial driver used for terminals. We only
1194 provide the TTY-related methods. */
1196 ops = XMALLOC (struct serial_ops);
1197 memset (ops, 0, sizeof (struct serial_ops));
1199 ops->name = "terminal";
1202 ops->close = ser_console_close;
1203 ops->get_tty_state = ser_console_get_tty_state;
1204 ops->set_tty_state = ser_base_set_tty_state;
1205 ops->print_tty_state = ser_base_print_tty_state;
1206 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1207 ops->drain_output = ser_base_drain_output;
1208 ops->wait_handle = ser_console_wait_handle;
1209 ops->done_wait_handle = ser_console_done_wait_handle;
1211 serial_add_interface (ops);
1213 /* The pipe interface. */
1215 ops = XMALLOC (struct serial_ops);
1216 memset (ops, 0, sizeof (struct serial_ops));
1219 ops->open = pipe_windows_open;
1220 ops->close = pipe_windows_close;
1221 ops->readchar = ser_base_readchar;
1222 ops->write = ser_base_write;
1223 ops->flush_output = ser_base_flush_output;
1224 ops->flush_input = ser_base_flush_input;
1225 ops->send_break = ser_base_send_break;
1226 ops->go_raw = ser_base_raw;
1227 ops->get_tty_state = ser_base_get_tty_state;
1228 ops->set_tty_state = ser_base_set_tty_state;
1229 ops->print_tty_state = ser_base_print_tty_state;
1230 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1231 ops->setbaudrate = ser_base_setbaudrate;
1232 ops->setstopbits = ser_base_setstopbits;
1233 ops->drain_output = ser_base_drain_output;
1234 ops->async = ser_base_async;
1235 ops->read_prim = pipe_windows_read;
1236 ops->write_prim = pipe_windows_write;
1237 ops->wait_handle = pipe_wait_handle;
1238 ops->done_wait_handle = pipe_done_wait_handle;
1239 ops->avail = pipe_avail;
1241 serial_add_interface (ops);
1243 /* If WinSock works, register the TCP/UDP socket driver. */
1245 if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
1246 /* WinSock is unavailable. */
1249 ops = XMALLOC (struct serial_ops);
1250 memset (ops, 0, sizeof (struct serial_ops));
1253 ops->open = net_windows_open;
1254 ops->close = net_windows_close;
1255 ops->readchar = ser_base_readchar;
1256 ops->write = ser_base_write;
1257 ops->flush_output = ser_base_flush_output;
1258 ops->flush_input = ser_base_flush_input;
1259 ops->send_break = ser_base_send_break;
1260 ops->go_raw = ser_base_raw;
1261 ops->get_tty_state = ser_base_get_tty_state;
1262 ops->set_tty_state = ser_base_set_tty_state;
1263 ops->print_tty_state = ser_base_print_tty_state;
1264 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1265 ops->setbaudrate = ser_base_setbaudrate;
1266 ops->setstopbits = ser_base_setstopbits;
1267 ops->drain_output = ser_base_drain_output;
1268 ops->async = ser_base_async;
1269 ops->read_prim = net_read_prim;
1270 ops->write_prim = net_write_prim;
1271 ops->wait_handle = net_windows_wait_handle;
1272 ops->done_wait_handle = net_windows_done_wait_handle;
1273 serial_add_interface (ops);