* spu-tdep.c: Update for unwinder changes.
[deliverable/binutils-gdb.git] / gdb / ser-unix.c
index 0b73958d82c5ce6d2c9074a3e2c6780a198a1b3f..679d23e569e71bca6ef753ef85e07d390cd32368 100644 (file)
@@ -1,12 +1,13 @@
 /* Serial interface for local (hardwired) serial ports on Un*x like systems
-   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2003,
+   2004, 2005, 2007, 2008 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 2 of the License, or
+   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,
    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, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "serial.h"
+#include "ser-base.h"
 #include "ser-unix.h"
 
 #include <fcntl.h>
@@ -29,8 +29,9 @@
 #include <sys/socket.h>
 #include <sys/time.h>
 
+#include "gdb_select.h"
 #include "gdb_string.h"
-#include "event-loop.h"
+#include "gdbcmd.h"
 
 #ifdef HAVE_TERMIOS
 
@@ -38,6 +39,18 @@ struct hardwire_ttystate
   {
     struct termios termios;
   };
+
+#ifdef CRTSCTS
+/* Boolean to explicitly enable or disable h/w flow control.  */
+static int serial_hwflow;
+static void
+show_serial_hwflow (struct ui_file *file, int from_tty,
+                   struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("Hardware flow control is %s.\n"), value);
+}
+#endif
+
 #endif /* termios */
 
 #ifdef HAVE_TERMIO
@@ -69,9 +82,6 @@ static void hardwire_raw (struct serial *scb);
 static int wait_for (struct serial *scb, int timeout);
 static int hardwire_readchar (struct serial *scb, int timeout);
 static int do_hardwire_readchar (struct serial *scb, int timeout);
-static int generic_readchar (struct serial *scb, int timeout,
-                            int (*do_readchar) (struct serial *scb,
-                                                int timeout));
 static int rate_to_code (int rate);
 static int hardwire_setbaudrate (struct serial *scb, int rate);
 static void hardwire_close (struct serial *scb);
@@ -91,15 +101,8 @@ static int hardwire_flush_input (struct serial *);
 static int hardwire_send_break (struct serial *);
 static int hardwire_setstopbits (struct serial *, int);
 
-static int do_unix_readchar (struct serial *scb, int timeout);
-static timer_handler_func push_event;
-static handler_func fd_event;
-static void reschedule (struct serial *scb);
-
 void _initialize_ser_hardwire (void);
 
-extern int (*ui_loop_hook) (int);
-
 /* Open up a real live device for serial I/O */
 
 static int
@@ -335,7 +338,7 @@ hardwire_flush_output (struct serial *scb)
 static int
 hardwire_flush_input (struct serial *scb)
 {
-  ser_unix_flush_input (scb);
+  ser_base_flush_input (scb);
 
 #ifdef HAVE_TERMIOS
   return tcflush (scb->fd, TCIFLUSH);
@@ -374,7 +377,7 @@ hardwire_send_break (struct serial *scb)
        the full length of time.  I think that is OK.  */
     timeout.tv_sec = 0;
     timeout.tv_usec = 250000;
-    select (0, 0, 0, 0, &timeout);
+    gdb_select (0, 0, 0, 0, &timeout);
     status = ioctl (scb->fd, TIOCCBRK, 0);
     return status;
   }
@@ -395,6 +398,19 @@ hardwire_raw (struct serial *scb)
   state.termios.c_lflag = 0;
   state.termios.c_cflag &= ~(CSIZE | PARENB);
   state.termios.c_cflag |= CLOCAL | CS8;
+#ifdef CRTSCTS
+  /* h/w flow control.  */
+  if (serial_hwflow)
+    state.termios.c_cflag |= CRTSCTS;
+  else
+    state.termios.c_cflag &= ~CRTSCTS;
+#ifdef CRTS_IFLOW
+  if (serial_hwflow)
+    state.termios.c_cflag |= CRTS_IFLOW;
+  else
+    state.termios.c_cflag &= ~CRTS_IFLOW;
+#endif
+#endif
   state.termios.c_cc[VMIN] = 0;
   state.termios.c_cc[VTIME] = 0;
 #endif
