/* Generic serial interface functions.

   Copyright (C) 1992-2019 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 "event-loop.h"

#include "gdb_select.h"
#include "gdbsupport/gdb_sys_time.h"
#ifdef USE_WIN32API
#include <winsock2.h>
#endif


static timer_handler_func push_event;
static handler_func fd_event;

/* Event handling for ASYNC serial code.

   At any time the SERIAL device either: has an empty FIFO and is
   waiting on a FD event; or has a non-empty FIFO/error condition and
   is constantly scheduling timer events.

   ASYNC only stops pestering its client when it is de-async'ed or it
   is told to go away.  */

/* Value of scb->async_state: */
enum {
  /* >= 0 (TIMER_SCHEDULED) */
  /* The ID of the currently scheduled timer event.  This state is
     rarely encountered.  Timer events are one-off so as soon as the
     event is delivered the state is shanged to NOTHING_SCHEDULED.  */
  FD_SCHEDULED = -1,
  /* The fd_event() handler is scheduled.  It is called when ever the
     file descriptor becomes ready.  */
  NOTHING_SCHEDULED = -2
  /* Either no task is scheduled (just going into ASYNC mode) or a
     timer event has just gone off and the current state has been
     forced into nothing scheduled.  */
};

/* Identify and schedule the next ASYNC task based on scb->async_state
   and scb->buf* (the input FIFO).  A state machine is used to avoid
   the need to make redundant calls into the event-loop - the next
   scheduled task is only changed when needed.  */

static void
reschedule (struct serial *scb)
{
  if (serial_is_async_p (scb))
    {
      int next_state;

      switch (scb->async_state)
	{
	case FD_SCHEDULED:
	  if (scb->bufcnt == 0)
	    next_state = FD_SCHEDULED;
	  else
	    {
	      delete_file_handler (scb->fd);
	      next_state = create_timer (0, push_event, scb);
	    }
	  break;
	case NOTHING_SCHEDULED:
	  if (scb->bufcnt == 0)
	    {
	      add_file_handler (scb->fd, fd_event, scb);
	      next_state = FD_SCHEDULED;
	    }
	  else
	    {
	      next_state = create_timer (0, push_event, scb);
	    }
	  break;
	default: /* TIMER SCHEDULED */
	  if (scb->bufcnt == 0)
	    {
	      delete_timer (scb->async_state);
	      add_file_handler (scb->fd, fd_event, scb);
	      next_state = FD_SCHEDULED;
	    }
	  else
	    next_state = scb->async_state;
	  break;
	}
      if (serial_debug_p (scb))
	{
	  switch (next_state)
	    {
	    case FD_SCHEDULED:
	      if (scb->async_state != FD_SCHEDULED)
		fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
				    scb->fd);
	      break;
	    default: /* TIMER SCHEDULED */
	      if (scb->async_state == FD_SCHEDULED)
		fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
				    scb->fd);
	      break;
	    }
	}
      scb->async_state = next_state;
    }
}

/* Run the SCB's async handle, and reschedule, if the handler doesn't
   close SCB.  */

static void
run_async_handler_and_reschedule (struct serial *scb)
{
  int is_open;

  /* Take a reference, so a serial_close call within the handler
     doesn't make SCB a dangling pointer.  */
  serial_ref (scb);

  /* Run the handler.  */
  scb->async_handler (scb, scb->async_context);

  is_open = serial_is_open (scb);
  serial_unref (scb);

  /* Get ready for more, if not already closed.  */
  if (is_open)
    reschedule (scb);
}

/* FD_EVENT: This is scheduled when the input FIFO is empty (and there
   is no pending error).  As soon as data arrives, it is read into the
   input FIFO and the client notified.  The client should then drain
   the FIFO using readchar().  If the FIFO isn't immediatly emptied,
   push_event() is used to nag the client until it is.  */

