1 /* Serial interface for local (hardwired) serial ports on Windows systems
3 Copyright (C) 2006, 2007 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 /* Only allow COM ports. */
55 if (strncmp (name
, "COM", 3) != 0)
61 h
= CreateFile (name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
62 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
63 if (h
== INVALID_HANDLE_VALUE
)
69 scb
->fd
= _open_osfhandle ((long) h
, O_RDWR
);
76 if (!SetCommMask (h
, EV_RXCHAR
))
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
))
93 state
= xmalloc (sizeof (struct ser_windows_state
));
94 memset (state
, 0, sizeof (struct ser_windows_state
));
97 /* Create a manual reset event to watch the input buffer. */
98 state
->ov
.hEvent
= CreateEvent (0, TRUE
, FALSE
, 0);
100 /* Create a (currently unused) handle to record exceptions. */
101 state
->except_event
= CreateEvent (0, TRUE
, FALSE
, 0);
106 /* Wait for the output to drain away, as opposed to flushing (discarding)
110 ser_windows_drain_output (struct serial
*scb
)
112 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
114 return (FlushFileBuffers (h
) != 0) ? 0 : -1;
118 ser_windows_flush_output (struct serial
*scb
)
120 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
122 return (PurgeComm (h
, PURGE_TXCLEAR
) != 0) ? 0 : -1;
126 ser_windows_flush_input (struct serial
*scb
)
128 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
130 return (PurgeComm (h
, PURGE_RXCLEAR
) != 0) ? 0 : -1;
134 ser_windows_send_break (struct serial
*scb
)
136 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
138 if (SetCommBreak (h
) == 0)
141 /* Delay for 250 milliseconds. */
144 if (ClearCommBreak (h
))
151 ser_windows_raw (struct serial
*scb
)
153 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
156 if (GetCommState (h
, &state
) == 0)
159 state
.fParity
= FALSE
;
160 state
.fOutxCtsFlow
= FALSE
;
161 state
.fOutxDsrFlow
= FALSE
;
162 state
.fDtrControl
= DTR_CONTROL_ENABLE
;
163 state
.fDsrSensitivity
= FALSE
;
167 state
.fAbortOnError
= FALSE
;
169 state
.Parity
= NOPARITY
;
171 scb
->current_timeout
= 0;
173 if (SetCommState (h
, &state
) == 0)
174 warning (_("SetCommState failed\n"));
178 ser_windows_setstopbits (struct serial
*scb
, int num
)
180 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
183 if (GetCommState (h
, &state
) == 0)
188 case SERIAL_1_STOPBITS
:
189 state
.StopBits
= ONESTOPBIT
;
191 case SERIAL_1_AND_A_HALF_STOPBITS
:
192 state
.StopBits
= ONE5STOPBITS
;
194 case SERIAL_2_STOPBITS
:
195 state
.StopBits
= TWOSTOPBITS
;
201 return (SetCommState (h
, &state
) != 0) ? 0 : -1;
205 ser_windows_setbaudrate (struct serial
*scb
, int rate
)
207 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
210 if (GetCommState (h
, &state
) == 0)
213 state
.BaudRate
= rate
;
215 return (SetCommState (h
, &state
) != 0) ? 0 : -1;
219 ser_windows_close (struct serial
*scb
)
221 struct ser_windows_state
*state
;
223 /* Stop any pending selects. */
224 CancelIo ((HANDLE
) _get_osfhandle (scb
->fd
));
226 CloseHandle (state
->ov
.hEvent
);
227 CloseHandle (state
->except_event
);
239 ser_windows_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
241 struct ser_windows_state
*state
;
244 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
248 *except
= state
->except_event
;
249 *read
= state
->ov
.hEvent
;
251 if (state
->in_progress
)
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. */
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"));
265 if (!SetCommMask (h
, EV_RXCHAR
))
266 warning (_("ser_windows_wait_handle: reseting mask failed (2)"));
268 /* There's a potential race condition here; we must check cbInQue
269 and not wait if that's nonzero. */
271 ClearCommError (h
, &errors
, &status
);
272 if (status
.cbInQue
> 0)
274 SetEvent (state
->ov
.hEvent
);
278 state
->in_progress
= 1;
279 ResetEvent (state
->ov
.hEvent
);
280 state
->lastCommMask
= -2;
281 if (WaitCommEvent (h
, &state
->lastCommMask
, &state
->ov
))
283 gdb_assert (state
->lastCommMask
& EV_RXCHAR
);
284 SetEvent (state
->ov
.hEvent
);
287 gdb_assert (GetLastError () == ERROR_IO_PENDING
);
291 ser_windows_read_prim (struct serial
*scb
, size_t count
)
293 struct ser_windows_state
*state
;
295 DWORD bytes_read
, bytes_read_tmp
;
300 if (state
->in_progress
)
302 WaitForSingleObject (state
->ov
.hEvent
, INFINITE
);
303 state
->in_progress
= 0;
304 ResetEvent (state
->ov
.hEvent
);
307 memset (&ov
, 0, sizeof (OVERLAPPED
));
308 ov
.hEvent
= CreateEvent (0, FALSE
, FALSE
, 0);
309 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
311 if (!ReadFile (h
, scb
->buf
, /* count */ 1, &bytes_read
, &ov
))
313 if (GetLastError () != ERROR_IO_PENDING
314 || !GetOverlappedResult (h
, &ov
, &bytes_read
, TRUE
))
318 CloseHandle (ov
.hEvent
);
323 ser_windows_write_prim (struct serial
*scb
, const void *buf
, size_t len
)
325 struct ser_windows_state
*state
;
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
))
335 if (GetLastError () != ERROR_IO_PENDING
336 || !GetOverlappedResult (h
, &ov
, &bytes_written
, TRUE
))
340 CloseHandle (ov
.hEvent
);
341 return bytes_written
;
344 struct ser_console_state
358 console_select_thread (void *arg
)
360 struct serial
*scb
= arg
;
361 struct ser_console_state
*state
;
366 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
370 HANDLE wait_events
[2];
374 SetEvent (state
->have_stopped
);
376 wait_events
[0] = state
->start_select
;
377 wait_events
[1] = state
->exit_select
;
379 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
382 ResetEvent (state
->have_stopped
);
385 wait_events
[0] = state
->stop_select
;
388 event_index
= WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
);
390 if (event_index
== WAIT_OBJECT_0
391 || WaitForSingleObject (state
->stop_select
, 0) == WAIT_OBJECT_0
)
394 if (event_index
!= WAIT_OBJECT_0
+ 1)
396 /* Wait must have failed; assume an error has occured, e.g.
397 the handle has been closed. */
398 SetEvent (state
->except_event
);
402 /* We've got a pending event on the console. See if it's
404 if (!PeekConsoleInput (h
, &record
, 1, &n_records
) || n_records
!= 1)
406 /* Something went wrong. Maybe the console is gone. */
407 SetEvent (state
->except_event
);
411 if (record
.EventType
== KEY_EVENT
&& record
.Event
.KeyEvent
.bKeyDown
)
413 WORD keycode
= record
.Event
.KeyEvent
.wVirtualKeyCode
;
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. */
421 if (record
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0
422 || keycode
== VK_PRIOR
423 || keycode
== VK_NEXT
425 || keycode
== VK_HOME
426 || keycode
== VK_LEFT
428 || keycode
== VK_RIGHT
429 || keycode
== VK_DOWN
430 || keycode
== VK_INSERT
431 || keycode
== VK_DELETE
)
433 /* This is really a keypress. */
434 SetEvent (state
->read_event
);
439 /* Otherwise discard it and wait again. */
440 ReadConsoleInput (h
, &record
, 1, &n_records
);
448 if (PeekNamedPipe ((HANDLE
) _get_osfhandle (fd
), NULL
, 0, NULL
, NULL
, NULL
))
457 if (GetFileType ((HANDLE
) _get_osfhandle (fd
)) == FILE_TYPE_DISK
)
464 pipe_select_thread (void *arg
)
466 struct serial
*scb
= arg
;
467 struct ser_console_state
*state
;
472 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
476 HANDLE wait_events
[2];
479 SetEvent (state
->have_stopped
);
481 wait_events
[0] = state
->start_select
;
482 wait_events
[1] = state
->exit_select
;
484 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
487 ResetEvent (state
->have_stopped
);
490 if (!PeekNamedPipe (h
, NULL
, 0, NULL
, &n_avail
, NULL
))
492 SetEvent (state
->except_event
);
498 SetEvent (state
->read_event
);
502 /* Delay 10ms before checking again, but allow the stop event
504 if (WaitForSingleObject (state
->stop_select
, 10) == WAIT_OBJECT_0
)
512 file_select_thread (void *arg
)
514 struct serial
*scb
= arg
;
515 struct ser_console_state
*state
;
520 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
524 HANDLE wait_events
[2];
527 SetEvent (state
->have_stopped
);
529 wait_events
[0] = state
->start_select
;
530 wait_events
[1] = state
->exit_select
;
532 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
535 ResetEvent (state
->have_stopped
);
537 if (SetFilePointer (h
, 0, NULL
, FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
539 SetEvent (state
->except_event
);
543 SetEvent (state
->read_event
);
548 ser_console_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
550 struct ser_console_state
*state
= scb
->state
;
557 is_tty
= isatty (scb
->fd
);
558 if (!is_tty
&& !fd_is_file (scb
->fd
) && !fd_is_pipe (scb
->fd
))
565 state
= xmalloc (sizeof (struct ser_console_state
));
566 memset (state
, 0, sizeof (struct ser_console_state
));
569 /* Create auto reset events to wake, stop, and exit the select
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);
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);
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);
585 state
->thread
= CreateThread (NULL
, 0, console_select_thread
, scb
, 0,
587 else if (fd_is_pipe (scb
->fd
))
588 state
->thread
= CreateThread (NULL
, 0, pipe_select_thread
, scb
, 0,
591 state
->thread
= CreateThread (NULL
, 0, file_select_thread
, scb
, 0,
595 *read
= state
->read_event
;
596 *except
= state
->except_event
;
598 /* Start from a blank state. */
599 ResetEvent (state
->read_event
);
600 ResetEvent (state
->except_event
);
601 ResetEvent (state
->stop_select
);
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. */
610 SetEvent (state
->read_event
);
614 /* Otherwise, start the select thread. */
615 SetEvent (state
->start_select
);
619 ser_console_done_wait_handle (struct serial
*scb
)
621 struct ser_console_state
*state
= scb
->state
;
626 SetEvent (state
->stop_select
);
627 WaitForSingleObject (state
->have_stopped
, INFINITE
);
631 ser_console_close (struct serial
*scb
)
633 struct ser_console_state
*state
= scb
->state
;
637 SetEvent (state
->exit_select
);
639 WaitForSingleObject (state
->thread
, INFINITE
);
641 CloseHandle (state
->start_select
);
642 CloseHandle (state
->stop_select
);
643 CloseHandle (state
->exit_select
);
644 CloseHandle (state
->have_stopped
);
646 CloseHandle (state
->read_event
);
647 CloseHandle (state
->except_event
);
653 struct ser_console_ttystate
658 static serial_ttystate
659 ser_console_get_tty_state (struct serial
*scb
)
661 if (isatty (scb
->fd
))
663 struct ser_console_ttystate
*state
;
664 state
= (struct ser_console_ttystate
*) xmalloc (sizeof *state
);
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
677 struct ser_console_state wait
;
679 /* The pex obj for our (one-stage) pipeline. */
682 /* Streams for the pipeline's input and output. */
683 FILE *input
, *output
;
686 static struct pipe_state
*
687 make_pipe_state (void)
689 struct pipe_state
*ps
= XMALLOC (struct pipe_state
);
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
;
701 free_pipe_state (struct pipe_state
*ps
)
703 int saved_errno
= errno
;
705 if (ps
->wait
.read_event
!= INVALID_HANDLE_VALUE
)
707 SetEvent (ps
->wait
.exit_select
);
709 WaitForSingleObject (ps
->wait
.thread
, INFINITE
);
711 CloseHandle (ps
->wait
.start_select
);
712 CloseHandle (ps
->wait
.stop_select
);
713 CloseHandle (ps
->wait
.exit_select
);
714 CloseHandle (ps
->wait
.have_stopped
);
716 CloseHandle (ps
->wait
.read_event
);
717 CloseHandle (ps
->wait
.except_event
);
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. */
727 /* pex_free closes ps->output. */
735 cleanup_pipe_state (void *untyped
)
737 struct pipe_state
*ps
= untyped
;
739 free_pipe_state (ps
);
743 pipe_windows_open (struct serial
*scb
, const char *name
)
745 struct pipe_state
*ps
;
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");
754 ps
= make_pipe_state ();
755 make_cleanup (cleanup_pipe_state
, ps
);
757 ps
->pex
= pex_init (PEX_USE_PIPES
, "target remote pipe", NULL
);
760 ps
->input
= pex_input_pipe (ps
->pex
, 1);
767 = pex_run (ps
->pex
, PEX_SEARCH
| PEX_BINARY_INPUT
| PEX_BINARY_OUTPUT
768 | PEX_STDERR_TO_PIPE
,
769 argv
[0], argv
, NULL
, NULL
,
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. */
779 error ("error starting child process '%s': %s: %s",
780 name
, err_msg
, safe_strerror (err
));
782 error ("error starting child process '%s': %s",
787 ps
->output
= pex_read_output (ps
->pex
, 1);
790 scb
->fd
= fileno (ps
->output
);
792 pex_stderr
= pex_read_err (ps
->pex
, 1);
795 scb
->error_fd
= fileno (pex_stderr
);
797 scb
->state
= (void *) ps
;
799 discard_cleanups (back_to
);
803 do_cleanups (back_to
);
809 pipe_windows_close (struct serial
*scb
)
811 struct pipe_state
*ps
= scb
->state
;
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. */
817 free_pipe_state (ps
);
822 pipe_windows_read (struct serial
*scb
, size_t count
)
824 HANDLE pipeline_out
= (HANDLE
) _get_osfhandle (scb
->fd
);
828 if (pipeline_out
== INVALID_HANDLE_VALUE
)
831 if (! PeekNamedPipe (pipeline_out
, NULL
, 0, NULL
, &available
, NULL
))
834 if (count
> available
)
837 if (! ReadFile (pipeline_out
, scb
->buf
, count
, &bytes_read
, NULL
))
845 pipe_windows_write (struct serial
*scb
, const void *buf
, size_t count
)
847 struct pipe_state
*ps
= scb
->state
;
851 int pipeline_in_fd
= fileno (ps
->input
);
852 if (pipeline_in_fd
< 0)
855 pipeline_in
= (HANDLE
) _get_osfhandle (pipeline_in_fd
);
856 if (pipeline_in
== INVALID_HANDLE_VALUE
)
859 if (! WriteFile (pipeline_in
, buf
, count
, &written
, NULL
))
867 pipe_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
869 struct pipe_state
*ps
= scb
->state
;
871 /* Have we allocated our events yet? */
872 if (ps
->wait
.read_event
== INVALID_HANDLE_VALUE
)
876 /* Create auto reset events to wake, stop, and exit the select
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);
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);
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);
892 /* Start the select thread. */
893 CreateThread (NULL
, 0, pipe_select_thread
, scb
, 0, &threadId
);
896 *read
= ps
->wait
.read_event
;
897 *except
= ps
->wait
.except_event
;
899 /* Start from a blank state. */
900 ResetEvent (ps
->wait
.read_event
);
901 ResetEvent (ps
->wait
.except_event
);
902 ResetEvent (ps
->wait
.stop_select
);
904 /* Start the select thread. */
905 SetEvent (ps
->wait
.start_select
);
909 pipe_done_wait_handle (struct serial
*scb
)
911 struct pipe_state
*ps
= scb
->state
;
913 /* Have we allocated our events yet? */
914 if (ps
->wait
.read_event
== INVALID_HANDLE_VALUE
)
917 SetEvent (ps
->wait
.stop_select
);
918 WaitForSingleObject (ps
->wait
.have_stopped
, INFINITE
);
922 pipe_avail (struct serial
*scb
, int fd
)
924 HANDLE h
= (HANDLE
) _get_osfhandle (fd
);
926 BOOL r
= PeekNamedPipe (h
, NULL
, 0, NULL
, &numBytes
, NULL
);
932 struct net_windows_state
948 net_windows_select_thread (void *arg
)
950 struct serial
*scb
= arg
;
951 struct net_windows_state
*state
, state_copy
;
958 HANDLE wait_events
[2];
959 WSANETWORKEVENTS events
;
961 SetEvent (state
->have_stopped
);
963 wait_events
[0] = state
->start_select
;
964 wait_events
[1] = state
->exit_select
;
966 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
969 ResetEvent (state
->have_stopped
);
971 wait_events
[0] = state
->stop_select
;
972 wait_events
[1] = state
->sock_event
;
974 event_index
= WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
);
976 if (event_index
== WAIT_OBJECT_0
977 || WaitForSingleObject (state
->stop_select
, 0) == WAIT_OBJECT_0
)
980 if (event_index
!= WAIT_OBJECT_0
+ 1)
982 /* Some error has occured. Assume that this is an error
984 SetEvent (state
->except_event
);
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
);
992 gdb_assert (events
.lNetworkEvents
& (FD_READ
| FD_CLOSE
));
994 if (events
.lNetworkEvents
& FD_READ
)
995 SetEvent (state
->read_event
);
997 if (events
.lNetworkEvents
& FD_CLOSE
)
998 SetEvent (state
->except_event
);
1003 net_windows_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
1005 struct net_windows_state
*state
= scb
->state
;
1007 /* Start from a clean slate. */
1008 ResetEvent (state
->read_event
);
1009 ResetEvent (state
->except_event
);
1010 ResetEvent (state
->stop_select
);
1012 *read
= state
->read_event
;
1013 *except
= state
->except_event
;
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
)
1019 WSANETWORKEVENTS events
;
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
);
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. */
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
)
1040 unsigned long available
;
1042 if (ioctlsocket (scb
->fd
, FIONREAD
, &available
) == 0
1045 SetEvent (state
->read_event
);
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);
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
)
1059 SetEvent (state
->except_event
);
1063 /* If we set either handle, there's no need to wake the thread. */
1068 /* Start the select thread. */
1069 SetEvent (state
->start_select
);
1073 net_windows_done_wait_handle (struct serial
*scb
)
1075 struct net_windows_state
*state
= scb
->state
;
1077 SetEvent (state
->stop_select
);
1078 WaitForSingleObject (state
->have_stopped
, INFINITE
);
1082 net_windows_open (struct serial
*scb
, const char *name
)
1084 struct net_windows_state
*state
;
1088 ret
= net_open (scb
, name
);
1092 state
= xmalloc (sizeof (struct net_windows_state
));
1093 memset (state
, 0, sizeof (struct net_windows_state
));
1096 /* Create auto reset events to wake, stop, and exit the select
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);
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);
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
);
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);
1115 /* And finally start the select thread. */
1116 state
->thread
= CreateThread (NULL
, 0, net_windows_select_thread
, scb
, 0,
1124 net_windows_close (struct serial
*scb
)
1126 struct net_windows_state
*state
= scb
->state
;
1128 SetEvent (state
->exit_select
);
1129 WaitForSingleObject (state
->thread
, INFINITE
);
1131 CloseHandle (state
->read_event
);
1132 CloseHandle (state
->except_event
);
1134 CloseHandle (state
->start_select
);
1135 CloseHandle (state
->stop_select
);
1136 CloseHandle (state
->exit_select
);
1137 CloseHandle (state
->have_stopped
);
1139 CloseHandle (state
->sock_event
);
1147 _initialize_ser_windows (void)
1150 struct serial_ops
*ops
;
1152 /* First register the serial port driver. */
1154 ops
= XMALLOC (struct serial_ops
);
1155 memset (ops
, 0, sizeof (struct serial_ops
));
1156 ops
->name
= "hardwire";
1158 ops
->open
= ser_windows_open
;
1159 ops
->close
= ser_windows_close
;
1161 ops
->flush_output
= ser_windows_flush_output
;
1162 ops
->flush_input
= ser_windows_flush_input
;
1163 ops
->send_break
= ser_windows_send_break
;
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
;
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
;
1183 serial_add_interface (ops
);
1185 /* Next create the dummy serial driver used for terminals. We only
1186 provide the TTY-related methods. */
1188 ops
= XMALLOC (struct serial_ops
);
1189 memset (ops
, 0, sizeof (struct serial_ops
));
1191 ops
->name
= "terminal";
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
;
1203 serial_add_interface (ops
);
1205 /* The pipe interface. */
1207 ops
= XMALLOC (struct serial_ops
);
1208 memset (ops
, 0, sizeof (struct serial_ops
));
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
;
1233 serial_add_interface (ops
);
1235 /* If WinSock works, register the TCP/UDP socket driver. */
1237 if (WSAStartup (MAKEWORD (1, 0), &wsa_data
) != 0)
1238 /* WinSock is unavailable. */
1241 ops
= XMALLOC (struct serial_ops
);
1242 memset (ops
, 0, sizeof (struct serial_ops
));
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
);