xref: /dflybsd-src/contrib/gdb-7/gdb/ser-base.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Generic serial interface functions.
25796c8dcSSimon Schubert 
3*ef5ccd6cSJohn Marino    Copyright (C) 1992-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "serial.h"
225796c8dcSSimon Schubert #include "ser-base.h"
235796c8dcSSimon Schubert #include "event-loop.h"
245796c8dcSSimon Schubert 
255796c8dcSSimon Schubert #include "gdb_select.h"
265796c8dcSSimon Schubert #include "gdb_string.h"
27*ef5ccd6cSJohn Marino #include "gdb_assert.h"
285796c8dcSSimon Schubert #include <sys/time.h>
295796c8dcSSimon Schubert #ifdef USE_WIN32API
305796c8dcSSimon Schubert #include <winsock2.h>
315796c8dcSSimon Schubert #endif
325796c8dcSSimon Schubert 
335796c8dcSSimon Schubert 
345796c8dcSSimon Schubert static timer_handler_func push_event;
355796c8dcSSimon Schubert static handler_func fd_event;
365796c8dcSSimon Schubert 
375796c8dcSSimon Schubert /* Event handling for ASYNC serial code.
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert    At any time the SERIAL device either: has an empty FIFO and is
405796c8dcSSimon Schubert    waiting on a FD event; or has a non-empty FIFO/error condition and
415796c8dcSSimon Schubert    is constantly scheduling timer events.
425796c8dcSSimon Schubert 
435796c8dcSSimon Schubert    ASYNC only stops pestering its client when it is de-async'ed or it
445796c8dcSSimon Schubert    is told to go away.  */
455796c8dcSSimon Schubert 
465796c8dcSSimon Schubert /* Value of scb->async_state: */
475796c8dcSSimon Schubert enum {
485796c8dcSSimon Schubert   /* >= 0 (TIMER_SCHEDULED) */
495796c8dcSSimon Schubert   /* The ID of the currently scheduled timer event.  This state is
505796c8dcSSimon Schubert      rarely encountered.  Timer events are one-off so as soon as the
515796c8dcSSimon Schubert      event is delivered the state is shanged to NOTHING_SCHEDULED.  */
525796c8dcSSimon Schubert   FD_SCHEDULED = -1,
535796c8dcSSimon Schubert   /* The fd_event() handler is scheduled.  It is called when ever the
545796c8dcSSimon Schubert      file descriptor becomes ready.  */
555796c8dcSSimon Schubert   NOTHING_SCHEDULED = -2
565796c8dcSSimon Schubert   /* Either no task is scheduled (just going into ASYNC mode) or a
575796c8dcSSimon Schubert      timer event has just gone off and the current state has been
585796c8dcSSimon Schubert      forced into nothing scheduled.  */
595796c8dcSSimon Schubert };
605796c8dcSSimon Schubert 
615796c8dcSSimon Schubert /* Identify and schedule the next ASYNC task based on scb->async_state
625796c8dcSSimon Schubert    and scb->buf* (the input FIFO).  A state machine is used to avoid
635796c8dcSSimon Schubert    the need to make redundant calls into the event-loop - the next
645796c8dcSSimon Schubert    scheduled task is only changed when needed.  */
655796c8dcSSimon Schubert 
66cf7f2e2dSJohn Marino static void
reschedule(struct serial * scb)675796c8dcSSimon Schubert reschedule (struct serial *scb)
685796c8dcSSimon Schubert {
695796c8dcSSimon Schubert   if (serial_is_async_p (scb))
705796c8dcSSimon Schubert     {
715796c8dcSSimon Schubert       int next_state;
72cf7f2e2dSJohn Marino 
735796c8dcSSimon Schubert       switch (scb->async_state)
745796c8dcSSimon Schubert 	{
755796c8dcSSimon Schubert 	case FD_SCHEDULED:
765796c8dcSSimon Schubert 	  if (scb->bufcnt == 0)
775796c8dcSSimon Schubert 	    next_state = FD_SCHEDULED;
785796c8dcSSimon Schubert 	  else
795796c8dcSSimon Schubert 	    {
805796c8dcSSimon Schubert 	      delete_file_handler (scb->fd);
815796c8dcSSimon Schubert 	      next_state = create_timer (0, push_event, scb);
825796c8dcSSimon Schubert 	    }
835796c8dcSSimon Schubert 	  break;
845796c8dcSSimon Schubert 	case NOTHING_SCHEDULED:
855796c8dcSSimon Schubert 	  if (scb->bufcnt == 0)
865796c8dcSSimon Schubert 	    {
875796c8dcSSimon Schubert 	      add_file_handler (scb->fd, fd_event, scb);
885796c8dcSSimon Schubert 	      next_state = FD_SCHEDULED;
895796c8dcSSimon Schubert 	    }
905796c8dcSSimon Schubert 	  else
915796c8dcSSimon Schubert 	    {
925796c8dcSSimon Schubert 	      next_state = create_timer (0, push_event, scb);
935796c8dcSSimon Schubert 	    }
945796c8dcSSimon Schubert 	  break;
955796c8dcSSimon Schubert 	default: /* TIMER SCHEDULED */
965796c8dcSSimon Schubert 	  if (scb->bufcnt == 0)
975796c8dcSSimon Schubert 	    {
985796c8dcSSimon Schubert 	      delete_timer (scb->async_state);
995796c8dcSSimon Schubert 	      add_file_handler (scb->fd, fd_event, scb);
1005796c8dcSSimon Schubert 	      next_state = FD_SCHEDULED;
1015796c8dcSSimon Schubert 	    }
1025796c8dcSSimon Schubert 	  else
1035796c8dcSSimon Schubert 	    next_state = scb->async_state;
1045796c8dcSSimon Schubert 	  break;
1055796c8dcSSimon Schubert 	}
1065796c8dcSSimon Schubert       if (serial_debug_p (scb))
1075796c8dcSSimon Schubert 	{
1085796c8dcSSimon Schubert 	  switch (next_state)
1095796c8dcSSimon Schubert 	    {
1105796c8dcSSimon Schubert 	    case FD_SCHEDULED:
1115796c8dcSSimon Schubert 	      if (scb->async_state != FD_SCHEDULED)
1125796c8dcSSimon Schubert 		fprintf_unfiltered (gdb_stdlog, "[fd%d->fd-scheduled]\n",
1135796c8dcSSimon Schubert 				    scb->fd);
1145796c8dcSSimon Schubert 	      break;
1155796c8dcSSimon Schubert 	    default: /* TIMER SCHEDULED */
1165796c8dcSSimon Schubert 	      if (scb->async_state == FD_SCHEDULED)
1175796c8dcSSimon Schubert 		fprintf_unfiltered (gdb_stdlog, "[fd%d->timer-scheduled]\n",
1185796c8dcSSimon Schubert 				    scb->fd);
1195796c8dcSSimon Schubert 	      break;
1205796c8dcSSimon Schubert 	    }
1215796c8dcSSimon Schubert 	}
1225796c8dcSSimon Schubert       scb->async_state = next_state;
1235796c8dcSSimon Schubert     }
1245796c8dcSSimon Schubert }
1255796c8dcSSimon Schubert 
126*ef5ccd6cSJohn Marino /* Run the SCB's async handle, and reschedule, if the handler doesn't
127*ef5ccd6cSJohn Marino    close SCB.  */
128*ef5ccd6cSJohn Marino 
129*ef5ccd6cSJohn Marino static void
run_async_handler_and_reschedule(struct serial * scb)130*ef5ccd6cSJohn Marino run_async_handler_and_reschedule (struct serial *scb)
131*ef5ccd6cSJohn Marino {
132*ef5ccd6cSJohn Marino   int is_open;
133*ef5ccd6cSJohn Marino 
134*ef5ccd6cSJohn Marino   /* Take a reference, so a serial_close call within the handler
135*ef5ccd6cSJohn Marino      doesn't make SCB a dangling pointer.  */
136*ef5ccd6cSJohn Marino   serial_ref (scb);
137*ef5ccd6cSJohn Marino 
138*ef5ccd6cSJohn Marino   /* Run the handler.  */
139*ef5ccd6cSJohn Marino   scb->async_handler (scb, scb->async_context);
140*ef5ccd6cSJohn Marino 
141*ef5ccd6cSJohn Marino   is_open = serial_is_open (scb);
142*ef5ccd6cSJohn Marino   serial_unref (scb);
143*ef5ccd6cSJohn Marino 
144*ef5ccd6cSJohn Marino   /* Get ready for more, if not already closed.  */
145*ef5ccd6cSJohn Marino   if (is_open)
146*ef5ccd6cSJohn Marino     reschedule (scb);
147*ef5ccd6cSJohn Marino }
148*ef5ccd6cSJohn Marino 
1495796c8dcSSimon Schubert /* FD_EVENT: This is scheduled when the input FIFO is empty (and there
1505796c8dcSSimon Schubert    is no pending error).  As soon as data arrives, it is read into the
1515796c8dcSSimon Schubert    input FIFO and the client notified.  The client should then drain
1525796c8dcSSimon Schubert    the FIFO using readchar().  If the FIFO isn't immediatly emptied,
1535796c8dcSSimon Schubert    push_event() is used to nag the client until it is.  */
1545796c8dcSSimon Schubert 
1555796c8dcSSimon Schubert static void
fd_event(int error,void * context)1565796c8dcSSimon Schubert fd_event (int error, void *context)
1575796c8dcSSimon Schubert {
1585796c8dcSSimon Schubert   struct serial *scb = context;
1595796c8dcSSimon Schubert   if (error != 0)
1605796c8dcSSimon Schubert     {
1615796c8dcSSimon Schubert       scb->bufcnt = SERIAL_ERROR;
1625796c8dcSSimon Schubert     }
1635796c8dcSSimon Schubert   else if (scb->bufcnt == 0)
1645796c8dcSSimon Schubert     {
1655796c8dcSSimon Schubert       /* Prime the input FIFO.  The readchar() function is used to
1665796c8dcSSimon Schubert          pull characters out of the buffer.  See also
1675796c8dcSSimon Schubert          generic_readchar().  */
1685796c8dcSSimon Schubert       int nr;
1695796c8dcSSimon Schubert       nr = scb->ops->read_prim (scb, BUFSIZ);
1705796c8dcSSimon Schubert       if (nr == 0)
1715796c8dcSSimon Schubert 	{
1725796c8dcSSimon Schubert 	  scb->bufcnt = SERIAL_EOF;
1735796c8dcSSimon Schubert 	}
1745796c8dcSSimon Schubert       else if (nr > 0)
1755796c8dcSSimon Schubert 	{
1765796c8dcSSimon Schubert 	  scb->bufcnt = nr;
1775796c8dcSSimon Schubert 	  scb->bufp = scb->buf;
1785796c8dcSSimon Schubert 	}
1795796c8dcSSimon Schubert       else
1805796c8dcSSimon Schubert 	{
1815796c8dcSSimon Schubert 	  scb->bufcnt = SERIAL_ERROR;
1825796c8dcSSimon Schubert 	}
1835796c8dcSSimon Schubert     }
184*ef5ccd6cSJohn Marino   run_async_handler_and_reschedule (scb);
1855796c8dcSSimon Schubert }
1865796c8dcSSimon Schubert 
1875796c8dcSSimon Schubert /* PUSH_EVENT: The input FIFO is non-empty (or there is a pending
1885796c8dcSSimon Schubert    error).  Nag the client until all the data has been read.  In the
1895796c8dcSSimon Schubert    case of errors, the client will need to close or de-async the
1905796c8dcSSimon Schubert    device before naging stops.  */
1915796c8dcSSimon Schubert 
1925796c8dcSSimon Schubert static void
push_event(void * context)1935796c8dcSSimon Schubert push_event (void *context)
1945796c8dcSSimon Schubert {
1955796c8dcSSimon Schubert   struct serial *scb = context;
196cf7f2e2dSJohn Marino 
1975796c8dcSSimon Schubert   scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
198*ef5ccd6cSJohn Marino   run_async_handler_and_reschedule (scb);
1995796c8dcSSimon Schubert }
2005796c8dcSSimon Schubert 
2015796c8dcSSimon Schubert /* Wait for input on scb, with timeout seconds.  Returns 0 on success,
2025796c8dcSSimon Schubert    otherwise SERIAL_TIMEOUT or SERIAL_ERROR.  */
2035796c8dcSSimon Schubert 
2045796c8dcSSimon Schubert static int
ser_base_wait_for(struct serial * scb,int timeout)2055796c8dcSSimon Schubert ser_base_wait_for (struct serial *scb, int timeout)
2065796c8dcSSimon Schubert {
2075796c8dcSSimon Schubert   while (1)
2085796c8dcSSimon Schubert     {
2095796c8dcSSimon Schubert       int numfds;
2105796c8dcSSimon Schubert       struct timeval tv;
2115796c8dcSSimon Schubert       fd_set readfds, exceptfds;
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert       /* NOTE: Some OS's can scramble the READFDS when the select()
2145796c8dcSSimon Schubert          call fails (ex the kernel with Red Hat 5.2).  Initialize all
2155796c8dcSSimon Schubert          arguments before each call.  */
2165796c8dcSSimon Schubert 
2175796c8dcSSimon Schubert       tv.tv_sec = timeout;
2185796c8dcSSimon Schubert       tv.tv_usec = 0;
2195796c8dcSSimon Schubert 
2205796c8dcSSimon Schubert       FD_ZERO (&readfds);
2215796c8dcSSimon Schubert       FD_ZERO (&exceptfds);
2225796c8dcSSimon Schubert       FD_SET (scb->fd, &readfds);
2235796c8dcSSimon Schubert       FD_SET (scb->fd, &exceptfds);
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert       if (timeout >= 0)
2265796c8dcSSimon Schubert 	numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
2275796c8dcSSimon Schubert       else
2285796c8dcSSimon Schubert 	numfds = gdb_select (scb->fd + 1, &readfds, 0, &exceptfds, 0);
2295796c8dcSSimon Schubert 
2305796c8dcSSimon Schubert       if (numfds <= 0)
2315796c8dcSSimon Schubert 	{
2325796c8dcSSimon Schubert 	  if (numfds == 0)
2335796c8dcSSimon Schubert 	    return SERIAL_TIMEOUT;
2345796c8dcSSimon Schubert 	  else if (errno == EINTR)
2355796c8dcSSimon Schubert 	    continue;
2365796c8dcSSimon Schubert 	  else
237c50c785cSJohn Marino 	    return SERIAL_ERROR;	/* Got an error from select or
238c50c785cSJohn Marino 					   poll.  */
2395796c8dcSSimon Schubert 	}
2405796c8dcSSimon Schubert 
2415796c8dcSSimon Schubert       return 0;
2425796c8dcSSimon Schubert     }
2435796c8dcSSimon Schubert }
2445796c8dcSSimon Schubert 
245*ef5ccd6cSJohn Marino /* Read any error output we might have.  */
246*ef5ccd6cSJohn Marino 
247*ef5ccd6cSJohn Marino static void
ser_base_read_error_fd(struct serial * scb,int close_fd)248*ef5ccd6cSJohn Marino ser_base_read_error_fd (struct serial *scb, int close_fd)
249*ef5ccd6cSJohn Marino {
250*ef5ccd6cSJohn Marino   if (scb->error_fd != -1)
251*ef5ccd6cSJohn Marino     {
252*ef5ccd6cSJohn Marino       ssize_t s;
253*ef5ccd6cSJohn Marino       char buf[GDB_MI_MSG_WIDTH + 1];
254*ef5ccd6cSJohn Marino 
255*ef5ccd6cSJohn Marino       for (;;)
256*ef5ccd6cSJohn Marino 	{
257*ef5ccd6cSJohn Marino 	  char *current;
258*ef5ccd6cSJohn Marino 	  char *newline;
259*ef5ccd6cSJohn Marino 	  int to_read = GDB_MI_MSG_WIDTH;
260*ef5ccd6cSJohn Marino 	  int num_bytes = -1;
261*ef5ccd6cSJohn Marino 
262*ef5ccd6cSJohn Marino 	  if (scb->ops->avail)
263*ef5ccd6cSJohn Marino 	    num_bytes = (scb->ops->avail)(scb, scb->error_fd);
264*ef5ccd6cSJohn Marino 
265*ef5ccd6cSJohn Marino 	  if (num_bytes != -1)
266*ef5ccd6cSJohn Marino 	    to_read = (num_bytes < to_read) ? num_bytes : to_read;
267*ef5ccd6cSJohn Marino 
268*ef5ccd6cSJohn Marino 	  if (to_read == 0)
269*ef5ccd6cSJohn Marino 	    break;
270*ef5ccd6cSJohn Marino 
271*ef5ccd6cSJohn Marino 	  s = read (scb->error_fd, &buf, to_read);
272*ef5ccd6cSJohn Marino 	  if ((s == -1) || (s == 0 && !close_fd))
273*ef5ccd6cSJohn Marino 	    break;
274*ef5ccd6cSJohn Marino 
275*ef5ccd6cSJohn Marino 	  if (s == 0 && close_fd)
276*ef5ccd6cSJohn Marino 	    {
277*ef5ccd6cSJohn Marino 	      /* End of file.  */
278*ef5ccd6cSJohn Marino 	      close (scb->error_fd);
279*ef5ccd6cSJohn Marino 	      scb->error_fd = -1;
280*ef5ccd6cSJohn Marino 	      break;
281*ef5ccd6cSJohn Marino 	    }
282*ef5ccd6cSJohn Marino 
283*ef5ccd6cSJohn Marino 	  /* In theory, embedded newlines are not a problem.
284*ef5ccd6cSJohn Marino 	     But for MI, we want each output line to have just
285*ef5ccd6cSJohn Marino 	     one newline for legibility.  So output things
286*ef5ccd6cSJohn Marino 	     in newline chunks.  */
287*ef5ccd6cSJohn Marino 	  gdb_assert (s > 0 && s <= GDB_MI_MSG_WIDTH);
288*ef5ccd6cSJohn Marino 	  buf[s] = '\0';
289*ef5ccd6cSJohn Marino 	  current = buf;
290*ef5ccd6cSJohn Marino 	  while ((newline = strstr (current, "\n")) != NULL)
291*ef5ccd6cSJohn Marino 	    {
292*ef5ccd6cSJohn Marino 	      *newline = '\0';
293*ef5ccd6cSJohn Marino 	      fputs_unfiltered (current, gdb_stderr);
294*ef5ccd6cSJohn Marino 	      fputs_unfiltered ("\n", gdb_stderr);
295*ef5ccd6cSJohn Marino 	      current = newline + 1;
296*ef5ccd6cSJohn Marino 	    }
297*ef5ccd6cSJohn Marino 
298*ef5ccd6cSJohn Marino 	  fputs_unfiltered (current, gdb_stderr);
299*ef5ccd6cSJohn Marino        }
300*ef5ccd6cSJohn Marino     }
301*ef5ccd6cSJohn Marino }
302*ef5ccd6cSJohn Marino 
3035796c8dcSSimon Schubert /* Read a character with user-specified timeout.  TIMEOUT is number of seconds
3045796c8dcSSimon Schubert    to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
3055796c8dcSSimon Schubert    char if successful.  Returns -2 if timeout expired, EOF if line dropped
3065796c8dcSSimon Schubert    dead, or -3 for any other error (see errno in that case).  */
3075796c8dcSSimon Schubert 
3085796c8dcSSimon Schubert static int
do_ser_base_readchar(struct serial * scb,int timeout)3095796c8dcSSimon Schubert do_ser_base_readchar (struct serial *scb, int timeout)
3105796c8dcSSimon Schubert {
3115796c8dcSSimon Schubert   int status;
3125796c8dcSSimon Schubert   int delta;
3135796c8dcSSimon Schubert 
3145796c8dcSSimon Schubert   /* We have to be able to keep the GUI alive here, so we break the
3155796c8dcSSimon Schubert      original timeout into steps of 1 second, running the "keep the
3165796c8dcSSimon Schubert      GUI alive" hook each time through the loop.
3175796c8dcSSimon Schubert 
3185796c8dcSSimon Schubert      Also, timeout = 0 means to poll, so we just set the delta to 0,
3195796c8dcSSimon Schubert      so we will only go through the loop once.  */
3205796c8dcSSimon Schubert 
3215796c8dcSSimon Schubert   delta = (timeout == 0 ? 0 : 1);
3225796c8dcSSimon Schubert   while (1)
3235796c8dcSSimon Schubert     {
3245796c8dcSSimon Schubert       /* N.B. The UI may destroy our world (for instance by calling
3255796c8dcSSimon Schubert          remote_stop,) in which case we want to get out of here as
3265796c8dcSSimon Schubert          quickly as possible.  It is not safe to touch scb, since
3275796c8dcSSimon Schubert          someone else might have freed it.  The
3285796c8dcSSimon Schubert          deprecated_ui_loop_hook signals that we should exit by
3295796c8dcSSimon Schubert          returning 1.  */
3305796c8dcSSimon Schubert 
3315796c8dcSSimon Schubert       if (deprecated_ui_loop_hook)
3325796c8dcSSimon Schubert 	{
3335796c8dcSSimon Schubert 	  if (deprecated_ui_loop_hook (0))
3345796c8dcSSimon Schubert 	    return SERIAL_TIMEOUT;
3355796c8dcSSimon Schubert 	}
3365796c8dcSSimon Schubert 
3375796c8dcSSimon Schubert       status = ser_base_wait_for (scb, delta);
3385796c8dcSSimon Schubert       if (timeout > 0)
3395796c8dcSSimon Schubert         timeout -= delta;
3405796c8dcSSimon Schubert 
3415796c8dcSSimon Schubert       /* If we got a character or an error back from wait_for, then we can
3425796c8dcSSimon Schubert          break from the loop before the timeout is completed.  */
3435796c8dcSSimon Schubert       if (status != SERIAL_TIMEOUT)
3445796c8dcSSimon Schubert 	break;
3455796c8dcSSimon Schubert 
3465796c8dcSSimon Schubert       /* If we have exhausted the original timeout, then generate
3475796c8dcSSimon Schubert          a SERIAL_TIMEOUT, and pass it out of the loop.  */
3485796c8dcSSimon Schubert       else if (timeout == 0)
3495796c8dcSSimon Schubert 	{
3505796c8dcSSimon Schubert 	  status = SERIAL_TIMEOUT;
3515796c8dcSSimon Schubert 	  break;
3525796c8dcSSimon Schubert 	}
353*ef5ccd6cSJohn Marino 
354*ef5ccd6cSJohn Marino       /* We also need to check and consume the stderr because it could
355*ef5ccd6cSJohn Marino 	 come before the stdout for some stubs.  If we just sit and wait
356*ef5ccd6cSJohn Marino 	 for stdout, we would hit a deadlock for that case.  */
357*ef5ccd6cSJohn Marino       ser_base_read_error_fd (scb, 0);
3585796c8dcSSimon Schubert     }
3595796c8dcSSimon Schubert 
3605796c8dcSSimon Schubert   if (status < 0)
3615796c8dcSSimon Schubert     return status;
3625796c8dcSSimon Schubert 
3635796c8dcSSimon Schubert   status = scb->ops->read_prim (scb, BUFSIZ);
3645796c8dcSSimon Schubert 
3655796c8dcSSimon Schubert   if (status <= 0)
3665796c8dcSSimon Schubert     {
3675796c8dcSSimon Schubert       if (status == 0)
3685796c8dcSSimon Schubert         return SERIAL_EOF;
3695796c8dcSSimon Schubert       else
3705796c8dcSSimon Schubert 	/* Got an error from read.  */
3715796c8dcSSimon Schubert 	return SERIAL_ERROR;
3725796c8dcSSimon Schubert     }
3735796c8dcSSimon Schubert 
3745796c8dcSSimon Schubert   scb->bufcnt = status;
3755796c8dcSSimon Schubert   scb->bufcnt--;
3765796c8dcSSimon Schubert   scb->bufp = scb->buf;
3775796c8dcSSimon Schubert   return *scb->bufp++;
3785796c8dcSSimon Schubert }
3795796c8dcSSimon Schubert 
3805796c8dcSSimon Schubert /* Perform operations common to both old and new readchar.  */
3815796c8dcSSimon Schubert 
3825796c8dcSSimon Schubert /* Return the next character from the input FIFO.  If the FIFO is
3835796c8dcSSimon Schubert    empty, call the SERIAL specific routine to try and read in more
3845796c8dcSSimon Schubert    characters.
3855796c8dcSSimon Schubert 
3865796c8dcSSimon Schubert    Initially data from the input FIFO is returned (fd_event()
3875796c8dcSSimon Schubert    pre-reads the input into that FIFO.  Once that has been emptied,
3885796c8dcSSimon Schubert    further data is obtained by polling the input FD using the device
3895796c8dcSSimon Schubert    specific readchar() function.  Note: reschedule() is called after
3905796c8dcSSimon Schubert    every read.  This is because there is no guarentee that the lower
3915796c8dcSSimon Schubert    level fd_event() poll_event() code (which also calls reschedule())
3925796c8dcSSimon Schubert    will be called.  */
3935796c8dcSSimon Schubert 
3945796c8dcSSimon Schubert int
generic_readchar(struct serial * scb,int timeout,int (do_readchar)(struct serial * scb,int timeout))3955796c8dcSSimon Schubert generic_readchar (struct serial *scb, int timeout,
3965796c8dcSSimon Schubert 		  int (do_readchar) (struct serial *scb, int timeout))
3975796c8dcSSimon Schubert {
3985796c8dcSSimon Schubert   int ch;
3995796c8dcSSimon Schubert   if (scb->bufcnt > 0)
4005796c8dcSSimon Schubert     {
4015796c8dcSSimon Schubert       ch = *scb->bufp;
4025796c8dcSSimon Schubert       scb->bufcnt--;
4035796c8dcSSimon Schubert       scb->bufp++;
4045796c8dcSSimon Schubert     }
4055796c8dcSSimon Schubert   else if (scb->bufcnt < 0)
4065796c8dcSSimon Schubert     {
4075796c8dcSSimon Schubert       /* Some errors/eof are are sticky.  */
4085796c8dcSSimon Schubert       ch = scb->bufcnt;
4095796c8dcSSimon Schubert     }
4105796c8dcSSimon Schubert   else
4115796c8dcSSimon Schubert     {
4125796c8dcSSimon Schubert       ch = do_readchar (scb, timeout);
4135796c8dcSSimon Schubert       if (ch < 0)
4145796c8dcSSimon Schubert 	{
4155796c8dcSSimon Schubert 	  switch ((enum serial_rc) ch)
4165796c8dcSSimon Schubert 	    {
4175796c8dcSSimon Schubert 	    case SERIAL_EOF:
4185796c8dcSSimon Schubert 	    case SERIAL_ERROR:
4195796c8dcSSimon Schubert 	      /* Make the error/eof stick.  */
4205796c8dcSSimon Schubert 	      scb->bufcnt = ch;
4215796c8dcSSimon Schubert 	      break;
4225796c8dcSSimon Schubert 	    case SERIAL_TIMEOUT:
4235796c8dcSSimon Schubert 	      scb->bufcnt = 0;
4245796c8dcSSimon Schubert 	      break;
4255796c8dcSSimon Schubert 	    }
4265796c8dcSSimon Schubert 	}
4275796c8dcSSimon Schubert     }
428*ef5ccd6cSJohn Marino 
4295796c8dcSSimon Schubert   /* Read any error output we might have.  */
430*ef5ccd6cSJohn Marino   ser_base_read_error_fd (scb, 1);
4315796c8dcSSimon Schubert 
4325796c8dcSSimon Schubert   reschedule (scb);
4335796c8dcSSimon Schubert   return ch;
4345796c8dcSSimon Schubert }
4355796c8dcSSimon Schubert 
4365796c8dcSSimon Schubert int
ser_base_readchar(struct serial * scb,int timeout)4375796c8dcSSimon Schubert ser_base_readchar (struct serial *scb, int timeout)
4385796c8dcSSimon Schubert {
4395796c8dcSSimon Schubert   return generic_readchar (scb, timeout, do_ser_base_readchar);
4405796c8dcSSimon Schubert }
4415796c8dcSSimon Schubert 
4425796c8dcSSimon Schubert int
ser_base_write(struct serial * scb,const char * str,int len)4435796c8dcSSimon Schubert ser_base_write (struct serial *scb, const char *str, int len)
4445796c8dcSSimon Schubert {
4455796c8dcSSimon Schubert   int cc;
4465796c8dcSSimon Schubert 
4475796c8dcSSimon Schubert   while (len > 0)
4485796c8dcSSimon Schubert     {
4495796c8dcSSimon Schubert       cc = scb->ops->write_prim (scb, str, len);
4505796c8dcSSimon Schubert 
4515796c8dcSSimon Schubert       if (cc < 0)
4525796c8dcSSimon Schubert 	return 1;
4535796c8dcSSimon Schubert       len -= cc;
4545796c8dcSSimon Schubert       str += cc;
4555796c8dcSSimon Schubert     }
4565796c8dcSSimon Schubert   return 0;
4575796c8dcSSimon Schubert }
4585796c8dcSSimon Schubert 
4595796c8dcSSimon Schubert int
ser_base_flush_output(struct serial * scb)4605796c8dcSSimon Schubert ser_base_flush_output (struct serial *scb)
4615796c8dcSSimon Schubert {
4625796c8dcSSimon Schubert   return 0;
4635796c8dcSSimon Schubert }
4645796c8dcSSimon Schubert 
4655796c8dcSSimon Schubert int
ser_base_flush_input(struct serial * scb)4665796c8dcSSimon Schubert ser_base_flush_input (struct serial *scb)
4675796c8dcSSimon Schubert {
4685796c8dcSSimon Schubert   if (scb->bufcnt >= 0)
4695796c8dcSSimon Schubert     {
4705796c8dcSSimon Schubert       scb->bufcnt = 0;
4715796c8dcSSimon Schubert       scb->bufp = scb->buf;
4725796c8dcSSimon Schubert       return 0;
4735796c8dcSSimon Schubert     }
4745796c8dcSSimon Schubert   else
4755796c8dcSSimon Schubert     return SERIAL_ERROR;
4765796c8dcSSimon Schubert }
4775796c8dcSSimon Schubert 
4785796c8dcSSimon Schubert int
ser_base_send_break(struct serial * scb)4795796c8dcSSimon Schubert ser_base_send_break (struct serial *scb)
4805796c8dcSSimon Schubert {
4815796c8dcSSimon Schubert   return 0;
4825796c8dcSSimon Schubert }
4835796c8dcSSimon Schubert 
4845796c8dcSSimon Schubert int
ser_base_drain_output(struct serial * scb)4855796c8dcSSimon Schubert ser_base_drain_output (struct serial *scb)
4865796c8dcSSimon Schubert {
4875796c8dcSSimon Schubert   return 0;
4885796c8dcSSimon Schubert }
4895796c8dcSSimon Schubert 
4905796c8dcSSimon Schubert void
ser_base_raw(struct serial * scb)4915796c8dcSSimon Schubert ser_base_raw (struct serial *scb)
4925796c8dcSSimon Schubert {
493c50c785cSJohn Marino   return;			/* Always in raw mode.  */
4945796c8dcSSimon Schubert }
4955796c8dcSSimon Schubert 
4965796c8dcSSimon Schubert serial_ttystate
ser_base_get_tty_state(struct serial * scb)4975796c8dcSSimon Schubert ser_base_get_tty_state (struct serial *scb)
4985796c8dcSSimon Schubert {
499c50c785cSJohn Marino   /* Allocate a dummy.  */
500c50c785cSJohn Marino   return (serial_ttystate) XMALLOC (int);
501c50c785cSJohn Marino }
502c50c785cSJohn Marino 
503c50c785cSJohn Marino serial_ttystate
ser_base_copy_tty_state(struct serial * scb,serial_ttystate ttystate)504c50c785cSJohn Marino ser_base_copy_tty_state (struct serial *scb, serial_ttystate ttystate)
505c50c785cSJohn Marino {
506c50c785cSJohn Marino   /* Allocate another dummy.  */
5075796c8dcSSimon Schubert   return (serial_ttystate) XMALLOC (int);
5085796c8dcSSimon Schubert }
5095796c8dcSSimon Schubert 
5105796c8dcSSimon Schubert int
ser_base_set_tty_state(struct serial * scb,serial_ttystate ttystate)5115796c8dcSSimon Schubert ser_base_set_tty_state (struct serial *scb, serial_ttystate ttystate)
5125796c8dcSSimon Schubert {
5135796c8dcSSimon Schubert   return 0;
5145796c8dcSSimon Schubert }
5155796c8dcSSimon Schubert 
5165796c8dcSSimon Schubert int
ser_base_noflush_set_tty_state(struct serial * scb,serial_ttystate new_ttystate,serial_ttystate old_ttystate)5175796c8dcSSimon Schubert ser_base_noflush_set_tty_state (struct serial *scb,
5185796c8dcSSimon Schubert 				serial_ttystate new_ttystate,
5195796c8dcSSimon Schubert 				serial_ttystate old_ttystate)
5205796c8dcSSimon Schubert {
5215796c8dcSSimon Schubert   return 0;
5225796c8dcSSimon Schubert }
5235796c8dcSSimon Schubert 
5245796c8dcSSimon Schubert void
ser_base_print_tty_state(struct serial * scb,serial_ttystate ttystate,struct ui_file * stream)5255796c8dcSSimon Schubert ser_base_print_tty_state (struct serial *scb,
5265796c8dcSSimon Schubert 			  serial_ttystate ttystate,
5275796c8dcSSimon Schubert 			  struct ui_file *stream)
5285796c8dcSSimon Schubert {
5295796c8dcSSimon Schubert   /* Nothing to print.  */
5305796c8dcSSimon Schubert   return;
5315796c8dcSSimon Schubert }
5325796c8dcSSimon Schubert 
5335796c8dcSSimon Schubert int
ser_base_setbaudrate(struct serial * scb,int rate)5345796c8dcSSimon Schubert ser_base_setbaudrate (struct serial *scb, int rate)
5355796c8dcSSimon Schubert {
5365796c8dcSSimon Schubert   return 0;			/* Never fails!  */
5375796c8dcSSimon Schubert }
5385796c8dcSSimon Schubert 
5395796c8dcSSimon Schubert int
ser_base_setstopbits(struct serial * scb,int num)5405796c8dcSSimon Schubert ser_base_setstopbits (struct serial *scb, int num)
5415796c8dcSSimon Schubert {
5425796c8dcSSimon Schubert   return 0;			/* Never fails!  */
5435796c8dcSSimon Schubert }
5445796c8dcSSimon Schubert 
5455796c8dcSSimon Schubert /* Put the SERIAL device into/out-of ASYNC mode.  */
5465796c8dcSSimon Schubert 
5475796c8dcSSimon Schubert void
ser_base_async(struct serial * scb,int async_p)5485796c8dcSSimon Schubert ser_base_async (struct serial *scb,
5495796c8dcSSimon Schubert 		int async_p)
5505796c8dcSSimon Schubert {
5515796c8dcSSimon Schubert   if (async_p)
5525796c8dcSSimon Schubert     {
5535796c8dcSSimon Schubert       /* Force a re-schedule.  */
5545796c8dcSSimon Schubert       scb->async_state = NOTHING_SCHEDULED;
5555796c8dcSSimon Schubert       if (serial_debug_p (scb))
5565796c8dcSSimon Schubert 	fprintf_unfiltered (gdb_stdlog, "[fd%d->asynchronous]\n",
5575796c8dcSSimon Schubert 			    scb->fd);
5585796c8dcSSimon Schubert       reschedule (scb);
5595796c8dcSSimon Schubert     }
5605796c8dcSSimon Schubert   else
5615796c8dcSSimon Schubert     {
5625796c8dcSSimon Schubert       if (serial_debug_p (scb))
5635796c8dcSSimon Schubert 	fprintf_unfiltered (gdb_stdlog, "[fd%d->synchronous]\n",
5645796c8dcSSimon Schubert 			    scb->fd);
5655796c8dcSSimon Schubert       /* De-schedule whatever tasks are currently scheduled.  */
5665796c8dcSSimon Schubert       switch (scb->async_state)
5675796c8dcSSimon Schubert 	{
5685796c8dcSSimon Schubert 	case FD_SCHEDULED:
5695796c8dcSSimon Schubert 	  delete_file_handler (scb->fd);
5705796c8dcSSimon Schubert 	  break;
5715796c8dcSSimon Schubert 	case NOTHING_SCHEDULED:
5725796c8dcSSimon Schubert 	  break;
5735796c8dcSSimon Schubert 	default: /* TIMER SCHEDULED */
5745796c8dcSSimon Schubert 	  delete_timer (scb->async_state);
5755796c8dcSSimon Schubert 	  break;
5765796c8dcSSimon Schubert 	}
5775796c8dcSSimon Schubert     }
5785796c8dcSSimon Schubert }
579