static void
fd_event (int error, void *context)
{
  struct serial *scb = (struct serial *) context;
  if (error != 0)
    {
      scb->bufcnt = SERIAL_ERROR;
    }
  else if (scb->bufcnt == 0)
    {
      /* Prime the input FIFO.  The readchar() function is used to
         pull characters out of the buffer.  See also
         generic_readchar().  */
      int nr;

      do
	{
	  nr = scb->ops->read_prim (scb, BUFSIZ);
	}
      while (nr < 0 && errno == EINTR);

      if (nr == 0)
	{
	  scb->bufcnt = SERIAL_EOF;
	}
      else if (nr > 0)
	{
	  scb->bufcnt = nr;
	  scb->bufp = scb->buf;
	}
      else
	{
	  scb->bufcnt = SERIAL_ERROR;
	}
    }
  run_async_handler_and_reschedule (scb);
}

/* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
   error).  Nag the client until all the data has been read.  In the
   case of errors, the client will need to close or de-async the
   device before naging stops.  */

static void
push_event (void *context)
{
  struct serial *scb = (struct serial *) context;

  scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
  run_async_handler_and_reschedule (scb);
}

/* Wait for input on scb, with timeout seconds.  Returns 0 on success,
   otherwise SERIAL_TIMEOUT or SERIAL_ERROR.  */

/* NOTE: Some of the code below is dead.  The only possible values of
   the TIMEOUT parameter are ONE and ZERO.  OTOH, we should probably
   get rid of the deprecated_ui_loop_hook call in do_ser_base_readchar
   instead and support infinite time outs here.  */

static int
ser_base_wait_for (struct serial *scb, int timeout)
{
  while (1)
    {
      int numfds;
      struct timeval tv;
      fd_set readfds, exceptfds;
      int nfds;

      /* NOTE: Some OS's can scramble the READFDS when the select()
         call fails (ex the kernel with Red Hat 5.2).  Initialize all
         arguments before each call.  */

      tv.tv_sec = timeout;
      tv.tv_usec = 0;

      FD_ZERO (&readfds);
      FD_ZERO (&exceptfds);
      FD_SET (scb->fd, &readfds);
      FD_SET (scb->fd, &exceptfds);

      QUIT;

      nfds = scb->fd + 1;
      if (timeout >= 0)
	numfds = interruptible_select (nfds, &readfds, 0, &exceptfds, &tv);
      else
	numfds = interruptible_select (nfds, &readfds, 0, &exceptfds, 0);

      if (numfds <= 0)
	{
	  if (numfds == 0)
	    return SERIAL_TIMEOUT;
	  else if (errno == EINTR)
	    continue;
	  else
	    return SERIAL_ERROR;	/* Got an error from select or
					   poll.  */
	}

      return 0;
    }
}

/* Read any error output we might have.  */

static void
ser_base_read_error_fd (struct serial *scb, int close_fd)
{
  if (scb->error_fd != -1)
    {
      ssize_t s;
      char buf[GDB_MI_MSG_WIDTH + 1];

      for (;;)
	{
	  char *current;
	  char *newline;
	  int to_read = GDB_MI_MSG_WIDTH;
	  int num_bytes = -1;

	  if (scb->ops->avail)
	    num_bytes = (scb->ops->avail)(scb, scb->error_fd);

	  if (num_bytes != -1)
	    to_read = (num_bytes < to_read) ? num_bytes : to_read;

	  if (to_read == 0)
	    break;

	  s = read (scb->error_fd, &buf, to_read);
	  if ((s == -1) || (s == 0 && !close_fd))
	    break;

	  if (s == 0 && close_fd)
	    {
	      /* End of file.  */
	      if (serial_is_async_p (scb))
		delete_file_handler (scb->error_fd);
	      close (scb->error_fd);
	      scb->error_fd = -1;
	      break;
	    }

	  /* In theory, embedded newlines are not a problem.
	     But for MI, we want each output line to have just
	     one newline for legibility.  So output things
	     in newline chunks.  */
	  gdb_assert (s > 0 && s <= GDB_MI_MSG_WIDTH);
	  buf[s] = '\0';
	  current = buf;
	  while ((newline = strstr (current, "\n")) != NULL)
	    {
	      *newline = '\0';
	      fputs_unfiltered (current, gdb_stderr);
	      fputs_unfiltered ("\n", gdb_stderr);
	      current = newline + 1;
	    }

	  fputs_unfiltered (current, gdb_stderr);
       }
    }
}

