* gdb/testsuite: Initial creation of gdb/testsuite.
[deliverable/binutils-gdb.git] / gdb / ser-termios.c
index 3bf8f172bb19675e7137a2970a79dc72351c2d1a..b759632f8a36294c5bc15eea5d36a33c598fde25 100644 (file)
@@ -1,7 +1,5 @@
-/* Remote serial interface for OS's with termios
-
-   Copyright 1992
-   Free Software Foundation, Inc.
+/* Remote serial interface for OS's with termios, for GDB.
+   Copyright 1992 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -20,189 +18,206 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
-#include "serial.h"
 #include <fcntl.h>
-#include <termios.h>
 #include <sys/time.h>
+#include "serial.h"
 
-static int desc;
-
-
-CONST char *
-DEFUN_VOID(serial_default_name)
-{
-  return "/dev/ttya";
-}
+static int desc = -1;
 
 void
-DEFUN_VOID(serial_raw)
+serial_raw(fd, oldstate)
+     int fd;
+     struct ttystate *oldstate;
 {
-  /* Now happens inside of serial_open */
-}
+  struct termios termios;
 
-static struct termios otermios;
-static int oflags;
+  oldstate->flags = fcntl(fd, F_GETFL, 0);
 
-void
-DEFUN_VOID(serial_normal)
-{
-  fcntl(desc, oflags, 0);
+  fcntl(fd, F_SETFL, oldstate->flags|FNDELAY);
 
-  if (tcsetattr(desc, TCSANOW, &otermios))
+  if (tcgetattr(fd, &termios))
     {
-      printf("tcgetattr failed: errno=%d\n", errno);
+      fprintf(stderr, "tcgetattr failed: %s\n", safe_strerror(errno));
+    }
+
+  oldstate->termios = termios;
+
+  termios.c_iflag = 0;
+  termios.c_oflag = 0;
+  termios.c_lflag = 0;
+  termios.c_cc[VMIN] = 0;
+  termios.c_cc[VTIME] = 0;
+
+  if (tcsetattr(fd, TCSANOW, &termios))
+    {
+      fprintf(stderr, "tcsetattr failed: %s\n", safe_strerror(errno));
     }
 }
 
+void
+serial_restore(fd, oldstate)
+     int fd;
+     struct ttystate *oldstate;
+{
+  fcntl(fd, F_SETFL, oldstate->flags);
+
+  tcsetattr(fd, TCSANOW, &oldstate->termios);
+}
+
+static struct ttystate oldstate;
+
+static fd_set readfds;
+
 int
-DEFUN(serial_open,(name),
-      CONST char *name)
+serial_open(name)
+     const char *name;
 {
   struct termios termios;
 
   desc = open (name, O_RDWR);
   if (desc < 0)
-   perror("Open failed: ");
-
-  oflags = fcntl(desc, F_GETFL, 0);
-
-  fcntl(desc, F_SETFL, oflags|FNDELAY);
-
-  if (tcgetattr(desc, &termios)) {
-    printf("tcgetattr failed: errno=%d\n", errno);
-  }
+    error("Open of %s failed: %s", name, safe_strerror(errno));
 
-  otermios = termios;
+  serial_raw(desc, &oldstate);
 
-  termios.c_iflag = 0;
-  termios.c_oflag = 0;
-  termios.c_lflag = 0;
-  termios.c_cc[VMIN] = 0;
-  termios.c_cc[VTIME] = 0;
+/* Setup constant stuff for select */
 
-  if (tcsetattr(desc, TCSANOW, &termios)) {
-    printf("tcgetattr failed: errno=%d\n", errno);
-  }
+  FD_ZERO(&readfds);
 
-  return 1;
+  return desc;
 }
 
+/* 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). */
+
 int
