/* Serial interface for local (hardwired) serial ports on Windows systems

   Copyright (C) 2006-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "serial.h"
#include "ser-base.h"
#include "ser-tcp.h"

#include <windows.h>
#include <conio.h>

#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>

#include "command.h"
#include "gdbsupport/buildargv.h"

struct ser_windows_state
{
  int in_progress;
  OVERLAPPED ov;
  DWORD lastCommMask;
  HANDLE except_event;
};

/* CancelIo is not available for Windows 95 OS, so we need to use
   LoadLibrary/GetProcAddress to avoid a startup failure.  */
#define CancelIo dyn_CancelIo
typedef BOOL WINAPI (CancelIo_ftype) (HANDLE);
static CancelIo_ftype *CancelIo;

/* Open up a real live device for serial I/O.  */

static void
ser_windows_open (struct serial *scb, const char *name)
{
  HANDLE h;
  struct ser_windows_state *state;
  COMMTIMEOUTS timeouts;

  h = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
		  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  if (h == INVALID_HANDLE_VALUE)
    {
      std::string msg = string_printf(_("could not open file: %s"),
				      name);
      throw_winerror_with_name (msg.c_str (), GetLastError ());
    }

  scb->fd = _open_osfhandle ((intptr_t) h, O_RDWR);
  if (scb->fd < 0)
    error (_("could not get underlying file descriptor"));

  if (!SetCommMask (h, EV_RXCHAR))
    throw_winerror_with_name (_("error calling SetCommMask"),
			      GetLastError ());

  timeouts.ReadIntervalTimeout = MAXDWORD;
  timeouts.ReadTotalTimeoutConstant = 0;
  timeouts.ReadTotalTimeoutMultiplier = 0;
  timeouts.WriteTotalTimeoutConstant = 0;
  timeouts.WriteTotalTimeoutMultiplier = 0;
  if (!SetCommTimeouts (h, &timeouts))
    throw_winerror_with_name (_("error calling SetCommTimeouts"),
			      GetLastError ());

  state = XCNEW (struct ser_windows_state);
  scb->state = state;

  /* Create a manual reset event to watch the input buffer.  */
  state->ov.hEvent = CreateEvent (0, TRUE, FALSE, 0);

  /* Create a (currently unused) handle to record exceptions.  */
  state->except_event = CreateEvent (0, TRUE, FALSE, 0);
}

/* Wait for the output to drain away, as opposed to flushing (discarding)
   it.  */

static int
ser_windows_drain_output (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  return (FlushFileBuffers (h) != 0) ? 0 : -1;
}

static int
ser_windows_flush_output (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  return (PurgeComm (h, PURGE_TXCLEAR) != 0) ? 0 : -1;
}

static int
ser_windows_flush_input (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  return (PurgeComm (h, PURGE_RXCLEAR) != 0) ? 0 : -1;
}

static void
ser_windows_send_break (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  if (SetCommBreak (h) == 0)
    throw_winerror_with_name ("error calling SetCommBreak",
			      GetLastError ());

  /* Delay for 250 milliseconds.  */
  Sleep (250);

  if (ClearCommBreak (h) == 0)
    throw_winerror_with_name ("error calling ClearCommBreak",
			      GetLastError ());
}

static void
ser_windows_raw (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
  DCB state;

  if (GetCommState (h, &state) == 0)
    return;

  state.fOutxCtsFlow = FALSE;
  state.fOutxDsrFlow = FALSE;
  state.fDtrControl = DTR_CONTROL_ENABLE;
  state.fDsrSensitivity = FALSE;
  state.fOutX = FALSE;
  state.fInX = FALSE;
  state.fNull = FALSE;
  state.fAbortOnError = FALSE;
  state.ByteSize = 8;

  if (SetCommState (h, &state) == 0)
    warning (_("SetCommState failed"));
}

static int
ser_windows_setstopbits (struct serial *scb, int num)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
  DCB state;

  if (GetCommState (h, &state) == 0)
    return -1;

  switch (num)
    {
    case SERIAL_1_STOPBITS:
      state.StopBits = ONESTOPBIT;
      break;
    case SERIAL_1_AND_A_HALF_STOPBITS:
      state.StopBits = ONE5STOPBITS;
      break;
    case SERIAL_2_STOPBITS:
      state.StopBits = TWOSTOPBITS;
      break;
    default:
      return 1;
    }

  return (SetCommState (h, &state) != 0) ? 0 : -1;
}