@@ -428,7 +444,7 @@ hardwire_raw (struct serial *scb)
  */
 
 /* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
-   ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
+   ser_base*() until the old TERMIOS/SGTTY/... timer code has been
    flushed. . */
 
 /* NOTE: cagney/1999-09-30: Much of the code below is dead.  The only
@@ -457,9 +473,9 @@ wait_for (struct serial *scb, int timeout)
       FD_SET (scb->fd, &readfds);
 
       if (timeout >= 0)
-       numfds = select (scb->fd + 1, &readfds, 0, 0, &tv);
+       numfds = gdb_select (scb->fd + 1, &readfds, 0, 0, &tv);
       else
-       numfds = select (scb->fd + 1, &readfds, 0, 0, 0);
+       numfds = gdb_select (scb->fd + 1, &readfds, 0, 0, 0);
 
       if (numfds <= 0)
        if (numfds == 0)
@@ -548,13 +564,13 @@ wait_for (struct serial *scb, int timeout)
    dropped dead, or SERIAL_ERROR for any other error (see errno in that case).  */
 
 /* FIXME: cagney/1999-09-16: Don't replace this with the equivalent
-   ser_unix*() until the old TERMIOS/SGTTY/... timer code has been
+   ser_base*() until the old TERMIOS/SGTTY/... timer code has been
    flushed. */
 
 /* NOTE: cagney/1999-09-16: This function is not identical to
-   ser_unix_readchar() as part of replacing it with ser_unix*()
+   ser_base_readchar() as part of replacing it with ser_base*()
    merging will be required - this code handles the case where read()
-   times out due to no data while ser_unix_readchar() doesn't expect
+   times out due to no data while ser_base_readchar() doesn't expect
    that. */
 
 static int
@@ -566,11 +582,12 @@ do_hardwire_readchar (struct serial *scb, int timeout)
   if (timeout > 0)
     timeout++;
 
-  /* 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. */
+  /* 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)
@@ -579,11 +596,12 @@ do_hardwire_readchar (struct serial *scb, int timeout)
       /* 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 ui_loop_hook signals that 
-         we should exit by returning 1. */
+         someone else might have freed it.  The
+         deprecated_ui_loop_hook signals that we should exit by
+         returning 1.  */
 
-      if (ui_loop_hook)
-       detach = ui_loop_hook (0);
+      if (deprecated_ui_loop_hook)
+       detach = deprecated_ui_loop_hook (0);
 
       if (detach)
        return SERIAL_TIMEOUT;
@@ -757,12 +775,12 @@ rate_to_code (int rate)
            {
              if (i)
                {
-                 warning ("Invalid baud rate %d.  Closest values are %d and %d.",
+                 warning (_("Invalid baud rate %d.  Closest values are %d and %d."),
                            rate, baudtab[i - 1].rate, baudtab[i].rate);
                }
              else
                {
-                 warning ("Invalid baud rate %d.  Minimum value is %d.",
+                 warning (_("Invalid baud rate %d.  Minimum value is %d."),
                            rate, baudtab[0].rate);
                }
              return -1;
@@ -771,7 +789,7 @@ rate_to_code (int rate)
     }
  
   /* The requested speed was too large. */
-  warning ("Invalid baud rate %d.  Maximum value is %d.",
+  warning (_("Invalid baud rate %d.  Maximum value is %d."),
             rate, baudtab[i - 1].rate);
   return -1;
 }
@@ -867,472 +885,8 @@ hardwire_close (struct serial *scb)
   close (scb->fd);
   scb->fd = -1;
 }
-
 \f
-/* Generic operations used by all UNIX/FD based serial interfaces. */
-
-serial_ttystate
-ser_unix_nop_get_tty_state (struct serial *scb)
-{
-  /* allocate a dummy */
-  return (serial_ttystate) XMALLOC (int);
-}
-
-int
-ser_unix_nop_set_tty_state (struct serial *scb, serial_ttystate ttystate)
-{
-  return 0;
-}
-
-void
-ser_unix_nop_raw (struct serial *scb)
-{
-  return;                      /* Always in raw mode */
-}
-
-/* Wait for input on scb, with timeout seconds.  Returns 0 on success,
-   otherwise SERIAL_TIMEOUT or SERIAL_ERROR. */
-
-int
-ser_unix_wait_for (struct serial *scb, int timeout)
-{
-  while (1)
-    {
-      int numfds;
-      struct timeval tv;
-      fd_set readfds, exceptfds;
-
-      /* 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);
-
-      if (timeout >= 0)
-       numfds = select (scb->fd + 1, &readfds, 0, &exceptfds, &tv);
-      else
-       numfds = select (scb->fd + 1, &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 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 -2 if timeout expired, EOF if line dropped
-   dead, or -3 for any other error (see errno in that case). */
-
-static int
-do_unix_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 ui_loop_hook signals that 
-         we should exit by returning 1. */
-
-      if (ui_loop_hook)
-       {
-         if (ui_loop_hook (0))
-           return SERIAL_TIMEOUT;
-       }
-
-      status = ser_unix_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;
-       }
-    }
-
-  if (status < 0)
-    return status;
-
-  while (1)
-    {
-      status = read (scb->fd, scb->buf, BUFSIZ);
-      if (status != -1 || errno != EINTR)
-       break;
-    }
-
-  if (status <= 0)
-    {
-      if (status == 0)
-       return SERIAL_TIMEOUT;  /* 0 chars means timeout [may need to
-                                  distinguish between EOF & timeouts
-                                  someday] */
-      else
-       return SERIAL_ERROR;    /* Got an error from read */
-    }
-
-  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. */
-
-static 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;
-           }
-       }
-    }
-  reschedule (scb);
-  return ch;
-}
-
-int
-ser_unix_readchar (struct serial *scb, int timeout)
-{
-  return generic_readchar (scb, timeout, do_unix_readchar);
-}
-
-int
-ser_unix_nop_noflush_set_tty_state (struct serial *scb,
-                                   serial_ttystate new_ttystate,
-                                   serial_ttystate old_ttystate)
-{
-  return 0;
-}
-
-void
-ser_unix_nop_print_tty_state (struct serial *scb, 
-                             serial_ttystate ttystate,
-                             struct ui_file *stream)
-{
-  /* Nothing to print.  */
-  return;
-}
-
-int
-ser_unix_nop_setbaudrate (struct serial *scb, int rate)
-{
-  return 0;                    /* Never fails! */
-}
-
-int
-ser_unix_nop_setstopbits (struct serial *scb, int num)
-{
-  return 0;                    /* Never fails! */
-}
-
-int
-ser_unix_write (struct serial *scb, const char *str, int len)
-{
-  int cc;
-
-  while (len > 0)
-    {
-      cc = write (scb->fd, str, len);
-
-      if (cc < 0)
-       return 1;
-      len -= cc;
-      str += cc;
-    }
-  return 0;
-}
-
-int
-ser_unix_nop_flush_output (struct serial *scb)
-{
-  return 0;
-}
-
-int
-ser_unix_flush_input (struct serial *scb)
-{
-  if (scb->bufcnt >= 0)
-    {
-      scb->bufcnt = 0;
-      scb->bufp = scb->buf;
-      return 0;
-    }
-  else
-    return SERIAL_ERROR;
-}
-
-int
-ser_unix_nop_send_break (struct serial *scb)
-{
-  return 0;
-}
-
-int
-ser_unix_nop_drain_output (struct serial *scb)
-{
-  return 0;
-}
-
-
 \f
