1 /* Serial interface for local (hardwired) serial ports on Windows systems
4 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
33 #include <sys/types.h>
35 #include "gdb_assert.h"
36 #include "gdb_string.h"
38 void _initialize_ser_windows (void);
40 struct ser_windows_state
48 /* Open up a real live device for serial I/O. */
51 ser_windows_open (struct serial
*scb
, const char *name
)
54 struct ser_windows_state
*state
;
55 COMMTIMEOUTS timeouts
;
57 /* Only allow COM ports. */
58 if (strncmp (name
, "COM", 3) != 0)
64 h
= CreateFile (name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
65 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
66 if (h
== INVALID_HANDLE_VALUE
)
72 scb
->fd
= _open_osfhandle ((long) h
, O_RDWR
);
79 if (!SetCommMask (h
, EV_RXCHAR
))
85 timeouts
.ReadIntervalTimeout
= MAXDWORD
;
86 timeouts
.ReadTotalTimeoutConstant
= 0;
87 timeouts
.ReadTotalTimeoutMultiplier
= 0;
88 timeouts
.WriteTotalTimeoutConstant
= 0;
89 timeouts
.WriteTotalTimeoutMultiplier
= 0;
90 if (!SetCommTimeouts (h
, &timeouts
))
96 state
= xmalloc (sizeof (struct ser_windows_state
));
97 memset (state
, 0, sizeof (struct ser_windows_state
));
100 /* Create a manual reset event to watch the input buffer. */
101 state
->ov
.hEvent
= CreateEvent (0, TRUE
, FALSE
, 0);
103 /* Create a (currently unused) handle to record exceptions. */
104 state
->except_event
= CreateEvent (0, TRUE
, FALSE
, 0);
109 /* Wait for the output to drain away, as opposed to flushing (discarding)
113 ser_windows_drain_output (struct serial
*scb
)
115 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
117 return (FlushFileBuffers (h
) != 0) ? 0 : -1;
121 ser_windows_flush_output (struct serial
*scb
)
123 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
125 return (PurgeComm (h
, PURGE_TXCLEAR
) != 0) ? 0 : -1;
129 ser_windows_flush_input (struct serial
*scb
)
131 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
133 return (PurgeComm (h
, PURGE_RXCLEAR
) != 0) ? 0 : -1;
137 ser_windows_send_break (struct serial
*scb
)
139 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
141 if (SetCommBreak (h
) == 0)
144 /* Delay for 250 milliseconds. */
147 if (ClearCommBreak (h
))
154 ser_windows_raw (struct serial
*scb
)
156 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
159 if (GetCommState (h
, &state
) == 0)
162 state
.fParity
= FALSE
;
163 state
.fOutxCtsFlow
= FALSE
;
164 state
.fOutxDsrFlow
= FALSE
;
165 state
.fDtrControl
= DTR_CONTROL_ENABLE
;
166 state
.fDsrSensitivity
= FALSE
;
170 state
.fAbortOnError
= FALSE
;
172 state
.Parity
= NOPARITY
;
174 scb
->current_timeout
= 0;
176 if (SetCommState (h
, &state
) == 0)
177 warning (_("SetCommState failed\n"));
181 ser_windows_setstopbits (struct serial
*scb
, int num
)
183 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
186 if (GetCommState (h
, &state
) == 0)
191 case SERIAL_1_STOPBITS
:
192 state
.StopBits
= ONESTOPBIT
;
194 case SERIAL_1_AND_A_HALF_STOPBITS
:
195 state
.StopBits
= ONE5STOPBITS
;
197 case SERIAL_2_STOPBITS
:
198 state
.StopBits
= TWOSTOPBITS
;
204 return (SetCommState (h
, &state
) != 0) ? 0 : -1;
208 ser_windows_setbaudrate (struct serial
*scb
, int rate
)
210 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
213 if (GetCommState (h
, &state
) == 0)
216 state
.BaudRate
= rate
;
218 return (SetCommState (h
, &state
) != 0) ? 0 : -1;
222 ser_windows_close (struct serial
*scb
)
224 struct ser_windows_state
*state
;
226 /* Stop any pending selects. */
227 CancelIo ((HANDLE
) _get_osfhandle (scb
->fd
));
229 CloseHandle (state
->ov
.hEvent
);
230 CloseHandle (state
->except_event
);
242 ser_windows_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
244 struct ser_windows_state
*state
;
247 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
251 *except
= state
->except_event
;
252 *read
= state
->ov
.hEvent
;
254 if (state
->in_progress
)
257 /* Reset the mask - we are only interested in any characters which
258 arrive after this point, not characters which might have arrived
259 and already been read. */
261 /* This really, really shouldn't be necessary - just the second one.
262 But otherwise an internal flag for EV_RXCHAR does not get
263 cleared, and we get a duplicated event, if the last batch
264 of characters included at least two arriving close together. */
265 if (!SetCommMask (h
, 0))
266 warning (_("ser_windows_wait_handle: reseting mask failed"));
268 if (!SetCommMask (h
, EV_RXCHAR
))
269 warning (_("ser_windows_wait_handle: reseting mask failed (2)"));
271 /* There's a potential race condition here; we must check cbInQue
272 and not wait if that's nonzero. */
274 ClearCommError (h
, &errors
, &status
);
275 if (status
.cbInQue
> 0)
277 SetEvent (state
->ov
.hEvent
);
281 state
->in_progress
= 1;
282 ResetEvent (state
->ov
.hEvent
);
283 state
->lastCommMask
= -2;
284 if (WaitCommEvent (h
, &state
->lastCommMask
, &state
->ov
))
286 gdb_assert (state
->lastCommMask
& EV_RXCHAR
);
287 SetEvent (state
->ov
.hEvent
);
290 gdb_assert (GetLastError () == ERROR_IO_PENDING
);
294 ser_windows_read_prim (struct serial
*scb
, size_t count
)
296 struct ser_windows_state
*state
;
298 DWORD bytes_read
, bytes_read_tmp
;
303 if (state
->in_progress
)
305 WaitForSingleObject (state
->ov
.hEvent
, INFINITE
);
306 state
->in_progress
= 0;
307 ResetEvent (state
->ov
.hEvent
);
310 memset (&ov
, 0, sizeof (OVERLAPPED
));
311 ov
.hEvent
= CreateEvent (0, FALSE
, FALSE
, 0);
312 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
314 if (!ReadFile (h
, scb
->buf
, /* count */ 1, &bytes_read
, &ov
))
316 if (GetLastError () != ERROR_IO_PENDING
317 || !GetOverlappedResult (h
, &ov
, &bytes_read
, TRUE
))
321 CloseHandle (ov
.hEvent
);
326 ser_windows_write_prim (struct serial
*scb
, const void *buf
, size_t len
)
328 struct ser_windows_state
*state
;
333 memset (&ov
, 0, sizeof (OVERLAPPED
));
334 ov
.hEvent
= CreateEvent (0, FALSE
, FALSE
, 0);
335 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
336 if (!WriteFile (h
, buf
, len
, &bytes_written
, &ov
))
338 if (GetLastError () != ERROR_IO_PENDING
339 || !GetOverlappedResult (h
, &ov
, &bytes_written
, TRUE
))
343 CloseHandle (ov
.hEvent
);
344 return bytes_written
;
347 struct ser_console_state
361 console_select_thread (void *arg
)
363 struct serial
*scb
= arg
;
364 struct ser_console_state
*state
;
369 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
373 HANDLE wait_events
[2];
377 SetEvent (state
->have_stopped
);
379 wait_events
[0] = state
->start_select
;
380 wait_events
[1] = state
->exit_select
;
382 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
385 ResetEvent (state
->have_stopped
);
388 wait_events
[0] = state
->stop_select
;
391 event_index
= WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
);
393 if (event_index
== WAIT_OBJECT_0
394 || WaitForSingleObject (state
->stop_select
, 0) == WAIT_OBJECT_0
)
397 if (event_index
!= WAIT_OBJECT_0
+ 1)
399 /* Wait must have failed; assume an error has occured, e.g.
400 the handle has been closed. */
401 SetEvent (state
->except_event
);
405 /* We've got a pending event on the console. See if it's
407 if (!PeekConsoleInput (h
, &record
, 1, &n_records
) || n_records
!= 1)
409 /* Something went wrong. Maybe the console is gone. */
410 SetEvent (state
->except_event
);
414 if (record
.EventType
== KEY_EVENT
&& record
.Event
.KeyEvent
.bKeyDown
)
416 WORD keycode
= record
.Event
.KeyEvent
.wVirtualKeyCode
;
418 /* Ignore events containing only control keys. We must
419 recognize "enhanced" keys which we are interested in
420 reading via getch, if they do not map to ASCII. But we
421 do not want to report input available for e.g. the
422 control key alone. */
424 if (record
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0
425 || keycode
== VK_PRIOR
426 || keycode
== VK_NEXT
428 || keycode
== VK_HOME
429 || keycode
== VK_LEFT
431 || keycode
== VK_RIGHT
432 || keycode
== VK_DOWN
433 || keycode
== VK_INSERT
434 || keycode
== VK_DELETE
)
436 /* This is really a keypress. */
437 SetEvent (state
->read_event
);
442 /* Otherwise discard it and wait again. */
443 ReadConsoleInput (h
, &record
, 1, &n_records
);
451 if (PeekNamedPipe ((HANDLE
) _get_osfhandle (fd
), NULL
, 0, NULL
, NULL
, NULL
))
458 pipe_select_thread (void *arg
)
460 struct serial
*scb
= arg
;
461 struct ser_console_state
*state
;
466 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
470 HANDLE wait_events
[2];
473 SetEvent (state
->have_stopped
);
475 wait_events
[0] = state
->start_select
;
476 wait_events
[1] = state
->exit_select
;
478 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
481 ResetEvent (state
->have_stopped
);
484 if (!PeekNamedPipe (h
, NULL
, 0, NULL
, &n_avail
, NULL
))
486 SetEvent (state
->except_event
);
492 SetEvent (state
->read_event
);
496 /* Delay 10ms before checking again, but allow the stop event
498 if (WaitForSingleObject (state
->stop_select
, 10) == WAIT_OBJECT_0
)
506 ser_console_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
508 struct ser_console_state
*state
= scb
->state
;
515 is_tty
= isatty (scb
->fd
);
516 if (!is_tty
&& !fd_is_pipe (scb
->fd
))
523 state
= xmalloc (sizeof (struct ser_console_state
));
524 memset (state
, 0, sizeof (struct ser_console_state
));
527 /* Create auto reset events to wake, stop, and exit the select
529 state
->start_select
= CreateEvent (0, FALSE
, FALSE
, 0);
530 state
->stop_select
= CreateEvent (0, FALSE
, FALSE
, 0);
531 state
->exit_select
= CreateEvent (0, FALSE
, FALSE
, 0);
533 /* Create a manual reset event to signal whether the thread is
534 stopped. This must be manual reset, because we may wait on
535 it multiple times without ever starting the thread. */
536 state
->have_stopped
= CreateEvent (0, TRUE
, FALSE
, 0);
538 /* Create our own events to report read and exceptions separately. */
539 state
->read_event
= CreateEvent (0, FALSE
, FALSE
, 0);
540 state
->except_event
= CreateEvent (0, FALSE
, FALSE
, 0);
543 state
->thread
= CreateThread (NULL
, 0, console_select_thread
, scb
, 0,
546 state
->thread
= CreateThread (NULL
, 0, pipe_select_thread
, scb
, 0,
550 *read
= state
->read_event
;
551 *except
= state
->except_event
;
553 /* Start from a blank state. */
554 ResetEvent (state
->read_event
);
555 ResetEvent (state
->except_event
);
556 ResetEvent (state
->stop_select
);
558 /* First check for a key already in the buffer. If there is one,
559 we don't need a thread. This also catches the second key of
560 multi-character returns from getch, for instance for arrow
561 keys. The second half is in a C library internal buffer,
562 and PeekConsoleInput will not find it. */
565 SetEvent (state
->read_event
);
569 /* Otherwise, start the select thread. */
570 SetEvent (state
->start_select
);
574 ser_console_done_wait_handle (struct serial
*scb
)
576 struct ser_console_state
*state
= scb
->state
;
581 SetEvent (state
->stop_select
);
582 WaitForSingleObject (state
->have_stopped
, INFINITE
);
586 ser_console_close (struct serial
*scb
)
588 struct ser_console_state
*state
= scb
->state
;
592 SetEvent (state
->exit_select
);
594 WaitForSingleObject (state
->thread
, INFINITE
);
596 CloseHandle (state
->start_select
);
597 CloseHandle (state
->stop_select
);
598 CloseHandle (state
->exit_select
);
599 CloseHandle (state
->have_stopped
);
601 CloseHandle (state
->read_event
);
602 CloseHandle (state
->except_event
);
608 struct ser_console_ttystate
613 static serial_ttystate
614 ser_console_get_tty_state (struct serial
*scb
)
616 if (isatty (scb
->fd
))
618 struct ser_console_ttystate
*state
;
619 state
= (struct ser_console_ttystate
*) xmalloc (sizeof *state
);
629 /* Since we use the pipe_select_thread for our select emulation,
630 we need to place the state structure it requires at the front
632 struct ser_console_state wait
;
634 /* The pex obj for our (one-stage) pipeline. */
637 /* Streams for the pipeline's input and output. */
638 FILE *input
, *output
;
641 static struct pipe_state
*
642 make_pipe_state (void)
644 struct pipe_state
*ps
= XMALLOC (struct pipe_state
);
646 memset (ps
, 0, sizeof (*ps
));
647 ps
->wait
.read_event
= INVALID_HANDLE_VALUE
;
648 ps
->wait
.except_event
= INVALID_HANDLE_VALUE
;
649 ps
->wait
.start_select
= INVALID_HANDLE_VALUE
;
650 ps
->wait
.stop_select
= INVALID_HANDLE_VALUE
;
656 free_pipe_state (struct pipe_state
*ps
)
658 int saved_errno
= errno
;
660 if (ps
->wait
.read_event
!= INVALID_HANDLE_VALUE
)
662 SetEvent (ps
->wait
.exit_select
);
664 WaitForSingleObject (ps
->wait
.thread
, INFINITE
);
666 CloseHandle (ps
->wait
.start_select
);
667 CloseHandle (ps
->wait
.stop_select
);
668 CloseHandle (ps
->wait
.exit_select
);
669 CloseHandle (ps
->wait
.have_stopped
);
671 CloseHandle (ps
->wait
.read_event
);
672 CloseHandle (ps
->wait
.except_event
);
675 /* Close the pipe to the child. We must close the pipe before
676 calling pex_free because pex_free will wait for the child to exit
677 and the child will not exit until the pipe is closed. */
682 /* pex_free closes ps->output. */
690 cleanup_pipe_state (void *untyped
)
692 struct pipe_state
*ps
= untyped
;
694 free_pipe_state (ps
);
698 pipe_windows_open (struct serial
*scb
, const char *name
)
700 char **argv
= buildargv (name
);
701 struct cleanup
*back_to
= make_cleanup_freeargv (argv
);
702 if (! argv
[0] || argv
[0][0] == '\0')
703 error ("missing child command");
705 struct pipe_state
*ps
= make_pipe_state ();
706 make_cleanup (cleanup_pipe_state
, ps
);
708 ps
->pex
= pex_init (PEX_USE_PIPES
, "target remote pipe", NULL
);
711 ps
->input
= pex_input_pipe (ps
->pex
, 1);
718 = pex_run (ps
->pex
, PEX_SEARCH
| PEX_BINARY_INPUT
| PEX_BINARY_OUTPUT
,
719 argv
[0], argv
, NULL
, NULL
,
724 /* Our caller expects us to return -1, but all they'll do with
725 it generally is print the message based on errno. We have
726 all the same information here, plus err_msg provided by
727 pex_run, so we just raise the error here. */
729 error ("error starting child process '%s': %s: %s",
730 name
, err_msg
, safe_strerror (err
));
732 error ("error starting child process '%s': %s",
737 ps
->output
= pex_read_output (ps
->pex
, 1);
741 scb
->fd
= fileno (ps
->output
);
742 scb
->state
= (void *) ps
;
744 discard_cleanups (back_to
);
748 do_cleanups (back_to
);
754 pipe_windows_close (struct serial
*scb
)
756 struct pipe_state
*ps
= scb
->state
;
758 /* In theory, we should try to kill the subprocess here, but the pex
759 interface doesn't give us enough information to do that. Usually
760 closing the input pipe will get the message across. */
762 free_pipe_state (ps
);
767 pipe_windows_read (struct serial
*scb
, size_t count
)
769 HANDLE pipeline_out
= (HANDLE
) _get_osfhandle (scb
->fd
);
770 if (pipeline_out
== INVALID_HANDLE_VALUE
)
774 if (! PeekNamedPipe (pipeline_out
, NULL
, 0, NULL
, &available
, NULL
))
777 if (count
> available
)
781 if (! ReadFile (pipeline_out
, scb
->buf
, count
, &bytes_read
, NULL
))
789 pipe_windows_write (struct serial
*scb
, const void *buf
, size_t count
)
791 struct pipe_state
*ps
= scb
->state
;
792 int pipeline_in_fd
= fileno (ps
->input
);
793 if (pipeline_in_fd
< 0)
796 HANDLE pipeline_in
= (HANDLE
) _get_osfhandle (pipeline_in_fd
);
797 if (pipeline_in
== INVALID_HANDLE_VALUE
)
801 if (! WriteFile (pipeline_in
, buf
, count
, &written
, NULL
))
809 pipe_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
811 struct pipe_state
*ps
= scb
->state
;
813 /* Have we allocated our events yet? */
814 if (ps
->wait
.read_event
== INVALID_HANDLE_VALUE
)
818 /* Create auto reset events to wake, stop, and exit the select
820 ps
->wait
.start_select
= CreateEvent (0, FALSE
, FALSE
, 0);
821 ps
->wait
.stop_select
= CreateEvent (0, FALSE
, FALSE
, 0);
822 ps
->wait
.exit_select
= CreateEvent (0, FALSE
, FALSE
, 0);
824 /* Create a manual reset event to signal whether the thread is
825 stopped. This must be manual reset, because we may wait on
826 it multiple times without ever starting the thread. */
827 ps
->wait
.have_stopped
= CreateEvent (0, TRUE
, FALSE
, 0);
829 /* Create our own events to report read and exceptions separately.
830 The exception event is currently never used. */
831 ps
->wait
.read_event
= CreateEvent (0, FALSE
, FALSE
, 0);
832 ps
->wait
.except_event
= CreateEvent (0, FALSE
, FALSE
, 0);
834 /* Start the select thread. */
835 CreateThread (NULL
, 0, pipe_select_thread
, scb
, 0, &threadId
);
838 *read
= ps
->wait
.read_event
;
839 *except
= ps
->wait
.except_event
;
841 /* Start from a blank state. */
842 ResetEvent (ps
->wait
.read_event
);
843 ResetEvent (ps
->wait
.except_event
);
844 ResetEvent (ps
->wait
.stop_select
);
846 /* Start the select thread. */
847 SetEvent (ps
->wait
.start_select
);
851 pipe_done_wait_handle (struct serial
*scb
)
853 struct pipe_state
*ps
= scb
->state
;
855 /* Have we allocated our events yet? */
856 if (ps
->wait
.read_event
== INVALID_HANDLE_VALUE
)
859 SetEvent (ps
->wait
.stop_select
);
860 WaitForSingleObject (ps
->wait
.have_stopped
, INFINITE
);
863 struct net_windows_state
879 net_windows_select_thread (void *arg
)
881 struct serial
*scb
= arg
;
882 struct net_windows_state
*state
, state_copy
;
889 HANDLE wait_events
[2];
890 WSANETWORKEVENTS events
;
892 SetEvent (state
->have_stopped
);
894 wait_events
[0] = state
->start_select
;
895 wait_events
[1] = state
->exit_select
;
897 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
900 ResetEvent (state
->have_stopped
);
902 wait_events
[0] = state
->stop_select
;
903 wait_events
[1] = state
->sock_event
;
905 event_index
= WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
);
907 if (event_index
== WAIT_OBJECT_0
908 || WaitForSingleObject (state
->stop_select
, 0) == WAIT_OBJECT_0
)
911 if (event_index
!= WAIT_OBJECT_0
+ 1)
913 /* Some error has occured. Assume that this is an error
915 SetEvent (state
->except_event
);
919 /* Enumerate the internal network events, and reset the object that
920 signalled us to catch the next event. */
921 WSAEnumNetworkEvents (scb
->fd
, state
->sock_event
, &events
);
923 gdb_assert (events
.lNetworkEvents
& (FD_READ
| FD_CLOSE
));
925 if (events
.lNetworkEvents
& FD_READ
)
926 SetEvent (state
->read_event
);
928 if (events
.lNetworkEvents
& FD_CLOSE
)
929 SetEvent (state
->except_event
);
934 net_windows_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
936 struct net_windows_state
*state
= scb
->state
;
938 /* Start from a clean slate. */
939 ResetEvent (state
->read_event
);
940 ResetEvent (state
->except_event
);
941 ResetEvent (state
->stop_select
);
943 *read
= state
->read_event
;
944 *except
= state
->except_event
;
946 /* Check any pending events. This both avoids starting the thread
947 unnecessarily, and handles stray FD_READ events (see below). */
948 if (WaitForSingleObject (state
->sock_event
, 0) == WAIT_OBJECT_0
)
950 WSANETWORKEVENTS events
;
953 /* Enumerate the internal network events, and reset the object that
954 signalled us to catch the next event. */
955 WSAEnumNetworkEvents (scb
->fd
, state
->sock_event
, &events
);
957 /* You'd think that FD_READ or FD_CLOSE would be set here. But,
958 sometimes, neither is. I suspect that the FD_READ is set and
959 the corresponding event signalled while recv is running, and
960 the FD_READ is then lowered when recv consumes all the data,
961 but there's no way to un-signal the event. This isn't a
962 problem for the call in net_select_thread, since any new
963 events after this point will not have been drained by recv.
964 It just means that we can't have the obvious assert here. */
966 /* If there is a read event, it might be still valid, or it might
967 not be - it may have been signalled before we last called
968 recv. Double-check that there is data. */
969 if (events
.lNetworkEvents
& FD_READ
)
971 unsigned long available
;
973 if (ioctlsocket (scb
->fd
, FIONREAD
, &available
) == 0
976 SetEvent (state
->read_event
);
980 /* Oops, no data. This call to recv will cause future
981 data to retrigger the event, e.g. while we are
982 in net_select_thread. */
983 recv (scb
->fd
, NULL
, 0, 0);
986 /* If there's a close event, then record it - it is obviously
987 still valid, and it will not be resignalled. */
988 if (events
.lNetworkEvents
& FD_CLOSE
)
990 SetEvent (state
->except_event
);
994 /* If we set either handle, there's no need to wake the thread. */
999 /* Start the select thread. */
1000 SetEvent (state
->start_select
);
1004 net_windows_done_wait_handle (struct serial
*scb
)
1006 struct net_windows_state
*state
= scb
->state
;
1008 SetEvent (state
->stop_select
);
1009 WaitForSingleObject (state
->have_stopped
, INFINITE
);
1013 net_windows_open (struct serial
*scb
, const char *name
)
1015 struct net_windows_state
*state
;
1019 ret
= net_open (scb
, name
);
1023 state
= xmalloc (sizeof (struct net_windows_state
));
1024 memset (state
, 0, sizeof (struct net_windows_state
));
1027 /* Create auto reset events to wake, stop, and exit the select
1029 state
->start_select
= CreateEvent (0, FALSE
, FALSE
, 0);
1030 state
->stop_select
= CreateEvent (0, FALSE
, FALSE
, 0);
1031 state
->exit_select
= CreateEvent (0, FALSE
, FALSE
, 0);
1033 /* Create a manual reset event to signal whether the thread is
1034 stopped. This must be manual reset, because we may wait on
1035 it multiple times without ever starting the thread. */
1036 state
->have_stopped
= CreateEvent (0, TRUE
, FALSE
, 0);
1038 /* Associate an event with the socket. */
1039 state
->sock_event
= CreateEvent (0, TRUE
, FALSE
, 0);
1040 WSAEventSelect (scb
->fd
, state
->sock_event
, FD_READ
| FD_CLOSE
);
1042 /* Create our own events to report read and close separately. */
1043 state
->read_event
= CreateEvent (0, FALSE
, FALSE
, 0);
1044 state
->except_event
= CreateEvent (0, FALSE
, FALSE
, 0);
1046 /* And finally start the select thread. */
1047 state
->thread
= CreateThread (NULL
, 0, net_windows_select_thread
, scb
, 0,
1055 net_windows_close (struct serial
*scb
)
1057 struct net_windows_state
*state
= scb
->state
;
1059 SetEvent (state
->exit_select
);
1060 WaitForSingleObject (state
->thread
, INFINITE
);
1062 CloseHandle (state
->read_event
);
1063 CloseHandle (state
->except_event
);
1065 CloseHandle (state
->start_select
);
1066 CloseHandle (state
->stop_select
);
1067 CloseHandle (state
->exit_select
);
1068 CloseHandle (state
->have_stopped
);
1070 CloseHandle (state
->sock_event
);
1078 _initialize_ser_windows (void)
1081 struct serial_ops
*ops
;
1083 /* First register the serial port driver. */
1085 ops
= XMALLOC (struct serial_ops
);
1086 memset (ops
, 0, sizeof (struct serial_ops
));
1087 ops
->name
= "hardwire";
1089 ops
->open
= ser_windows_open
;
1090 ops
->close
= ser_windows_close
;
1092 ops
->flush_output
= ser_windows_flush_output
;
1093 ops
->flush_input
= ser_windows_flush_input
;
1094 ops
->send_break
= ser_windows_send_break
;
1096 /* These are only used for stdin; we do not need them for serial
1097 ports, so supply the standard dummies. */
1098 ops
->get_tty_state
= ser_base_get_tty_state
;
1099 ops
->set_tty_state
= ser_base_set_tty_state
;
1100 ops
->print_tty_state
= ser_base_print_tty_state
;
1101 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1103 ops
->go_raw
= ser_windows_raw
;
1104 ops
->setbaudrate
= ser_windows_setbaudrate
;
1105 ops
->setstopbits
= ser_windows_setstopbits
;
1106 ops
->drain_output
= ser_windows_drain_output
;
1107 ops
->readchar
= ser_base_readchar
;
1108 ops
->write
= ser_base_write
;
1109 ops
->async
= ser_base_async
;
1110 ops
->read_prim
= ser_windows_read_prim
;
1111 ops
->write_prim
= ser_windows_write_prim
;
1112 ops
->wait_handle
= ser_windows_wait_handle
;
1114 serial_add_interface (ops
);
1116 /* Next create the dummy serial driver used for terminals. We only
1117 provide the TTY-related methods. */
1119 ops
= XMALLOC (struct serial_ops
);
1120 memset (ops
, 0, sizeof (struct serial_ops
));
1122 ops
->name
= "terminal";
1125 ops
->close
= ser_console_close
;
1126 ops
->get_tty_state
= ser_console_get_tty_state
;
1127 ops
->set_tty_state
= ser_base_set_tty_state
;
1128 ops
->print_tty_state
= ser_base_print_tty_state
;
1129 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1130 ops
->drain_output
= ser_base_drain_output
;
1131 ops
->wait_handle
= ser_console_wait_handle
;
1132 ops
->done_wait_handle
= ser_console_done_wait_handle
;
1134 serial_add_interface (ops
);
1136 /* The pipe interface. */
1138 ops
= XMALLOC (struct serial_ops
);
1139 memset (ops
, 0, sizeof (struct serial_ops
));
1142 ops
->open
= pipe_windows_open
;
1143 ops
->close
= pipe_windows_close
;
1144 ops
->readchar
= ser_base_readchar
;
1145 ops
->write
= ser_base_write
;
1146 ops
->flush_output
= ser_base_flush_output
;
1147 ops
->flush_input
= ser_base_flush_input
;
1148 ops
->send_break
= ser_base_send_break
;
1149 ops
->go_raw
= ser_base_raw
;
1150 ops
->get_tty_state
= ser_base_get_tty_state
;
1151 ops
->set_tty_state
= ser_base_set_tty_state
;
1152 ops
->print_tty_state
= ser_base_print_tty_state
;
1153 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1154 ops
->setbaudrate
= ser_base_setbaudrate
;
1155 ops
->setstopbits
= ser_base_setstopbits
;
1156 ops
->drain_output
= ser_base_drain_output
;
1157 ops
->async
= ser_base_async
;
1158 ops
->read_prim
= pipe_windows_read
;
1159 ops
->write_prim
= pipe_windows_write
;
1160 ops
->wait_handle
= pipe_wait_handle
;
1161 ops
->done_wait_handle
= pipe_done_wait_handle
;
1163 serial_add_interface (ops
);
1165 /* If WinSock works, register the TCP/UDP socket driver. */
1167 if (WSAStartup (MAKEWORD (1, 0), &wsa_data
) != 0)
1168 /* WinSock is unavailable. */
1171 ops
= XMALLOC (struct serial_ops
);
1172 memset (ops
, 0, sizeof (struct serial_ops
));
1175 ops
->open
= net_windows_open
;
1176 ops
->close
= net_windows_close
;
1177 ops
->readchar
= ser_base_readchar
;
1178 ops
->write
= ser_base_write
;
1179 ops
->flush_output
= ser_base_flush_output
;
1180 ops
->flush_input
= ser_base_flush_input
;
1181 ops
->send_break
= ser_base_send_break
;
1182 ops
->go_raw
= ser_base_raw
;
1183 ops
->get_tty_state
= ser_base_get_tty_state
;
1184 ops
->set_tty_state
= ser_base_set_tty_state
;
1185 ops
->print_tty_state
= ser_base_print_tty_state
;
1186 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1187 ops
->setbaudrate
= ser_base_setbaudrate
;
1188 ops
->setstopbits
= ser_base_setstopbits
;
1189 ops
->drain_output
= ser_base_drain_output
;
1190 ops
->async
= ser_base_async
;
1191 ops
->read_prim
= net_read_prim
;
1192 ops
->write_prim
= net_write_prim
;
1193 ops
->wait_handle
= net_windows_wait_handle
;
1194 ops
->done_wait_handle
= net_windows_done_wait_handle
;
1195 serial_add_interface (ops
);