/* Event-loop callback for a serial's error_fd.  Flushes any error
   output we might have.  */

static void
handle_error_fd (int error, gdb_client_data client_data)
{
  serial *scb = (serial *) client_data;

  ser_base_read_error_fd (scb, 0);
}

/* Read a character with user-specified timeout.  TIMEOUT is number of
   seconds to wait, or -1 to wait forever.  Use timeout of 0 to effect
   a poll.  Returns char if successful.  Returns SERIAL_TIMEOUT if
   timeout expired, SERIAL_EOF if line dropped dead, or SERIAL_ERROR
   for any other error (see errno in that case).  */

static int
do_ser_base_readchar (struct serial *scb, int timeout)
{
  int status;
  int delta;

  /* We have to be able to keep the GUI alive here, so we break the
     original timeout into steps of 1 second, running the "keep the
     GUI alive" hook each time through the loop.

     Also, timeout = 0 means to poll, so we just set the delta to 0,
     so we will only go through the loop once.  */

  delta = (timeout == 0 ? 0 : 1);
  while (1)
    {
      /* N.B. The UI may destroy our world (for instance by calling
         remote_stop,) in which case we want to get out of here as
         quickly as possible.  It is not safe to touch scb, since
         someone else might have freed it.  The
         deprecated_ui_loop_hook signals that we should exit by
         returning 1.  */

      if (deprecated_ui_loop_hook)
	{
	  if (deprecated_ui_loop_hook (0))
	    return SERIAL_TIMEOUT;
	}

      status = ser_base_wait_for (scb, delta);
      if (timeout > 0)
        timeout -= delta;

      /* If we got a character or an error back from wait_for, then we can 
         break from the loop before the timeout is completed.  */
      if (status != SERIAL_TIMEOUT)
	break;

      /* If we have exhausted the original timeout, then generate
         a SERIAL_TIMEOUT, and pass it out of the loop.  */
      else if (timeout == 0)
	{
	  status = SERIAL_TIMEOUT;
	  break;
	}

      /* We also need to check and consume the stderr because it could
	 come before the stdout for some stubs.  If we just sit and wait
	 for stdout, we would hit a deadlock for that case.  */
      ser_base_read_error_fd (scb, 0);
    }

  if (status < 0)
    return status;

  do
    {
      status = scb->ops->read_prim (scb, BUFSIZ);
    }
  while (status < 0 && errno == EINTR);

  if (status <= 0)
    {
      if (status == 0)
        return SERIAL_EOF;
      else
	/* Got an error from read.  */
	return SERIAL_ERROR;	
    }

  scb->bufcnt = status;
  scb->bufcnt--;
  scb->bufp = scb->buf;
  return *scb->bufp++;
}

/* Perform operations common to both old and new readchar.  */

/* Return the next character from the input FIFO.  If the FIFO is
   empty, call the SERIAL specific routine to try and read in more
   characters.

   Initially data from the input FIFO is returned (fd_event()
   pre-reads the input into that FIFO.  Once that has been emptied,
   further data is obtained by polling the input FD using the device
   specific readchar() function.  Note: reschedule() is called after
   every read.  This is because there is no guarentee that the lower
   level fd_event() poll_event() code (which also calls reschedule())
   will be called.  */