/* Implement the "setparity" serial_ops callback.  */

static int
ser_windows_setparity (struct serial *scb, int parity)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
  DCB state;

  if (GetCommState (h, &state) == 0)
    return -1;

  switch (parity)
    {
    case GDBPARITY_NONE:
      state.Parity = NOPARITY;
      state.fParity = FALSE;
      break;
    case GDBPARITY_ODD:
      state.Parity = ODDPARITY;
      state.fParity = TRUE;
      break;
    case GDBPARITY_EVEN:
      state.Parity = EVENPARITY;
      state.fParity = TRUE;
      break;
    default:
      internal_warning ("Incorrect parity value: %d", parity);
      return -1;
    }

  return (SetCommState (h, &state) != 0) ? 0 : -1;
}

static void
ser_windows_setbaudrate (struct serial *scb, int rate)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
  DCB state;

  if (GetCommState (h, &state) == 0)
    throw_winerror_with_name ("call to GetCommState failed", GetLastError ());

  state.BaudRate = rate;

  if (SetCommState (h, &state) == 0)
    throw_winerror_with_name ("call to SetCommState failed", GetLastError ());
}

static void
ser_windows_close (struct serial *scb)
{
  struct ser_windows_state *state;

  /* Stop any pending selects.  On Windows 95 OS, CancelIo function does
     not exist.  In that case, it can be replaced by a call to CloseHandle,
     but this is not necessary here as we do close the Windows handle
     by calling close (scb->fd) below.  */
  if (CancelIo)
    CancelIo ((HANDLE) _get_osfhandle (scb->fd));
  state = (struct ser_windows_state *) scb->state;
  CloseHandle (state->ov.hEvent);
  CloseHandle (state->except_event);

  if (scb->fd < 0)
    return;

  close (scb->fd);
  scb->fd = -1;

  xfree (scb->state);
}

static void
ser_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct ser_windows_state *state;
  COMSTAT status;
  DWORD errors;
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  state = (struct ser_windows_state *) scb->state;

  *except = state->except_event;
  *read = state->ov.hEvent;

  if (state->in_progress)
    return;

  /* Reset the mask - we are only interested in any characters which
     arrive after this point, not characters which might have arrived
     and already been read.  */

  /* This really, really shouldn't be necessary - just the second one.
     But otherwise an internal flag for EV_RXCHAR does not get
     cleared, and we get a duplicated event, if the last batch
     of characters included at least two arriving close together.  */
  if (!SetCommMask (h, 0))
    warning (_("ser_windows_wait_handle: resetting mask failed"));

  if (!SetCommMask (h, EV_RXCHAR))
    warning (_("ser_windows_wait_handle: resetting mask failed (2)"));

  /* There's a potential race condition here; we must check cbInQue
     and not wait if that's nonzero.  */

  ClearCommError (h, &errors, &status);
  if (status.cbInQue > 0)
    {
      SetEvent (state->ov.hEvent);
      return;
    }

  state->in_progress = 1;
  ResetEvent (state->ov.hEvent);
  state->lastCommMask = -2;
  if (WaitCommEvent (h, &state->lastCommMask, &state->ov))
    {
      gdb_assert (state->lastCommMask & EV_RXCHAR);
      SetEvent (state->ov.hEvent);
    }
  else
    gdb_assert (GetLastError () == ERROR_IO_PENDING);
}

