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 2 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, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
32 #include <sys/types.h>
34 #include "gdb_assert.h"
35 #include "gdb_string.h"
37 void _initialize_ser_windows (void);
39 struct ser_windows_state
47 /* Open up a real live device for serial I/O. */
50 ser_windows_open (struct serial
*scb
, const char *name
)
53 struct ser_windows_state
*state
;
54 COMMTIMEOUTS timeouts
;
56 /* Only allow COM ports. */
57 if (strncmp (name
, "COM", 3) != 0)
63 h
= CreateFile (name
, GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
64 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
65 if (h
== INVALID_HANDLE_VALUE
)
71 scb
->fd
= _open_osfhandle ((long) h
, O_RDWR
);
78 if (!SetCommMask (h
, EV_RXCHAR
))
84 timeouts
.ReadIntervalTimeout
= MAXDWORD
;
85 timeouts
.ReadTotalTimeoutConstant
= 0;
86 timeouts
.ReadTotalTimeoutMultiplier
= 0;
87 timeouts
.WriteTotalTimeoutConstant
= 0;
88 timeouts
.WriteTotalTimeoutMultiplier
= 0;
89 if (!SetCommTimeouts (h
, &timeouts
))
95 state
= xmalloc (sizeof (struct ser_windows_state
));
96 memset (state
, 0, sizeof (struct ser_windows_state
));
99 /* Create a manual reset event to watch the input buffer. */
100 state
->ov
.hEvent
= CreateEvent (0, TRUE
, FALSE
, 0);
102 /* Create a (currently unused) handle to record exceptions. */
103 state
->except_event
= CreateEvent (0, TRUE
, FALSE
, 0);
108 /* Wait for the output to drain away, as opposed to flushing (discarding)
112 ser_windows_drain_output (struct serial
*scb
)
114 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
116 return (FlushFileBuffers (h
) != 0) ? 0 : -1;
120 ser_windows_flush_output (struct serial
*scb
)
122 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
124 return (PurgeComm (h
, PURGE_TXCLEAR
) != 0) ? 0 : -1;
128 ser_windows_flush_input (struct serial
*scb
)
130 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
132 return (PurgeComm (h
, PURGE_RXCLEAR
) != 0) ? 0 : -1;
136 ser_windows_send_break (struct serial
*scb
)
138 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
140 if (SetCommBreak (h
) == 0)
143 /* Delay for 250 milliseconds. */
146 if (ClearCommBreak (h
))
153 ser_windows_raw (struct serial
*scb
)
155 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
158 if (GetCommState (h
, &state
) == 0)
161 state
.fParity
= FALSE
;
162 state
.fOutxCtsFlow
= FALSE
;
163 state
.fOutxDsrFlow
= FALSE
;
164 state
.fDtrControl
= DTR_CONTROL_ENABLE
;
165 state
.fDsrSensitivity
= FALSE
;
169 state
.fAbortOnError
= FALSE
;
171 state
.Parity
= NOPARITY
;
173 scb
->current_timeout
= 0;
175 if (SetCommState (h
, &state
) == 0)
176 warning (_("SetCommState failed\n"));
180 ser_windows_setstopbits (struct serial
*scb
, int num
)
182 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
185 if (GetCommState (h
, &state
) == 0)
190 case SERIAL_1_STOPBITS
:
191 state
.StopBits
= ONESTOPBIT
;
193 case SERIAL_1_AND_A_HALF_STOPBITS
:
194 state
.StopBits
= ONE5STOPBITS
;
196 case SERIAL_2_STOPBITS
:
197 state
.StopBits
= TWOSTOPBITS
;
203 return (SetCommState (h
, &state
) != 0) ? 0 : -1;
207 ser_windows_setbaudrate (struct serial
*scb
, int rate
)
209 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
212 if (GetCommState (h
, &state
) == 0)
215 state
.BaudRate
= rate
;
217 return (SetCommState (h
, &state
) != 0) ? 0 : -1;
221 ser_windows_close (struct serial
*scb
)
223 struct ser_windows_state
*state
;
225 /* Stop any pending selects. */
226 CancelIo ((HANDLE
) _get_osfhandle (scb
->fd
));
228 CloseHandle (state
->ov
.hEvent
);
229 CloseHandle (state
->except_event
);
241 ser_windows_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
243 struct ser_windows_state
*state
;
246 HANDLE h
= (HANDLE
) _get_osfhandle (scb
->fd
);
250 *except
= state
->except_event
;
251 *read
= state
->ov
.hEvent
;
253 if (state
->in_progress
)
256 /* Reset the mask - we are only interested in any characters which
257 arrive after this point, not characters which might have arrived
258 and already been read. */
260 /* This really, really shouldn't be necessary - just the second one.
261 But otherwise an internal flag for EV_RXCHAR does not get
262 cleared, and we get a duplicated event, if the last batch
263 of characters included at least two arriving close together. */
264 if (!SetCommMask (h
, 0))
265 warning (_("ser_windows_wait_handle: reseting mask failed"));
267 if (!SetCommMask (h
, EV_RXCHAR
))
268 warning (_("ser_windows_wait_handle: reseting mask failed (2)"));
270 /* There's a potential race condition here; we must check cbInQue
271 and not wait if that's nonzero. */
273 ClearCommError (h
, &errors
, &status
);
274 if (status
.cbInQue
> 0)
276 SetEvent (state
->ov
.hEvent
);
280 state
->in_progress
= 1;
281 ResetEvent (state
->ov
.hEvent
);
282 state
->lastCommMask
= -2;
283 if (WaitCommEvent (h
, &state
->lastCommMask
, &state
->ov
))
285 gdb_assert (state
->lastCommMask
& EV_RXCHAR
);
286 SetEvent (state
->ov
.hEvent
);
289 gdb_assert (GetLastError () == ERROR_IO_PENDING
);
293 ser_windows_read_prim (struct serial
*scb
, size_t count
)
295 struct ser_windows_state
*state
;
297 DWORD bytes_read
, bytes_read_tmp
;
302 if (state
->in_progress
)
304 WaitForSingleObject (state
->ov
.hEvent
, INFINITE
);
305 state
->in_progress
= 0;
306 ResetEvent (state
->ov
.hEvent
);
309 memset (&ov
, 0, sizeof (OVERLAPPED
));
310 ov
.hEvent
= CreateEvent (0, FALSE
, FALSE
, 0);
311 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
313 if (!ReadFile (h
, scb
->buf
, /* count */ 1, &bytes_read
, &ov
))
315 if (GetLastError () != ERROR_IO_PENDING
316 || !GetOverlappedResult (h
, &ov
, &bytes_read
, TRUE
))
320 CloseHandle (ov
.hEvent
);
325 ser_windows_write_prim (struct serial
*scb
, const void *buf
, size_t len
)
327 struct ser_windows_state
*state
;
332 memset (&ov
, 0, sizeof (OVERLAPPED
));
333 ov
.hEvent
= CreateEvent (0, FALSE
, FALSE
, 0);
334 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
335 if (!WriteFile (h
, buf
, len
, &bytes_written
, &ov
))
337 if (GetLastError () != ERROR_IO_PENDING
338 || !GetOverlappedResult (h
, &ov
, &bytes_written
, TRUE
))
342 CloseHandle (ov
.hEvent
);
343 return bytes_written
;
346 struct ser_console_state
360 console_select_thread (void *arg
)
362 struct serial
*scb
= arg
;
363 struct ser_console_state
*state
;
368 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
372 HANDLE wait_events
[2];
376 SetEvent (state
->have_stopped
);
378 wait_events
[0] = state
->start_select
;
379 wait_events
[1] = state
->exit_select
;
381 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
384 ResetEvent (state
->have_stopped
);
387 wait_events
[0] = state
->stop_select
;
390 event_index
= WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
);
392 if (event_index
== WAIT_OBJECT_0
393 || WaitForSingleObject (state
->stop_select
, 0) == WAIT_OBJECT_0
)
396 if (event_index
!= WAIT_OBJECT_0
+ 1)
398 /* Wait must have failed; assume an error has occured, e.g.
399 the handle has been closed. */
400 SetEvent (state
->except_event
);
404 /* We've got a pending event on the console. See if it's
406 if (!PeekConsoleInput (h
, &record
, 1, &n_records
) || n_records
!= 1)
408 /* Something went wrong. Maybe the console is gone. */
409 SetEvent (state
->except_event
);
413 if (record
.EventType
== KEY_EVENT
&& record
.Event
.KeyEvent
.bKeyDown
)
415 WORD keycode
= record
.Event
.KeyEvent
.wVirtualKeyCode
;
417 /* Ignore events containing only control keys. We must
418 recognize "enhanced" keys which we are interested in
419 reading via getch, if they do not map to ASCII. But we
420 do not want to report input available for e.g. the
421 control key alone. */
423 if (record
.Event
.KeyEvent
.uChar
.AsciiChar
!= 0
424 || keycode
== VK_PRIOR
425 || keycode
== VK_NEXT
427 || keycode
== VK_HOME
428 || keycode
== VK_LEFT
430 || keycode
== VK_RIGHT
431 || keycode
== VK_DOWN
432 || keycode
== VK_INSERT
433 || keycode
== VK_DELETE
)
435 /* This is really a keypress. */
436 SetEvent (state
->read_event
);
441 /* Otherwise discard it and wait again. */
442 ReadConsoleInput (h
, &record
, 1, &n_records
);
450 if (PeekNamedPipe ((HANDLE
) _get_osfhandle (fd
), NULL
, 0, NULL
, NULL
, NULL
))
459 if (GetFileType ((HANDLE
) _get_osfhandle (fd
)) == FILE_TYPE_DISK
)
466 pipe_select_thread (void *arg
)
468 struct serial
*scb
= arg
;
469 struct ser_console_state
*state
;
474 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
478 HANDLE wait_events
[2];
481 SetEvent (state
->have_stopped
);
483 wait_events
[0] = state
->start_select
;
484 wait_events
[1] = state
->exit_select
;
486 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
489 ResetEvent (state
->have_stopped
);
492 if (!PeekNamedPipe (h
, NULL
, 0, NULL
, &n_avail
, NULL
))
494 SetEvent (state
->except_event
);
500 SetEvent (state
->read_event
);
504 /* Delay 10ms before checking again, but allow the stop event
506 if (WaitForSingleObject (state
->stop_select
, 10) == WAIT_OBJECT_0
)
514 file_select_thread (void *arg
)
516 struct serial
*scb
= arg
;
517 struct ser_console_state
*state
;
522 h
= (HANDLE
) _get_osfhandle (scb
->fd
);
526 HANDLE wait_events
[2];
529 SetEvent (state
->have_stopped
);
531 wait_events
[0] = state
->start_select
;
532 wait_events
[1] = state
->exit_select
;
534 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
537 ResetEvent (state
->have_stopped
);
539 if (SetFilePointer (h
, 0, NULL
, FILE_CURRENT
) == INVALID_SET_FILE_POINTER
)
541 SetEvent (state
->except_event
);
545 SetEvent (state
->read_event
);
550 ser_console_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
552 struct ser_console_state
*state
= scb
->state
;
559 is_tty
= isatty (scb
->fd
);
560 if (!is_tty
&& !fd_is_file (scb
->fd
) && !fd_is_pipe (scb
->fd
))
567 state
= xmalloc (sizeof (struct ser_console_state
));
568 memset (state
, 0, sizeof (struct ser_console_state
));
571 /* Create auto reset events to wake, stop, and exit the select
573 state
->start_select
= CreateEvent (0, FALSE
, FALSE
, 0);
574 state
->stop_select
= CreateEvent (0, FALSE
, FALSE
, 0);
575 state
->exit_select
= CreateEvent (0, FALSE
, FALSE
, 0);
577 /* Create a manual reset event to signal whether the thread is
578 stopped. This must be manual reset, because we may wait on
579 it multiple times without ever starting the thread. */
580 state
->have_stopped
= CreateEvent (0, TRUE
, FALSE
, 0);
582 /* Create our own events to report read and exceptions separately. */
583 state
->read_event
= CreateEvent (0, FALSE
, FALSE
, 0);
584 state
->except_event
= CreateEvent (0, FALSE
, FALSE
, 0);
587 state
->thread
= CreateThread (NULL
, 0, console_select_thread
, scb
, 0,
589 else if (fd_is_pipe (scb
->fd
))
590 state
->thread
= CreateThread (NULL
, 0, pipe_select_thread
, scb
, 0,
593 state
->thread
= CreateThread (NULL
, 0, file_select_thread
, scb
, 0,
597 *read
= state
->read_event
;
598 *except
= state
->except_event
;
600 /* Start from a blank state. */
601 ResetEvent (state
->read_event
);
602 ResetEvent (state
->except_event
);
603 ResetEvent (state
->stop_select
);
605 /* First check for a key already in the buffer. If there is one,
606 we don't need a thread. This also catches the second key of
607 multi-character returns from getch, for instance for arrow
608 keys. The second half is in a C library internal buffer,
609 and PeekConsoleInput will not find it. */
612 SetEvent (state
->read_event
);
616 /* Otherwise, start the select thread. */
617 SetEvent (state
->start_select
);
621 ser_console_done_wait_handle (struct serial
*scb
)
623 struct ser_console_state
*state
= scb
->state
;
628 SetEvent (state
->stop_select
);
629 WaitForSingleObject (state
->have_stopped
, INFINITE
);
633 ser_console_close (struct serial
*scb
)
635 struct ser_console_state
*state
= scb
->state
;
639 SetEvent (state
->exit_select
);
641 WaitForSingleObject (state
->thread
, INFINITE
);
643 CloseHandle (state
->start_select
);
644 CloseHandle (state
->stop_select
);
645 CloseHandle (state
->exit_select
);
646 CloseHandle (state
->have_stopped
);
648 CloseHandle (state
->read_event
);
649 CloseHandle (state
->except_event
);
655 struct ser_console_ttystate
660 static serial_ttystate
661 ser_console_get_tty_state (struct serial
*scb
)
663 if (isatty (scb
->fd
))
665 struct ser_console_ttystate
*state
;
666 state
= (struct ser_console_ttystate
*) xmalloc (sizeof *state
);
676 /* Since we use the pipe_select_thread for our select emulation,
677 we need to place the state structure it requires at the front
679 struct ser_console_state wait
;
681 /* The pex obj for our (one-stage) pipeline. */
684 /* Streams for the pipeline's input and output. */
685 FILE *input
, *output
;
688 static struct pipe_state
*
689 make_pipe_state (void)
691 struct pipe_state
*ps
= XMALLOC (struct pipe_state
);
693 memset (ps
, 0, sizeof (*ps
));
694 ps
->wait
.read_event
= INVALID_HANDLE_VALUE
;
695 ps
->wait
.except_event
= INVALID_HANDLE_VALUE
;
696 ps
->wait
.start_select
= INVALID_HANDLE_VALUE
;
697 ps
->wait
.stop_select
= INVALID_HANDLE_VALUE
;
703 free_pipe_state (struct pipe_state
*ps
)
705 int saved_errno
= errno
;
707 if (ps
->wait
.read_event
!= INVALID_HANDLE_VALUE
)
709 SetEvent (ps
->wait
.exit_select
);
711 WaitForSingleObject (ps
->wait
.thread
, INFINITE
);
713 CloseHandle (ps
->wait
.start_select
);
714 CloseHandle (ps
->wait
.stop_select
);
715 CloseHandle (ps
->wait
.exit_select
);
716 CloseHandle (ps
->wait
.have_stopped
);
718 CloseHandle (ps
->wait
.read_event
);
719 CloseHandle (ps
->wait
.except_event
);
722 /* Close the pipe to the child. We must close the pipe before
723 calling pex_free because pex_free will wait for the child to exit
724 and the child will not exit until the pipe is closed. */
729 /* pex_free closes ps->output. */
737 cleanup_pipe_state (void *untyped
)
739 struct pipe_state
*ps
= untyped
;
741 free_pipe_state (ps
);
745 pipe_windows_open (struct serial
*scb
, const char *name
)
747 struct pipe_state
*ps
;
750 char **argv
= buildargv (name
);
751 struct cleanup
*back_to
= make_cleanup_freeargv (argv
);
752 if (! argv
[0] || argv
[0][0] == '\0')
753 error ("missing child command");
756 ps
= make_pipe_state ();
757 make_cleanup (cleanup_pipe_state
, ps
);
759 ps
->pex
= pex_init (PEX_USE_PIPES
, "target remote pipe", NULL
);
762 ps
->input
= pex_input_pipe (ps
->pex
, 1);
769 = pex_run (ps
->pex
, PEX_SEARCH
| PEX_BINARY_INPUT
| PEX_BINARY_OUTPUT
770 | PEX_STDERR_TO_PIPE
,
771 argv
[0], argv
, NULL
, NULL
,
776 /* Our caller expects us to return -1, but all they'll do with
777 it generally is print the message based on errno. We have
778 all the same information here, plus err_msg provided by
779 pex_run, so we just raise the error here. */
781 error ("error starting child process '%s': %s: %s",
782 name
, err_msg
, safe_strerror (err
));
784 error ("error starting child process '%s': %s",
789 ps
->output
= pex_read_output (ps
->pex
, 1);
792 scb
->fd
= fileno (ps
->output
);
794 pex_stderr
= pex_read_err (ps
->pex
, 1);
797 scb
->error_fd
= fileno (pex_stderr
);
799 scb
->state
= (void *) ps
;
801 discard_cleanups (back_to
);
805 do_cleanups (back_to
);
811 pipe_windows_close (struct serial
*scb
)
813 struct pipe_state
*ps
= scb
->state
;
815 /* In theory, we should try to kill the subprocess here, but the pex
816 interface doesn't give us enough information to do that. Usually
817 closing the input pipe will get the message across. */
819 free_pipe_state (ps
);
824 pipe_windows_read (struct serial
*scb
, size_t count
)
826 HANDLE pipeline_out
= (HANDLE
) _get_osfhandle (scb
->fd
);
830 if (pipeline_out
== INVALID_HANDLE_VALUE
)
833 if (! PeekNamedPipe (pipeline_out
, NULL
, 0, NULL
, &available
, NULL
))
836 if (count
> available
)
839 if (! ReadFile (pipeline_out
, scb
->buf
, count
, &bytes_read
, NULL
))
847 pipe_windows_write (struct serial
*scb
, const void *buf
, size_t count
)
849 struct pipe_state
*ps
= scb
->state
;
853 int pipeline_in_fd
= fileno (ps
->input
);
854 if (pipeline_in_fd
< 0)
857 pipeline_in
= (HANDLE
) _get_osfhandle (pipeline_in_fd
);
858 if (pipeline_in
== INVALID_HANDLE_VALUE
)
861 if (! WriteFile (pipeline_in
, buf
, count
, &written
, NULL
))
869 pipe_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
871 struct pipe_state
*ps
= scb
->state
;
873 /* Have we allocated our events yet? */
874 if (ps
->wait
.read_event
== INVALID_HANDLE_VALUE
)
878 /* Create auto reset events to wake, stop, and exit the select
880 ps
->wait
.start_select
= CreateEvent (0, FALSE
, FALSE
, 0);
881 ps
->wait
.stop_select
= CreateEvent (0, FALSE
, FALSE
, 0);
882 ps
->wait
.exit_select
= CreateEvent (0, FALSE
, FALSE
, 0);
884 /* Create a manual reset event to signal whether the thread is
885 stopped. This must be manual reset, because we may wait on
886 it multiple times without ever starting the thread. */
887 ps
->wait
.have_stopped
= CreateEvent (0, TRUE
, FALSE
, 0);
889 /* Create our own events to report read and exceptions separately.
890 The exception event is currently never used. */
891 ps
->wait
.read_event
= CreateEvent (0, FALSE
, FALSE
, 0);
892 ps
->wait
.except_event
= CreateEvent (0, FALSE
, FALSE
, 0);
894 /* Start the select thread. */
895 CreateThread (NULL
, 0, pipe_select_thread
, scb
, 0, &threadId
);
898 *read
= ps
->wait
.read_event
;
899 *except
= ps
->wait
.except_event
;
901 /* Start from a blank state. */
902 ResetEvent (ps
->wait
.read_event
);
903 ResetEvent (ps
->wait
.except_event
);
904 ResetEvent (ps
->wait
.stop_select
);
906 /* Start the select thread. */
907 SetEvent (ps
->wait
.start_select
);
911 pipe_done_wait_handle (struct serial
*scb
)
913 struct pipe_state
*ps
= scb
->state
;
915 /* Have we allocated our events yet? */
916 if (ps
->wait
.read_event
== INVALID_HANDLE_VALUE
)
919 SetEvent (ps
->wait
.stop_select
);
920 WaitForSingleObject (ps
->wait
.have_stopped
, INFINITE
);
924 pipe_avail (struct serial
*scb
, int fd
)
926 HANDLE h
= (HANDLE
) _get_osfhandle (fd
);
928 BOOL r
= PeekNamedPipe (h
, NULL
, 0, NULL
, &numBytes
, NULL
);
934 struct net_windows_state
950 net_windows_select_thread (void *arg
)
952 struct serial
*scb
= arg
;
953 struct net_windows_state
*state
, state_copy
;
960 HANDLE wait_events
[2];
961 WSANETWORKEVENTS events
;
963 SetEvent (state
->have_stopped
);
965 wait_events
[0] = state
->start_select
;
966 wait_events
[1] = state
->exit_select
;
968 if (WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
) != WAIT_OBJECT_0
)
971 ResetEvent (state
->have_stopped
);
973 wait_events
[0] = state
->stop_select
;
974 wait_events
[1] = state
->sock_event
;
976 event_index
= WaitForMultipleObjects (2, wait_events
, FALSE
, INFINITE
);
978 if (event_index
== WAIT_OBJECT_0
979 || WaitForSingleObject (state
->stop_select
, 0) == WAIT_OBJECT_0
)
982 if (event_index
!= WAIT_OBJECT_0
+ 1)
984 /* Some error has occured. Assume that this is an error
986 SetEvent (state
->except_event
);
990 /* Enumerate the internal network events, and reset the object that
991 signalled us to catch the next event. */
992 WSAEnumNetworkEvents (scb
->fd
, state
->sock_event
, &events
);
994 gdb_assert (events
.lNetworkEvents
& (FD_READ
| FD_CLOSE
));
996 if (events
.lNetworkEvents
& FD_READ
)
997 SetEvent (state
->read_event
);
999 if (events
.lNetworkEvents
& FD_CLOSE
)
1000 SetEvent (state
->except_event
);
1005 net_windows_wait_handle (struct serial
*scb
, HANDLE
*read
, HANDLE
*except
)
1007 struct net_windows_state
*state
= scb
->state
;
1009 /* Start from a clean slate. */
1010 ResetEvent (state
->read_event
);
1011 ResetEvent (state
->except_event
);
1012 ResetEvent (state
->stop_select
);
1014 *read
= state
->read_event
;
1015 *except
= state
->except_event
;
1017 /* Check any pending events. This both avoids starting the thread
1018 unnecessarily, and handles stray FD_READ events (see below). */
1019 if (WaitForSingleObject (state
->sock_event
, 0) == WAIT_OBJECT_0
)
1021 WSANETWORKEVENTS events
;
1024 /* Enumerate the internal network events, and reset the object that
1025 signalled us to catch the next event. */
1026 WSAEnumNetworkEvents (scb
->fd
, state
->sock_event
, &events
);
1028 /* You'd think that FD_READ or FD_CLOSE would be set here. But,
1029 sometimes, neither is. I suspect that the FD_READ is set and
1030 the corresponding event signalled while recv is running, and
1031 the FD_READ is then lowered when recv consumes all the data,
1032 but there's no way to un-signal the event. This isn't a
1033 problem for the call in net_select_thread, since any new
1034 events after this point will not have been drained by recv.
1035 It just means that we can't have the obvious assert here. */
1037 /* If there is a read event, it might be still valid, or it might
1038 not be - it may have been signalled before we last called
1039 recv. Double-check that there is data. */
1040 if (events
.lNetworkEvents
& FD_READ
)
1042 unsigned long available
;
1044 if (ioctlsocket (scb
->fd
, FIONREAD
, &available
) == 0
1047 SetEvent (state
->read_event
);
1051 /* Oops, no data. This call to recv will cause future
1052 data to retrigger the event, e.g. while we are
1053 in net_select_thread. */
1054 recv (scb
->fd
, NULL
, 0, 0);
1057 /* If there's a close event, then record it - it is obviously
1058 still valid, and it will not be resignalled. */
1059 if (events
.lNetworkEvents
& FD_CLOSE
)
1061 SetEvent (state
->except_event
);
1065 /* If we set either handle, there's no need to wake the thread. */
1070 /* Start the select thread. */
1071 SetEvent (state
->start_select
);
1075 net_windows_done_wait_handle (struct serial
*scb
)
1077 struct net_windows_state
*state
= scb
->state
;
1079 SetEvent (state
->stop_select
);
1080 WaitForSingleObject (state
->have_stopped
, INFINITE
);
1084 net_windows_open (struct serial
*scb
, const char *name
)
1086 struct net_windows_state
*state
;
1090 ret
= net_open (scb
, name
);
1094 state
= xmalloc (sizeof (struct net_windows_state
));
1095 memset (state
, 0, sizeof (struct net_windows_state
));
1098 /* Create auto reset events to wake, stop, and exit the select
1100 state
->start_select
= CreateEvent (0, FALSE
, FALSE
, 0);
1101 state
->stop_select
= CreateEvent (0, FALSE
, FALSE
, 0);
1102 state
->exit_select
= CreateEvent (0, FALSE
, FALSE
, 0);
1104 /* Create a manual reset event to signal whether the thread is
1105 stopped. This must be manual reset, because we may wait on
1106 it multiple times without ever starting the thread. */
1107 state
->have_stopped
= CreateEvent (0, TRUE
, FALSE
, 0);
1109 /* Associate an event with the socket. */
1110 state
->sock_event
= CreateEvent (0, TRUE
, FALSE
, 0);
1111 WSAEventSelect (scb
->fd
, state
->sock_event
, FD_READ
| FD_CLOSE
);
1113 /* Create our own events to report read and close separately. */
1114 state
->read_event
= CreateEvent (0, FALSE
, FALSE
, 0);
1115 state
->except_event
= CreateEvent (0, FALSE
, FALSE
, 0);
1117 /* And finally start the select thread. */
1118 state
->thread
= CreateThread (NULL
, 0, net_windows_select_thread
, scb
, 0,
1126 net_windows_close (struct serial
*scb
)
1128 struct net_windows_state
*state
= scb
->state
;
1130 SetEvent (state
->exit_select
);
1131 WaitForSingleObject (state
->thread
, INFINITE
);
1133 CloseHandle (state
->read_event
);
1134 CloseHandle (state
->except_event
);
1136 CloseHandle (state
->start_select
);
1137 CloseHandle (state
->stop_select
);
1138 CloseHandle (state
->exit_select
);
1139 CloseHandle (state
->have_stopped
);
1141 CloseHandle (state
->sock_event
);
1149 _initialize_ser_windows (void)
1152 struct serial_ops
*ops
;
1154 /* First register the serial port driver. */
1156 ops
= XMALLOC (struct serial_ops
);
1157 memset (ops
, 0, sizeof (struct serial_ops
));
1158 ops
->name
= "hardwire";
1160 ops
->open
= ser_windows_open
;
1161 ops
->close
= ser_windows_close
;
1163 ops
->flush_output
= ser_windows_flush_output
;
1164 ops
->flush_input
= ser_windows_flush_input
;
1165 ops
->send_break
= ser_windows_send_break
;
1167 /* These are only used for stdin; we do not need them for serial
1168 ports, so supply the standard dummies. */
1169 ops
->get_tty_state
= ser_base_get_tty_state
;
1170 ops
->set_tty_state
= ser_base_set_tty_state
;
1171 ops
->print_tty_state
= ser_base_print_tty_state
;
1172 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1174 ops
->go_raw
= ser_windows_raw
;
1175 ops
->setbaudrate
= ser_windows_setbaudrate
;
1176 ops
->setstopbits
= ser_windows_setstopbits
;
1177 ops
->drain_output
= ser_windows_drain_output
;
1178 ops
->readchar
= ser_base_readchar
;
1179 ops
->write
= ser_base_write
;
1180 ops
->async
= ser_base_async
;
1181 ops
->read_prim
= ser_windows_read_prim
;
1182 ops
->write_prim
= ser_windows_write_prim
;
1183 ops
->wait_handle
= ser_windows_wait_handle
;
1185 serial_add_interface (ops
);
1187 /* Next create the dummy serial driver used for terminals. We only
1188 provide the TTY-related methods. */
1190 ops
= XMALLOC (struct serial_ops
);
1191 memset (ops
, 0, sizeof (struct serial_ops
));
1193 ops
->name
= "terminal";
1196 ops
->close
= ser_console_close
;
1197 ops
->get_tty_state
= ser_console_get_tty_state
;
1198 ops
->set_tty_state
= ser_base_set_tty_state
;
1199 ops
->print_tty_state
= ser_base_print_tty_state
;
1200 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1201 ops
->drain_output
= ser_base_drain_output
;
1202 ops
->wait_handle
= ser_console_wait_handle
;
1203 ops
->done_wait_handle
= ser_console_done_wait_handle
;
1205 serial_add_interface (ops
);
1207 /* The pipe interface. */
1209 ops
= XMALLOC (struct serial_ops
);
1210 memset (ops
, 0, sizeof (struct serial_ops
));
1213 ops
->open
= pipe_windows_open
;
1214 ops
->close
= pipe_windows_close
;
1215 ops
->readchar
= ser_base_readchar
;
1216 ops
->write
= ser_base_write
;
1217 ops
->flush_output
= ser_base_flush_output
;
1218 ops
->flush_input
= ser_base_flush_input
;
1219 ops
->send_break
= ser_base_send_break
;
1220 ops
->go_raw
= ser_base_raw
;
1221 ops
->get_tty_state
= ser_base_get_tty_state
;
1222 ops
->set_tty_state
= ser_base_set_tty_state
;
1223 ops
->print_tty_state
= ser_base_print_tty_state
;
1224 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1225 ops
->setbaudrate
= ser_base_setbaudrate
;
1226 ops
->setstopbits
= ser_base_setstopbits
;
1227 ops
->drain_output
= ser_base_drain_output
;
1228 ops
->async
= ser_base_async
;
1229 ops
->read_prim
= pipe_windows_read
;
1230 ops
->write_prim
= pipe_windows_write
;
1231 ops
->wait_handle
= pipe_wait_handle
;
1232 ops
->done_wait_handle
= pipe_done_wait_handle
;
1233 ops
->avail
= pipe_avail
;
1235 serial_add_interface (ops
);
1237 /* If WinSock works, register the TCP/UDP socket driver. */
1239 if (WSAStartup (MAKEWORD (1, 0), &wsa_data
) != 0)
1240 /* WinSock is unavailable. */
1243 ops
= XMALLOC (struct serial_ops
);
1244 memset (ops
, 0, sizeof (struct serial_ops
));
1247 ops
->open
= net_windows_open
;
1248 ops
->close
= net_windows_close
;
1249 ops
->readchar
= ser_base_readchar
;
1250 ops
->write
= ser_base_write
;
1251 ops
->flush_output
= ser_base_flush_output
;
1252 ops
->flush_input
= ser_base_flush_input
;
1253 ops
->send_break
= ser_base_send_break
;
1254 ops
->go_raw
= ser_base_raw
;
1255 ops
->get_tty_state
= ser_base_get_tty_state
;
1256 ops
->set_tty_state
= ser_base_set_tty_state
;
1257 ops
->print_tty_state
= ser_base_print_tty_state
;
1258 ops
->noflush_set_tty_state
= ser_base_noflush_set_tty_state
;
1259 ops
->setbaudrate
= ser_base_setbaudrate
;
1260 ops
->setstopbits
= ser_base_setstopbits
;
1261 ops
->drain_output
= ser_base_drain_output
;
1262 ops
->async
= ser_base_async
;
1263 ops
->read_prim
= net_read_prim
;
1264 ops
->write_prim
= net_write_prim
;
1265 ops
->wait_handle
= net_windows_wait_handle
;
1266 ops
->done_wait_handle
= net_windows_done_wait_handle
;
1267 serial_add_interface (ops
);