int
generic_readchar (struct serial *scb, int timeout,
		  int (do_readchar) (struct serial *scb, int timeout))
{
  int ch;
  if (scb->bufcnt > 0)
    {
      ch = *scb->bufp;
      scb->bufcnt--;
      scb->bufp++;
    }
  else if (scb->bufcnt < 0)
    {
      /* Some errors/eof are are sticky.  */
      ch = scb->bufcnt;
    }
  else
    {
      ch = do_readchar (scb, timeout);
      if (ch < 0)
	{
	  switch ((enum serial_rc) ch)
	    {
	    case SERIAL_EOF:
	    case SERIAL_ERROR:
	      /* Make the error/eof stick.  */
	      scb->bufcnt = ch;
	      break;
	    case SERIAL_TIMEOUT:
	      scb->bufcnt = 0;
	      break;
	    }
	}
    }

  /* Read any error output we might have.  */
  ser_base_read_error_fd (scb, 1);

  reschedule (scb);
  return ch;
}

int
ser_base_readchar (struct serial *scb, int timeout)
{
  return generic_readchar (scb, timeout, do_ser_base_readchar);
}

int
ser_base_write (struct serial *scb, const void *buf, size_t count)
{
  const char *str = (const char *) buf;
  int cc;

  while (count > 0)
    {
      QUIT;

      cc = scb->ops->write_prim (scb, str, count);

      if (cc < 0)
	{
	  if (errno == EINTR)
	    continue;
	  return 1;
	}
      count -= cc;
      str += cc;
    }
  return 0;
}

int
ser_base_flush_output (struct serial *scb)
{
  return 0;
}

int
ser_base_flush_input (struct serial *scb)
{
  if (scb->bufcnt >= 0)
    {
      scb->bufcnt = 0;
      scb->bufp = scb->buf;
      return 0;
    }
  else
    return SERIAL_ERROR;
}

int
ser_base_send_break (struct serial *scb)
{
  return 0;
}

int
ser_base_drain_output (struct serial *scb)
{
  return 0;
}

void
ser_base_raw (struct serial *scb)
{
  return;			/* Always in raw mode.  */
}

serial_ttystate
ser_base_get_tty_state (struct serial *scb)
{
  /* Allocate a dummy.  */
  return (serial_ttystate) XNEW (int);
}

serial_ttystate
ser_base_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
{
  /* Allocate another dummy.  */
  return (serial_ttystate) XNEW (int);
}

int
ser_base_set_tty_state (struct serial *scb, serial_ttystate ttystate)
{
  return 0;
}

void
ser_base_print_tty_state (struct serial *scb, 
			  serial_ttystate ttystate,
			  struct ui_file *stream)
{
  /* Nothing to print.  */
  return;
}

int
ser_base_setbaudrate (struct serial *scb, int rate)
{
  return 0;			/* Never fails!  */
}

int
ser_base_setstopbits (struct serial *scb, int num)
{
  return 0;			/* Never fails!  */
}

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

int
ser_base_setparity (struct serial *scb, int parity)
{
  return 0;			/* Never fails!  */
}

/* Put the SERIAL device into/out-of ASYNC mode.  */

void
ser_base_async (struct serial *scb,
		int async_p)
{
  if (async_p)
    {
      /* Force a re-schedule.  */
      scb->async_state = NOTHING_SCHEDULED;
      if (serial_debug_p (scb))
	fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
			    scb->fd);
      reschedule (scb);

      if (scb->error_fd != -1)
	add_file_handler (scb->error_fd, handle_error_fd, scb);
    }
  else
    {
      if (serial_debug_p (scb))
	fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
			    scb->fd);
      /* De-schedule whatever tasks are currently scheduled.  */
      switch (scb->async_state)
	{
	case FD_SCHEDULED:
	  delete_file_handler (scb->fd);
	  break;
	case NOTHING_SCHEDULED:
	  break;
	default: /* TIMER SCHEDULED */
	  delete_timer (scb->async_state);
	  break;
	}

      if (scb->error_fd != -1)
	delete_file_handler (scb->error_fd);
    }
}