static int
ser_windows_read_prim (struct serial *scb, size_t count)
{
  struct ser_windows_state *state;
  OVERLAPPED ov;
  DWORD bytes_read;
  HANDLE h;

  state = (struct ser_windows_state *) scb->state;
  if (state->in_progress)
    {
      WaitForSingleObject (state->ov.hEvent, INFINITE);
      state->in_progress = 0;
      ResetEvent (state->ov.hEvent);
    }

  memset (&ov, 0, sizeof (OVERLAPPED));
  ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
  h = (HANDLE) _get_osfhandle (scb->fd);

  if (!ReadFile (h, scb->buf, /* count */ 1, &bytes_read, &ov))
    {
      if (GetLastError () != ERROR_IO_PENDING
	  || !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
	{
	  ULONGEST err = GetLastError ();
	  CloseHandle (ov.hEvent);
	  throw_winerror_with_name (_("error while reading"), err);
	}
    }

  CloseHandle (ov.hEvent);
  return bytes_read;
}

static int
ser_windows_write_prim (struct serial *scb, const void *buf, size_t len)
{
  OVERLAPPED ov;
  DWORD bytes_written;
  HANDLE h;

  memset (&ov, 0, sizeof (OVERLAPPED));
  ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
  h = (HANDLE) _get_osfhandle (scb->fd);
  if (!WriteFile (h, buf, len, &bytes_written, &ov))
    {
      if (GetLastError () != ERROR_IO_PENDING
	  || !GetOverlappedResult (h, &ov, &bytes_written, TRUE))
	throw_winerror_with_name ("error while writing", GetLastError ());
    }

  CloseHandle (ov.hEvent);
  return bytes_written;
}

/* On Windows, gdb_select is implemented using WaitForMulpleObjects.
   A "select thread" is created for each file descriptor.  These
   threads looks for activity on the corresponding descriptor, using
   whatever techniques are appropriate for the descriptor type.  When
   that activity occurs, the thread signals an appropriate event,
   which wakes up WaitForMultipleObjects.

   Each select thread is in one of two states: stopped or started.
   Select threads begin in the stopped state.  When gdb_select is
   called, threads corresponding to the descriptors of interest are
   started by calling a wait_handle function.  Each thread that
   notices activity signals the appropriate event and then reenters
   the stopped state.  Before gdb_select returns it calls the
   wait_handle_done functions, which return the threads to the stopped
   state.  */

enum select_thread_state {
  STS_STARTED,
  STS_STOPPED
};

struct ser_console_state
{
  /* Signaled by the select thread to indicate that data is available
     on the file descriptor.  */
  HANDLE read_event;
  /* Signaled by the select thread to indicate that an exception has
     occurred on the file descriptor.  */
  HANDLE except_event;
  /* Signaled by the select thread to indicate that it has entered the
     started state.  HAVE_STARTED and HAVE_STOPPED are never signaled
     simultaneously.  */
  HANDLE have_started;
  /* Signaled by the select thread to indicate that it has stopped,
     either because data is available (and READ_EVENT is signaled),
     because an exception has occurred (and EXCEPT_EVENT is signaled),
     or because STOP_SELECT was signaled.  */
  HANDLE have_stopped;

  /* Signaled by the main program to tell the select thread to enter
     the started state.  */
  HANDLE start_select;
  /* Signaled by the main program to tell the select thread to enter
     the stopped state.  */
  HANDLE stop_select;
  /* Signaled by the main program to tell the select thread to
     exit.  */
  HANDLE exit_select;

  /* The handle for the select thread.  */
  HANDLE thread;
  /* The state of the select thread.  This field is only accessed in
     the main program, never by the select thread itself.  */
  enum select_thread_state thread_state;
};

/* Called by a select thread to enter the stopped state.  This
   function does not return until the thread has re-entered the
   started state.  */
static void
select_thread_wait (struct ser_console_state *state)
{
  HANDLE wait_events[2];

  /* There are two things that can wake us up: a request that we enter
     the started state, or that we exit this thread.  */
  wait_events[0] = state->start_select;
  wait_events[1] = state->exit_select;
  if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) 
      != WAIT_OBJECT_0)
    /* Either the EXIT_SELECT event was signaled (requesting that the
       thread exit) or an error has occurred.  In either case, we exit
       the thread.  */
    ExitThread (0);
  
  /* We are now in the started state.  */
  SetEvent (state->have_started);
}

typedef DWORD WINAPI (*thread_fn_type)(void *);

/* Create a new select thread for SCB executing THREAD_FN.  The STATE
   will be filled in by this function before return.  */
static void
create_select_thread (thread_fn_type thread_fn,
		      struct serial *scb,
		      struct ser_console_state *state)
{
  DWORD threadId;

  /* Create all of the events.  These are all auto-reset events.  */
  state->read_event = CreateEvent (NULL, FALSE, FALSE, NULL);
  state->except_event = CreateEvent (NULL, FALSE, FALSE, NULL);
  state->have_started = CreateEvent (NULL, FALSE, FALSE, NULL);
  state->have_stopped = CreateEvent (NULL, FALSE, FALSE, NULL);
  state->start_select = CreateEvent (NULL, FALSE, FALSE, NULL);
  state->stop_select = CreateEvent (NULL, FALSE, FALSE, NULL);
  state->exit_select = CreateEvent (NULL, FALSE, FALSE, NULL);

  state->thread = CreateThread (NULL, 0, thread_fn, scb, 0, &threadId);
  /* The thread begins in the stopped state.  */
  state->thread_state = STS_STOPPED;
}

