33#include "gdbsupport/buildargv.h"
45#define CancelIo dyn_CancelIo
56 COMMTIMEOUTS timeouts;
58 h = CreateFile (
name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
59 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
60 if (h == INVALID_HANDLE_VALUE)
66 scb->
fd = _open_osfhandle ((intptr_t) h, O_RDWR);
73 if (!SetCommMask (h, EV_RXCHAR))
79 timeouts.ReadIntervalTimeout = MAXDWORD;
80 timeouts.ReadTotalTimeoutConstant = 0;
81 timeouts.ReadTotalTimeoutMultiplier = 0;
82 timeouts.WriteTotalTimeoutConstant = 0;
83 timeouts.WriteTotalTimeoutMultiplier = 0;
84 if (!SetCommTimeouts (h, &timeouts))
94 state->
ov.hEvent = CreateEvent (0, TRUE, FALSE, 0);
108 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
110 return (FlushFileBuffers (h) != 0) ? 0 : -1;
116 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
118 return (PurgeComm (h, PURGE_TXCLEAR) != 0) ? 0 : -1;
124 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
126 return (PurgeComm (h, PURGE_RXCLEAR) != 0) ? 0 : -1;
132 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
134 if (SetCommBreak (h) == 0)
140 if (ClearCommBreak (h))
149 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
152 if (GetCommState (h, &state) == 0)
155 state.fOutxCtsFlow = FALSE;
156 state.fOutxDsrFlow = FALSE;
157 state.fDtrControl = DTR_CONTROL_ENABLE;
158 state.fDsrSensitivity = FALSE;
162 state.fAbortOnError = FALSE;
165 if (SetCommState (h, &state) == 0)
166 warning (_(
"SetCommState failed"));
172 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
175 if (GetCommState (h, &state) == 0)
181 state.StopBits = ONESTOPBIT;
184 state.StopBits = ONE5STOPBITS;
187 state.StopBits = TWOSTOPBITS;
193 return (SetCommState (h, &state) != 0) ? 0 : -1;
201 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
204 if (GetCommState (h, &state) == 0)
210 state.Parity = NOPARITY;
211 state.fParity = FALSE;
214 state.Parity = ODDPARITY;
215 state.fParity = TRUE;
218 state.Parity = EVENPARITY;
219 state.fParity = TRUE;
222 internal_warning (
"Incorrect parity value: %d",
parity);
226 return (SetCommState (h, &state) != 0) ? 0 : -1;
232 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
235 if (GetCommState (h, &state) == 0)
238 state.BaudRate =
rate;
240 return (SetCommState (h, &state) != 0) ? 0 : -1;
255 CloseHandle (state->
ov.hEvent);
273 HANDLE h = (HANDLE) _get_osfhandle (scb->
fd);
291 if (!SetCommMask (h, 0))
292 warning (_(
"ser_windows_wait_handle: reseting mask failed"));
294 if (!SetCommMask (h, EV_RXCHAR))
295 warning (_(
"ser_windows_wait_handle: reseting mask failed (2)"));
300 ClearCommError (h, &errors, &
status);
303 SetEvent (state->
ov.hEvent);
308 ResetEvent (state->
ov.hEvent);
313 SetEvent (state->
ov.hEvent);
316 gdb_assert (GetLastError () == ERROR_IO_PENDING);
330 WaitForSingleObject (state->
ov.hEvent, INFINITE);
332 ResetEvent (state->
ov.hEvent);
335 memset (&
ov, 0,
sizeof (OVERLAPPED));
336 ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
337 h = (HANDLE) _get_osfhandle (scb->
fd);
339 if (!ReadFile (h, scb->
buf, 1, &bytes_read, &
ov))
341 if (GetLastError () != ERROR_IO_PENDING
342 || !GetOverlappedResult (h, &
ov, &bytes_read, TRUE))
346 CloseHandle (
ov.hEvent);
357 memset (&
ov, 0,
sizeof (OVERLAPPED));
358 ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
359 h = (HANDLE) _get_osfhandle (scb->
fd);
360 if (!WriteFile (h, buf, len, &bytes_written, &
ov))
362 if (GetLastError () != ERROR_IO_PENDING
363 || !GetOverlappedResult (h, &
ov, &bytes_written, TRUE))
367 CloseHandle (
ov.hEvent);
368 return bytes_written;
433 HANDLE wait_events[2];
439 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE)
462 state->
read_event = CreateEvent (NULL, FALSE, FALSE, NULL);
463 state->
except_event = CreateEvent (NULL, FALSE, FALSE, NULL);
464 state->
have_started = CreateEvent (NULL, FALSE, FALSE, NULL);
465 state->
have_stopped = CreateEvent (NULL, FALSE, FALSE, NULL);
466 state->
start_select = CreateEvent (NULL, FALSE, FALSE, NULL);
467 state->
stop_select = CreateEvent (NULL, FALSE, FALSE, NULL);
468 state->
exit_select = CreateEvent (NULL, FALSE, FALSE, NULL);
470 state->
thread = CreateThread (NULL, 0, thread_fn, scb, 0, &threadId);
482 WaitForSingleObject (state->
thread, INFINITE);
536 h = (HANDLE) _get_osfhandle (scb->
fd);
540 HANDLE wait_events[2];
551 event_index = WaitForMultipleObjects (2, wait_events,
554 if (event_index == WAIT_OBJECT_0
555 || WaitForSingleObject (state->
stop_select, 0) == WAIT_OBJECT_0)
558 if (event_index != WAIT_OBJECT_0 + 1)
568 if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1)
575 if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
577 WORD keycode = record.Event.KeyEvent.wVirtualKeyCode;
585 if (record.Event.KeyEvent.uChar.AsciiChar != 0
586 || keycode == VK_PRIOR
587 || keycode == VK_NEXT
589 || keycode == VK_HOME
590 || keycode == VK_LEFT
592 || keycode == VK_RIGHT
593 || keycode == VK_DOWN
594 || keycode == VK_INSERT
595 || keycode == VK_DELETE)
602 else if (record.EventType == MOUSE_EVENT)
609 ReadConsoleInput (h, &record, 1, &n_records);
620 if (PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, NULL, NULL))
629 if (GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_DISK)
643 h = (HANDLE) _get_osfhandle (scb->
fd);
654 if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
668 if (WaitForSingleObject (state->
stop_select, 10) == WAIT_OBJECT_0)
685 h = (HANDLE) _get_osfhandle (scb->
fd);
691 if (SetFilePointer (h, 0, NULL, FILE_CURRENT)
692 == INVALID_SET_FILE_POINTER)
712 is_tty = isatty (scb->
fd);
787 if (isatty (scb->
fd))
829 int saved_errno = errno;
876 gdb_argv argv (
name);
878 if (! argv[0] || argv[0][0] ==
'\0')
879 error (_(
"missing child command"));
883 ps->pex = pex_init (PEX_USE_PIPES,
"target remote pipe", NULL);
886 ps->input = pex_input_pipe (ps->pex, 1);
893 = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
894 | PEX_STDERR_TO_PIPE,
895 argv[0], argv.get (), NULL, NULL,
905 error (_(
"error starting child process '%s': %s: %s"),
906 name, err_msg, safe_strerror (
err));
908 error (_(
"error starting child process '%s': %s"),
913 ps->output = pex_read_output (ps->pex, 1);
916 scb->
fd = fileno (ps->output);
918 pex_stderr = pex_read_err (ps->pex, 1);
921 scb->
error_fd = fileno (pex_stderr);
923 scb->
state = ps.release ();
935 ps->
input = fdopen (fd,
"r+");
939 ps->
output = fdopen (fd,
"r+");
944 scb->
state = (
void *) ps;
969 HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->
fd);
973 if (pipeline_out == INVALID_HANDLE_VALUE)
976 if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &
available, NULL))
982 if (! ReadFile (pipeline_out, scb->
buf, count, &bytes_read, NULL))
996 int pipeline_in_fd = fileno (ps->
input);
997 if (pipeline_in_fd < 0)
1000 pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
1001 if (pipeline_in == INVALID_HANDLE_VALUE)
1004 if (! WriteFile (pipeline_in, buf, count, &written, NULL))
1047 HANDLE h = (HANDLE) _get_osfhandle (fd);
1049 BOOL r = PeekNamedPipe (h, NULL, 0, NULL, &numBytes, NULL);
1059 if (_pipe (pdes, 512, _O_BINARY | _O_NOINHERIT) == -1)
1082 if (ioctlsocket (scb->
fd, FIONREAD, &
available) != 0)
1108 HANDLE wait_events[2];
1109 WSANETWORKEVENTS events;
1119 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
1121 if (event_index == WAIT_OBJECT_0
1128 if (event_index != WAIT_OBJECT_0 + 1)
1138 if (WSAEnumNetworkEvents (scb->
fd, state->
sock_event, &events) != 0)
1145 if (events.lNetworkEvents & FD_READ)
1154 if (events.lNetworkEvents & FD_CLOSE)
1207 state->
sock_event = CreateEvent (0, TRUE, FALSE, 0);
1208 WSAEventSelect (scb->
fd, state->
sock_event, FD_READ | FD_CLOSE);
1361 hm = LoadLibrary (
"kernel32.dll");
1376 if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
void error_no_arg(const char *why)
ssize_t read(int fd, void *buf, size_t count)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t err
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
void ser_base_async(struct serial *scb, int async_p)
void ser_base_print_tty_state(struct serial *scb, serial_ttystate ttystate, struct ui_file *stream)
void ser_base_raw(struct serial *scb)
int ser_base_set_tty_state(struct serial *scb, serial_ttystate ttystate)
serial_ttystate ser_base_get_tty_state(struct serial *scb)
int ser_base_drain_output(struct serial *scb)
int ser_base_send_break(struct serial *scb)
int ser_base_setbaudrate(struct serial *scb, int rate)
serial_ttystate ser_base_copy_tty_state(struct serial *scb, serial_ttystate ttystate)
int ser_base_write(struct serial *scb, const void *buf, size_t count)
int ser_base_setstopbits(struct serial *scb, int num)
int ser_base_flush_output(struct serial *scb)
int ser_base_flush_input(struct serial *scb)
int ser_base_readchar(struct serial *scb, int timeout)
int ser_base_setparity(struct serial *scb, int parity)
static void ser_windows_raw(struct serial *scb)
static int ser_windows_send_break(struct serial *scb)
static serial_ttystate ser_console_get_tty_state(struct serial *scb)
static int pipe_windows_write(struct serial *scb, const void *buf, size_t count)
static int ser_windows_flush_input(struct serial *scb)
static int ser_windows_setbaudrate(struct serial *scb, int rate)
static const struct serial_ops tcp_ops
static void destroy_select_thread(struct ser_console_state *state)
static int pipe_windows_open(struct serial *scb, const char *name)
static void pipe_windows_close(struct serial *scb)
static const struct serial_ops hardwire_ops
static int fd_is_file(int fd)
static int ser_windows_flush_output(struct serial *scb)
DWORD WINAPI(* thread_fn_type)(void *)
static int pipe_windows_fdopen(struct serial *scb, int fd)
static int ser_windows_open(struct serial *scb, const char *name)
int gdb_pipe(int pdes[2])
static void stop_select_thread(struct ser_console_state *state)
static DWORD WINAPI net_windows_select_thread(void *arg)
static int fd_is_pipe(int fd)
static struct pipe_state * make_pipe_state(void)
static void ser_windows_wait_handle(struct serial *scb, HANDLE *read, HANDLE *except)
void _initialize_ser_windows()
static void ser_console_done_wait_handle(struct serial *scb)
static int ser_windows_drain_output(struct serial *scb)
static void select_thread_wait(struct ser_console_state *state)
static void ser_console_wait_handle(struct serial *scb, HANDLE *read, HANDLE *except)
static int net_windows_socket_check_pending(struct serial *scb)
BOOL WINAPI CancelIo_ftype(HANDLE)
static DWORD WINAPI pipe_select_thread(void *arg)
static int ser_windows_read_prim(struct serial *scb, size_t count)
static void create_select_thread(thread_fn_type thread_fn, struct serial *scb, struct ser_console_state *state)
static void free_pipe_state(struct pipe_state *ps)
std::unique_ptr< pipe_state, pipe_state_destroyer > pipe_state_up
static void ser_console_close(struct serial *scb)
static DWORD WINAPI console_select_thread(void *arg)
static void pipe_done_wait_handle(struct serial *scb)
static int ser_windows_setparity(struct serial *scb, int parity)
static void start_select_thread(struct ser_console_state *state)
static void net_windows_close(struct serial *scb)
static void net_windows_done_wait_handle(struct serial *scb)
static int ser_windows_write_prim(struct serial *scb, const void *buf, size_t len)
static DWORD WINAPI file_select_thread(void *arg)
static const struct serial_ops pipe_ops
static void net_windows_wait_handle(struct serial *scb, HANDLE *read, HANDLE *except)
static int ser_windows_setstopbits(struct serial *scb, int num)
static int net_windows_open(struct serial *scb, const char *name)
static int pipe_avail(struct serial *scb, int fd)
static void ser_windows_close(struct serial *scb)
static int pipe_windows_read(struct serial *scb, size_t count)
static void pipe_wait_handle(struct serial *scb, HANDLE *read, HANDLE *except)
static const struct serial_ops tty_ops
int net_write_prim(struct serial *scb, const void *buf, size_t count)
int net_read_prim(struct serial *scb, size_t count)
int net_open(struct serial *scb, const char *name)
int ser_tcp_send_break(struct serial *scb)
void net_close(struct serial *scb)
static const char * parity
void serial_add_interface(const struct serial_ops *optable)
#define SERIAL_2_STOPBITS
#define SERIAL_1_AND_A_HALF_STOPBITS
#define SERIAL_1_STOPBITS
struct ser_console_state base
void operator()(pipe_state *ps) const
struct ser_console_state wait
enum select_thread_state thread_state
unsigned char buf[BUFSIZ]