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

   Copyright (C) 2006-2018 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 "defs.h"
#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"

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 int
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)
    {
      errno = ENOENT;
      return -1;
    }

  scb->fd = _open_osfhandle ((intptr_t) h, O_RDWR);
  if (scb->fd < 0)
    {
      errno = ENOENT;
      return -1;
    }

  if (!SetCommMask (h, EV_RXCHAR))
    {
      errno = EINVAL;
      return -1;
    }

  timeouts.ReadIntervalTimeout = MAXDWORD;
  timeouts.ReadTotalTimeoutConstant = 0;
  timeouts.ReadTotalTimeoutMultiplier = 0;
  timeouts.WriteTotalTimeoutConstant = 0;
  timeouts.WriteTotalTimeoutMultiplier = 0;
  if (!SetCommTimeouts (h, &timeouts))
    {
      errno = EINVAL;
      return -1;
    }

  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);

  return 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 int
ser_windows_send_break (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  if (SetCommBreak (h) == 0)
    return -1;

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

  if (ClearCommBreak (h))
    return -1;

  return 0;
}

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 (__FILE__, __LINE__,
			"Incorrect parity value: %d", parity);
      return -1;
    }

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

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

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

  state.BaudRate = rate;

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

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: reseting mask failed"));

  if (!SetCommMask (h, EV_RXCHAR))
    warning (_("ser_windows_wait_handle: reseting 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, bytes_read_tmp;
  HANDLE h;
  gdb_byte *p;

  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))
	bytes_read = -1;
    }

  CloseHandle (ov.hEvent);
  return bytes_read;
}

static int
ser_windows_write_prim (struct serial *scb, const void *buf, size_t len)
{
  struct ser_windows_state *state;
  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))
	bytes_written = -1;
    }

  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 occured, 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;
		}
	    }

	  /* 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;
  int event_index;
  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;
  int event_index;
  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 int
pipe_windows_open (struct serial *scb, const char *name)
{
  FILE *pex_stderr;

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

  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)
    return -1;
  ps->input = pex_input_pipe (ps->pex, 1);
  if (! ps->input)
    return -1;

  {
    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)
    return -1;
  scb->fd = fileno (ps->output);

  pex_stderr = pex_read_err (ps->pex, 1);
  if (! pex_stderr)
    return -1;
  scb->error_fd = fileno (pex_stderr);

  scb->state = ps.release ();

  return 0;
}

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)
    return -1;

  if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
    return -1;

  if (count > available)
    count = available;

  if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
    return -1;

  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)
    return -1;

  pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
  if (pipeline_in == INVALID_HANDLE_VALUE)
    return -1;

  if (! WriteFile (pipeline_in, buf, count, &written, NULL))
    return -1;

  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 occured.  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 int
net_windows_open (struct serial *scb, const char *name)
{
  struct net_windows_state *state;
  int ret;
  DWORD threadId;

  ret = net_open (scb, name);
  if (ret != 0)
    return ret;

  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);

  return 0;
}


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
};

void
_initialize_ser_windows (void)
{
  WSADATA wsa_data;
  struct serial_ops *ops;

  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);
}