/* Destroy the select thread indicated by STATE.  */
static void
destroy_select_thread (struct ser_console_state *state)
{
  /* Ask the thread to exit.  */
  SetEvent (state->exit_select);
  /* Wait until it does.  */
  WaitForSingleObject (state->thread, INFINITE);

  /* Destroy the events.  */
  CloseHandle (state->read_event);
  CloseHandle (state->except_event);
  CloseHandle (state->have_started);
  CloseHandle (state->have_stopped);
  CloseHandle (state->start_select);
  CloseHandle (state->stop_select);
  CloseHandle (state->exit_select);
}

/* Called by gdb_select to start the select thread indicated by STATE.
   This function does not return until the thread has started.  */
static void
start_select_thread (struct ser_console_state *state)
{
  /* Ask the thread to start.  */
  SetEvent (state->start_select);
  /* Wait until it does.  */
  WaitForSingleObject (state->have_started, INFINITE);
  /* The thread is now started.  */
  state->thread_state = STS_STARTED;
}

/* Called by gdb_select to stop the select thread indicated by STATE.
   This function does not return until the thread has stopped.  */
static void
stop_select_thread (struct ser_console_state *state)
{
  /* If the thread is already in the stopped state, we have nothing to
     do.  Some of the wait_handle functions avoid calling
     start_select_thread if they notice activity on the relevant file
     descriptors.  The wait_handle_done functions still call
     stop_select_thread -- but it is already stopped.  */
  if (state->thread_state != STS_STARTED)
    return;
  /* Ask the thread to stop.  */
  SetEvent (state->stop_select);
  /* Wait until it does.  */
  WaitForSingleObject (state->have_stopped, INFINITE);
  /* The thread is now stopped.  */
  state->thread_state = STS_STOPPED;
}

static DWORD WINAPI
console_select_thread (void *arg)
{
  struct serial *scb = (struct serial *) arg;
  struct ser_console_state *state;
  int event_index;
  HANDLE h;

  state = (struct ser_console_state *) scb->state;
  h = (HANDLE) _get_osfhandle (scb->fd);

  while (1)
    {
      HANDLE wait_events[2];
      INPUT_RECORD record;
      DWORD n_records;

      select_thread_wait (state);

      while (1)
	{
	  wait_events[0] = state->stop_select;
	  wait_events[1] = h;

	  event_index = WaitForMultipleObjects (2, wait_events,
						FALSE, INFINITE);

	  if (event_index == WAIT_OBJECT_0
	      || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
	    break;

	  if (event_index != WAIT_OBJECT_0 + 1)
	    {
	      /* Wait must have failed; assume an error has occurred, e.g.
		 the handle has been closed.  */
	      SetEvent (state->except_event);
	      break;
	    }

	  /* We've got a pending event on the console.  See if it's
	     of interest.  */
	  if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1)
	    {
	      /* Something went wrong.  Maybe the console is gone.  */
	      SetEvent (state->except_event);
	      break;
	    }

	  if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
	    {
	      WORD keycode = record.Event.KeyEvent.wVirtualKeyCode;

	      /* Ignore events containing only control keys.  We must
		 recognize "enhanced" keys which we are interested in
		 reading via getch, if they do not map to ASCII.  But we
		 do not want to report input available for e.g. the
		 control key alone.  */

	      if (record.Event.KeyEvent.uChar.AsciiChar != 0
		  || keycode == VK_PRIOR
		  || keycode == VK_NEXT
		  || keycode == VK_END
		  || keycode == VK_HOME
		  || keycode == VK_LEFT
		  || keycode == VK_UP
		  || keycode == VK_RIGHT
		  || keycode == VK_DOWN
		  || keycode == VK_INSERT
		  || keycode == VK_DELETE)
		{
		  /* This is really a keypress.  */
		  SetEvent (state->read_event);
		  break;
		}
	    }
	  else if (record.EventType == MOUSE_EVENT)
	    {
	      SetEvent (state->read_event);
	      break;
	    }

	  /* Otherwise discard it and wait again.  */
	  ReadConsoleInput (h, &record, 1, &n_records);
	}

      SetEvent(state->have_stopped);
    }
  return 0;
}

static int
fd_is_pipe (int fd)
{
  if (PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, NULL, NULL))
    return 1;
  else
    return 0;
}

static int
fd_is_file (int fd)
{
  if (GetFileType ((HANDLE) _get_osfhandle (fd)) == FILE_TYPE_DISK)
    return 1;
  else
    return 0;
}

