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

   Copyright (C) 2006-2015 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"

void _initialize_ser_windows (void);

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
static BOOL WINAPI (*CancelIo) (HANDLE);

/* 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;

  scb->current_timeout = 0;

  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 = 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 = 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 = 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 = arg;
  struct ser_console_state *state;
  int event_index;
  HANDLE h;

  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 = arg;
  struct ser_console_state *state;
  int event_index;
  HANDLE h;

  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 = arg;
  struct ser_console_state *state;
  int event_index;
  HANDLE h;

  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 = 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 = scb->state;

  if (state == NULL)
    return;

  stop_select_thread (state);
}

static void
ser_console_close (struct serial *scb)
{
  struct ser_console_state *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;
}

static void
cleanup_pipe_state (void *untyped)
{
  struct pipe_state *ps = untyped;

  free_pipe_state (ps);
}

static int
pipe_windows_open (struct serial *scb, const char *name)
{
  struct pipe_state *ps;
  FILE *pex_stderr;
  char **argv;
  struct cleanup *back_to;

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

  argv = gdb_buildargv (name);
  back_to = make_cleanup_freeargv (argv);

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

  ps = make_pipe_state ();
  make_cleanup (cleanup_pipe_state, ps);

  ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
  if (! ps->pex)
    goto fail;
  ps->input = pex_input_pipe (ps->pex, 1);
  if (! ps->input)
    goto fail;

  {
    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, 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)
    goto fail;
  scb->fd = fileno (ps->output);

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

  scb->state = (void *) ps;

  discard_cleanups (back_to);
  return 0;

 fail:
  do_cleanups (back_to);
  return -1;
}

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 = 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 = 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 = 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 = 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 = 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 = arg;
  struct net_windows_state *state;
  int event_index;

  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 = 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 = 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 = 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_base_noflush_set_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,
  ser_base_noflush_set_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_noflush_set_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_noflush_set_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 = (void *) 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);
}