-DEFUN(serial_timedreadchar,(timeout, ok),
-      int timeout AND
-      int *ok)
+serial_readchar(timeout)
+     int timeout;
 {
-  unsigned char buf;
-  fd_set readfds;
-  int val;
+  static unsigned char buf[BUFSIZ];
+  static unsigned char *bufp;
+  static int bufcnt = 0;
+  int numfds;
   struct timeval tv;
 
-  FD_ZERO(&readfds);
-  FD_SET(desc, &readfds);
+  if (bufcnt-- > 0)
+    return *bufp++;
 
   tv.tv_sec = timeout;
   tv.tv_usec = 0;
 
-  val = select(desc+1, &readfds, 0, 0, &tv);
+  FD_SET(desc, &readfds);
 
-  if (val > 0 && FD_ISSET(desc, &readfds))
-    {
-      val = read (desc, &buf, 1);
+  if (timeout >= 0)
+    numfds = select(desc+1, &readfds, 0, 0, &tv);
+  else
+    numfds = select(desc+1, &readfds, 0, 0, 0);
 
-      if (val == 1)
-       {
-         *ok = 1;
-         return buf;
-       }
-    }
+  if (numfds <= 0)
+    if (numfds == 0)
+      return -2;               /* Timeout */
+    else
+      return -3;               /* Got an error from select */
+
+  bufcnt = read(desc, buf, BUFSIZ);
 
-  *ok = 0;
+  if (bufcnt <= 0)
+    if (bufcnt == 0)
+      return EOF;              /* 0 chars means end of file */
+    else
+      return -3;               /* Got an error from read */
 
-  return 0;
+  bufcnt--;
+  bufp = buf;
+  return *bufp++;
 }
 
 /* Translate baud rates from integers to damn B_codes.  Unix should
    have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
 
-#ifndef B19200
-#define B19200 EXTA
-#endif
-#ifndef B38400
-#define B38400 EXTB
-#endif
-
-static struct {int rate, damn_b;} baudtab[] = {
-       {9600, B9600},
-
-       {19200, B19200},
-#if 0
-       {300, B300},
-       {1200, B1200},
-       {2400, B2400},
-       {4800, B4800},
-#endif
-       {-1, -1},
+static struct
+{
+  int rate;
+  int code;
+} baudtab[] = {
+  {50, B50},
+  {75, B75},
+  {110, B110},
+  {134, B134},
+  {150, B150},
+  {200, B200},
+  {300, B300},
+  {600, B600},
+  {1200, B1200},
+  {1800, B1800},
+  {2400, B2400},
+  {4800, B4800},
+  {9600, B9600},
+  {19200, B19200},
+  {38400, B38400},
+  {-1, -1},
 };
 
 static int 
-DEFUN(damn_b,(rate),
-      int rate)
+rate_to_code(rate)
+     int rate;
 {
   int i;
+
   for (i = 0; baudtab[i].rate != -1; i++)
-  {
     if (rate == baudtab[i].rate)  
-    {
-      return i;
-    }
-  }
+      return baudtab[i].code;
+
   return -1;
 }
 
-int 
-DEFUN(serial_setbaudrate,(rate),int rate)
+int
+serial_setbaudrate(rate)
+     int rate;
 {
   struct termios termios;
 
-  if (tcgetattr(desc, &termios)) {
-    printf("tcgetattr failed: errno=%d\n", errno);
-  }
+  if (tcgetattr(desc, &termios))
+    error("tcgetattr failed: %s\n", safe_strerror(errno));
 
-  cfsetospeed(&termios, baudtab[damn_b(rate)].damn_b);
-  cfsetispeed(&termios, baudtab[damn_b(rate)].damn_b);
+  cfsetospeed(&termios, rate_to_code(rate));
+  cfsetispeed(&termios, rate_to_code(rate));
 
-  if (tcsetattr(desc, TCSANOW, &termios)) {
-    printf("tcgetattr failed: errno=%d\n", errno);
-  }
+  if (tcsetattr(desc, TCSANOW, &termios))
+    error("tcsetattr failed: %s\n", safe_strerror(errno));
 
   return 1;
 }
 
 int
-DEFUN(serial_nextbaudrate,(rate),
-      int rate)
+serial_write(str, len)
+     const char *str;
+     int len;
 {
-  int lookup;
-  lookup = damn_b(rate);
-  if (lookup == -1)
-   return baudtab[0].rate;
-  lookup++;
-  if (baudtab[lookup].rate == -1)
-   return baudtab[0].rate;
-  return baudtab[lookup].rate;
+  int cc;
+
+  while (len > 0)
+    {
+      cc = write(desc, str, len);
+
+      if (cc < 0)
+       return 0;
+      len -= cc;
+      str += cc;
+    }
+  return 1;
 }
 
-int
-DEFUN(serial_write,(str, len),
-      CONST char *str AND
-      int len)
+void
+serial_close()
 {
-  return (write (desc, str, len));
-}
+  if (desc < 0)
+    return;
 
+  serial_restore(desc, &oldstate);
 
-int
-DEFUN_VOID(serial_close)
-{
-  return (close(desc));
+  close(desc);
+  desc = -1;
 }
This page took 0.026319 seconds and 4 git commands to generate.