static DWORD WINAPI
pipe_select_thread (void *arg)
{
  struct serial *scb = (struct serial *) arg;
  struct ser_console_state *state;
  HANDLE h;

  state = (struct ser_console_state *) scb->state;
  h = (HANDLE) _get_osfhandle (scb->fd);

  while (1)
    {
      DWORD n_avail;

      select_thread_wait (state);

      /* Wait for something to happen on the pipe.  */
      while (1)
	{
	  if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
	    {
	      SetEvent (state->except_event);
	      break;
	    }

	  if (n_avail > 0)
	    {
	      SetEvent (state->read_event);
	      break;
	    }

	  /* Delay 10ms before checking again, but allow the stop
	     event to wake us.  */
	  if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0)
	    break;
	}

      SetEvent (state->have_stopped);
    }
  return 0;
}

static DWORD WINAPI
file_select_thread (void *arg)
{
  struct serial *scb = (struct serial *) arg;
  struct ser_console_state *state;
  HANDLE h;

  state = (struct ser_console_state *) scb->state;
  h = (HANDLE) _get_osfhandle (scb->fd);

  while (1)
    {
      select_thread_wait (state);

      if (SetFilePointer (h, 0, NULL, FILE_CURRENT)
	  == INVALID_SET_FILE_POINTER)
	SetEvent (state->except_event);
      else
	SetEvent (state->read_event);

      SetEvent (state->have_stopped);
    }
  return 0;
}

static void
ser_console_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct ser_console_state *state = (struct ser_console_state *) scb->state;

  if (state == NULL)
    {
      thread_fn_type thread_fn;
      int is_tty;

      is_tty = isatty (scb->fd);
      if (!is_tty && !fd_is_file (scb->fd) && !fd_is_pipe (scb->fd))
	{
	  *read = NULL;
	  *except = NULL;
	  return;
	}

      state = XCNEW (struct ser_console_state);
      scb->state = state;

      if (is_tty)
	thread_fn = console_select_thread;
      else if (fd_is_pipe (scb->fd))
	thread_fn = pipe_select_thread;
      else
	thread_fn = file_select_thread;

      create_select_thread (thread_fn, scb, state);
    }

  *read = state->read_event;
  *except = state->except_event;

  /* Start from a blank state.  */
  ResetEvent (state->read_event);
  ResetEvent (state->except_event);
  ResetEvent (state->stop_select);

  /* First check for a key already in the buffer.  If there is one,
     we don't need a thread.  This also catches the second key of
     multi-character returns from getch, for instance for arrow
     keys.  The second half is in a C library internal buffer,
     and PeekConsoleInput will not find it.  */
  if (_kbhit ())
    {
      SetEvent (state->read_event);
      return;
    }

  /* Otherwise, start the select thread.  */
  start_select_thread (state);
}

static void
ser_console_done_wait_handle (struct serial *scb)
{
  struct ser_console_state *state = (struct ser_console_state *) scb->state;

  if (state == NULL)
    return;

  stop_select_thread (state);
}

static void
ser_console_close (struct serial *scb)
{
  struct ser_console_state *state = (struct ser_console_state *) scb->state;

  if (scb->state)
    {
      destroy_select_thread (state);
      xfree (scb->state);
    }
}

struct ser_console_ttystate
{
  int is_a_tty;
};

static serial_ttystate
ser_console_get_tty_state (struct serial *scb)
{
  if (isatty (scb->fd))
    {
      struct ser_console_ttystate *state;

      state = XNEW (struct ser_console_ttystate);
      state->is_a_tty = 1;
      return state;
    }
  else
    return NULL;
}

struct pipe_state
{
  /* Since we use the pipe_select_thread for our select emulation,
     we need to place the state structure it requires at the front
     of our state.  */
  struct ser_console_state wait;

  /* The pex obj for our (one-stage) pipeline.  */
  struct pex_obj *pex;

  /* Streams for the pipeline's input and output.  */
  FILE *input, *output;
};

static struct pipe_state *
make_pipe_state (void)
{
  struct pipe_state *ps = XCNEW (struct pipe_state);

  ps->wait.read_event = INVALID_HANDLE_VALUE;
  ps->wait.except_event = INVALID_HANDLE_VALUE;
  ps->wait.start_select = INVALID_HANDLE_VALUE;
  ps->wait.stop_select = INVALID_HANDLE_VALUE;

  return ps;
}