-/* 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;
-    }
-}
-
-/* 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 = 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 = read (scb->fd, scb->buf, BUFSIZ);
-       }
-      while (nr == -1 && 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;
-       }
-    }
-  scb->async_handler (scb, scb->async_context);
-  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 = context;
-  scb->async_state = NOTHING_SCHEDULED; /* Timers are one-off */
-  scb->async_handler (scb, scb->async_context);
-  /* re-schedule */
-  reschedule (scb);
-}
-
-/* Put the SERIAL device into/out-of ASYNC mode.  */
-
-void
-ser_unix_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);
-    }
-  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;
-       }
-    }
-}
-
 void
 _initialize_ser_hardwire (void)
 {
@@ -1342,11 +896,11 @@ _initialize_ser_hardwire (void)
   ops->next = 0;
   ops->open = hardwire_open;
   ops->close = hardwire_close;
-  /* FIXME: Don't replace this with the equivalent ser_unix*() until
+  /* FIXME: Don't replace this with the equivalent ser_base*() until
      the old TERMIOS/SGTTY/... timer code has been flushed. cagney
      1999-09-16. */
   ops->readchar = hardwire_readchar;
-  ops->write = ser_unix_write;
+  ops->write = ser_base_write;
   ops->flush_output = hardwire_flush_output;
   ops->flush_input = hardwire_flush_input;
   ops->send_break = hardwire_send_break;
@@ -1358,6 +912,44 @@ _initialize_ser_hardwire (void)
   ops->setbaudrate = hardwire_setbaudrate;
   ops->setstopbits = hardwire_setstopbits;
   ops->drain_output = hardwire_drain_output;
-  ops->async = ser_unix_async;
+  ops->async = ser_base_async;
+  ops->read_prim = ser_unix_read_prim;
+  ops->write_prim = ser_unix_write_prim;
   serial_add_interface (ops);
+
+#ifdef HAVE_TERMIOS
+#ifdef CRTSCTS
+  add_setshow_boolean_cmd ("remoteflow", no_class,
+                          &serial_hwflow, _("\
+Set use of hardware flow control for remote serial I/O."), _("\
+Show use of hardware flow control for remote serial I/O."), _("\
+Enable or disable hardware flow control (RTS/CTS) on the serial port\n\
+when debugging using remote targets."),
+                          NULL,
+                          show_serial_hwflow,
+                          &setlist, &showlist);
+#endif
+#endif
+}
+
+int
+ser_unix_read_prim (struct serial *scb, size_t count)
+{
+  int status;
+
+  while (1)
+    {
+      status = read (scb->fd, scb->buf, count);
+      if (status != -1 || errno != EINTR)
+       break;
+    }
+  return status;
+}
+
+int
+ser_unix_write_prim (struct serial *scb, const void *buf, size_t len)
+{
+  /* ??? Historically, GDB has not retried calls to "write" that
+     result in EINTR.  */
+  return write (scb->fd, buf, len);
 }
This page took 0.046179 seconds and 4 git commands to generate.