static void
free_pipe_state (struct pipe_state *ps)
{
  int saved_errno = errno;

  if (ps->wait.read_event != INVALID_HANDLE_VALUE)
    destroy_select_thread (&ps->wait);

  /* Close the pipe to the child.  We must close the pipe before
     calling pex_free because pex_free will wait for the child to exit
     and the child will not exit until the pipe is closed.  */
  if (ps->input)
    fclose (ps->input);
  if (ps->pex)
    {
      pex_free (ps->pex);
      /* pex_free closes ps->output.  */
    }
  else if (ps->output)
    fclose (ps->output);

  xfree (ps);

  errno = saved_errno;
}

struct pipe_state_destroyer
{
  void operator() (pipe_state *ps) const
  {
    free_pipe_state (ps);
  }
};

typedef std::unique_ptr<pipe_state, pipe_state_destroyer> pipe_state_up;

static void
pipe_windows_open (struct serial *scb, const char *name)
{
  FILE *pex_stderr;

  if (name == NULL)
    error_no_arg (_("child command"));

  if (*name == '|')
    {
      name++;
      name = skip_spaces (name);
    }

  gdb_argv argv (name);

  if (! argv[0] || argv[0][0] == '\0')
    error (_("missing child command"));

  pipe_state_up ps (make_pipe_state ());

  ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
  if (! ps->pex)
    error (_("could not start pipeline"));
  ps->input = pex_input_pipe (ps->pex, 1);
  if (! ps->input)
    error (_("could not find input pipe"));

  {
    int err;
    const char *err_msg
      = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT
		 | PEX_STDERR_TO_PIPE,
		 argv[0], argv.get (), NULL, NULL,
		 &err);

    if (err_msg)
      {
	/* Our caller expects us to return -1, but all they'll do with
	   it generally is print the message based on errno.  We have
	   all the same information here, plus err_msg provided by
	   pex_run, so we just raise the error here.  */
	if (err)
	  error (_("error starting child process '%s': %s: %s"),
		 name, err_msg, safe_strerror (err));
	else
	  error (_("error starting child process '%s': %s"),
		 name, err_msg);
      }
  }

  ps->output = pex_read_output (ps->pex, 1);
  if (! ps->output)
    error (_("could not find output pipe"));
  scb->fd = fileno (ps->output);

  pex_stderr = pex_read_err (ps->pex, 1);
  if (! pex_stderr)
    error (_("could not find error pipe"));
  scb->error_fd = fileno (pex_stderr);

  scb->state = ps.release ();
}

static int
pipe_windows_fdopen (struct serial *scb, int fd)
{
  struct pipe_state *ps;

  ps = make_pipe_state ();

  ps->input = fdopen (fd, "r+");
  if (! ps->input)
    goto fail;

  ps->output = fdopen (fd, "r+");
  if (! ps->output)
    goto fail;

  scb->fd = fd;
  scb->state = (void *) ps;

  return 0;

 fail:
  free_pipe_state (ps);
  return -1;
}

static void
pipe_windows_close (struct serial *scb)
{
  struct pipe_state *ps = (struct pipe_state *) scb->state;

  /* In theory, we should try to kill the subprocess here, but the pex
     interface doesn't give us enough information to do that.  Usually
     closing the input pipe will get the message across.  */

  free_pipe_state (ps);
}


static int
pipe_windows_read (struct serial *scb, size_t count)
{
  HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
  DWORD available;
  DWORD bytes_read;

  if (pipeline_out == INVALID_HANDLE_VALUE)
    error (_("could not find file number for pipe"));

  if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
    throw_winerror_with_name (_("could not peek into pipe"), GetLastError ());

  if (count > available)
    count = available;

  if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
    throw_winerror_with_name (_("could not read from pipe"), GetLastError ());

  return bytes_read;
}


static int
pipe_windows_write (struct serial *scb, const void *buf, size_t count)
{
  struct pipe_state *ps = (struct pipe_state *) scb->state;
  HANDLE pipeline_in;
  DWORD written;

  int pipeline_in_fd = fileno (ps->input);
  if (pipeline_in_fd < 0)
    error (_("could not find file number for pipe"));

  pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
  if (pipeline_in == INVALID_HANDLE_VALUE)
    error (_("could not find handle for pipe"));

  if (! WriteFile (pipeline_in, buf, count, &written, NULL))
    throw_winerror_with_name (_("could not write to pipe"), GetLastError ());

  return written;
}


static void
pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct pipe_state *ps = (struct pipe_state *) scb->state;

  /* Have we allocated our events yet?  */
  if (ps->wait.read_event == INVALID_HANDLE_VALUE)
    /* Start the thread.  */
    create_select_thread (pipe_select_thread, scb, &ps->wait);

  *read = ps->wait.read_event;
  *except = ps->wait.except_event;

  /* Start from a blank state.  */
  ResetEvent (ps->wait.read_event);
  ResetEvent (ps->wait.except_event);
  ResetEvent (ps->wait.stop_select);

  start_select_thread (&ps->wait);
}

static void
pipe_done_wait_handle (struct serial *scb)
{
  struct pipe_state *ps = (struct pipe_state *) scb->state;

  /* Have we allocated our events yet?  */
  if (ps->wait.read_event == INVALID_HANDLE_VALUE)
    return;

  stop_select_thread (&ps->wait);
}

static int
pipe_avail (struct serial *scb, int fd)
{
  HANDLE h = (HANDLE) _get_osfhandle (fd);
  DWORD numBytes;
  BOOL r = PeekNamedPipe (h, NULL, 0, NULL, &numBytes, NULL);

  if (r == FALSE)
    numBytes = 0;
  return numBytes;
}

int
gdb_pipe (int pdes[2])
{
  if (_pipe (pdes, 512, _O_BINARY | _O_NOINHERIT) == -1)
    return -1;
  return 0;
}

struct net_windows_state
{
  struct ser_console_state base;
  
  HANDLE sock_event;
};

/* Check whether the socket has any pending data to be read.  If so,
   set the select thread's read event.  On error, set the select
   thread's except event.  If any event was set, return true,
   otherwise return false.  */

static int
net_windows_socket_check_pending (struct serial *scb)
{
  struct net_windows_state *state = (struct net_windows_state *) scb->state;
  unsigned long available;

  if (ioctlsocket (scb->fd, FIONREAD, &available) != 0)
    {
      /* The socket closed, or some other error.  */
      SetEvent (state->base.except_event);
      return 1;
    }
  else if (available > 0)
    {
      SetEvent (state->base.read_event);
      return 1;
    }

  return 0;
}

static DWORD WINAPI
net_windows_select_thread (void *arg)
{
  struct serial *scb = (struct serial *) arg;
  struct net_windows_state *state;
  int event_index;

  state = (struct net_windows_state *) scb->state;

  while (1)
    {
      HANDLE wait_events[2];
      WSANETWORKEVENTS events;

      select_thread_wait (&state->base);

      wait_events[0] = state->base.stop_select;
      wait_events[1] = state->sock_event;

      /* Wait for something to happen on the socket.  */
      while (1)
	{
	  event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);

	  if (event_index == WAIT_OBJECT_0
	      || WaitForSingleObject (state->base.stop_select, 0) == WAIT_OBJECT_0)
	    {
	      /* We have been requested to stop.  */
	      break;
	    }

	  if (event_index != WAIT_OBJECT_0 + 1)
	    {
	      /* Some error has occurred.  Assume that this is an error
		 condition.  */
	      SetEvent (state->base.except_event);
	      break;
	    }

	  /* Enumerate the internal network events, and reset the
	     object that signalled us to catch the next event.  */
	  if (WSAEnumNetworkEvents (scb->fd, state->sock_event, &events) != 0)
	    {
	      /* Something went wrong.  Maybe the socket is gone.  */
	      SetEvent (state->base.except_event);
	      break;
	    }

	  if (events.lNetworkEvents & FD_READ)
	    {
	      if (net_windows_socket_check_pending (scb))
		break;

	      /* Spurious wakeup.  That is, the socket's event was
		 signalled before we last called recv.  */
	    }

	  if (events.lNetworkEvents & FD_CLOSE)
	    {
	      SetEvent (state->base.except_event);
	      break;
	    }
	}

      SetEvent (state->base.have_stopped);
    }
  return 0;
}

static void
net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct net_windows_state *state = (struct net_windows_state *) scb->state;

  /* Start from a clean slate.  */
  ResetEvent (state->base.read_event);
  ResetEvent (state->base.except_event);
  ResetEvent (state->base.stop_select);

  *read = state->base.read_event;
  *except = state->base.except_event;

  /* Check any pending events.  Otherwise, start the select
     thread.  */
  if (!net_windows_socket_check_pending (scb))
    start_select_thread (&state->base);
}

static void
net_windows_done_wait_handle (struct serial *scb)
{
  struct net_windows_state *state = (struct net_windows_state *) scb->state;

  stop_select_thread (&state->base);
}

static void
net_windows_open (struct serial *scb, const char *name)
{
  struct net_windows_state *state;

  net_open (scb, name);

  state = XCNEW (struct net_windows_state);
  scb->state = state;

  /* Associate an event with the socket.  */
  state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
  WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);

  /* Start the thread.  */
  create_select_thread (net_windows_select_thread, scb, &state->base);
}


static void
net_windows_close (struct serial *scb)
{
  struct net_windows_state *state = (struct net_windows_state *) scb->state;

  destroy_select_thread (&state->base);
  CloseHandle (state->sock_event);

  xfree (scb->state);

  net_close (scb);
}

/* The serial port driver.  */

static const struct serial_ops hardwire_ops =
{
  "hardwire",
  ser_windows_open,
  ser_windows_close,
  NULL,
  ser_base_readchar,
  ser_base_write,
  ser_windows_flush_output,
  ser_windows_flush_input,
  ser_windows_send_break,
  ser_windows_raw,
  /* These are only used for stdin; we do not need them for serial
     ports, so supply the standard dummies.  */
  ser_base_get_tty_state,
  ser_base_copy_tty_state,
  ser_base_set_tty_state,
  ser_base_print_tty_state,
  ser_windows_setbaudrate,
  ser_windows_setstopbits,
  ser_windows_setparity,
  ser_windows_drain_output,
  ser_base_async,
  ser_windows_read_prim,
  ser_windows_write_prim,
  NULL,
  ser_windows_wait_handle
};

/* The dummy serial driver used for terminals.  We only provide the
   TTY-related methods.  */

static const struct serial_ops tty_ops =
{
  "terminal",
  NULL,
  ser_console_close,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  ser_console_get_tty_state,
  ser_base_copy_tty_state,
  ser_base_set_tty_state,
  ser_base_print_tty_state,
  NULL,
  NULL,
  NULL,
  ser_base_drain_output,
  NULL,
  NULL,
  NULL,
  NULL,
  ser_console_wait_handle,
  ser_console_done_wait_handle
};

/* The pipe interface.  */

static const struct serial_ops pipe_ops =
{
  "pipe",
  pipe_windows_open,
  pipe_windows_close,
  pipe_windows_fdopen,
  ser_base_readchar,
  ser_base_write,
  ser_base_flush_output,
  ser_base_flush_input,
  ser_base_send_break,
  ser_base_raw,
  ser_base_get_tty_state,
  ser_base_copy_tty_state,
  ser_base_set_tty_state,
  ser_base_print_tty_state,
  ser_base_setbaudrate,
  ser_base_setstopbits,
  ser_base_setparity,
  ser_base_drain_output,
  ser_base_async,
  pipe_windows_read,
  pipe_windows_write,
  pipe_avail,
  pipe_wait_handle,
  pipe_done_wait_handle
};

/* The TCP/UDP socket driver.  */

static const struct serial_ops tcp_ops =
{
  "tcp",
  net_windows_open,
  net_windows_close,
  NULL,
  ser_base_readchar,
  ser_base_write,
  ser_base_flush_output,
  ser_base_flush_input,
  ser_tcp_send_break,
  ser_base_raw,
  ser_base_get_tty_state,
  ser_base_copy_tty_state,
  ser_base_set_tty_state,
  ser_base_print_tty_state,
  ser_base_setbaudrate,
  ser_base_setstopbits,
  ser_base_setparity,
  ser_base_drain_output,
  ser_base_async,
  net_read_prim,
  net_write_prim,
  NULL,
  net_windows_wait_handle,
  net_windows_done_wait_handle
};

INIT_GDB_FILE (ser_windows)
{
  WSADATA wsa_data;

  HMODULE hm = NULL;

  /* First find out if kernel32 exports CancelIo function.  */
  hm = LoadLibrary ("kernel32.dll");
  if (hm)
    {
      CancelIo = (CancelIo_ftype *) GetProcAddress (hm, "CancelIo");
      FreeLibrary (hm);
    }
  else
    CancelIo = NULL;

  serial_add_interface (&hardwire_ops);
  serial_add_interface (&tty_ops);
  serial_add_interface (&pipe_ops);

  /* If WinSock works, register the TCP/UDP socket driver.  */

  if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
    /* WinSock is unavailable.  */
    return;

  serial_add_interface (&tcp_ops);
}
