home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gdb-4.9 / gdb / ser-unix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-12  |  8.1 KB  |  393 lines

  1. /* Serial interface for local (hardwired) serial ports on Un*x like systems
  2.    Copyright 1992, 1993 Free Software Foundation, Inc.
  3.  
  4. This file is part of GDB.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "defs.h"
  21. #include "serial.h"
  22. #include <fcntl.h>
  23. #include <sys/types.h>
  24. #include <sys/time.h>
  25.  
  26. #if !defined (HAVE_TERMIOS) && !defined (HAVE_TERMIO) && !defined (HAVE_SGTTY)
  27. #define HAVE_SGTTY
  28. #endif
  29.  
  30. #ifdef HAVE_TERMIOS
  31. #include <termios.h>
  32. #include <unistd.h>
  33. #endif
  34. #ifdef HAVE_TERMIO
  35. #include <termio.h>
  36. #endif
  37. #ifdef HAVE_SGTTY
  38. #include <sgtty.h>
  39. #endif
  40.  
  41. static int hardwire_open PARAMS ((serial_t scb, const char *name));
  42. static void hardwire_raw PARAMS ((serial_t scb));
  43. static int wait_for PARAMS ((serial_t scb, int timeout));
  44. static int hardwire_readchar PARAMS ((serial_t scb, int timeout));
  45. static int rate_to_code PARAMS ((int rate));
  46. static int hardwire_setbaudrate PARAMS ((serial_t scb, int rate));
  47. static int hardwire_write PARAMS ((serial_t scb, const char *str, int len));
  48. static void hardwire_restore PARAMS ((serial_t scb));
  49. static void hardwire_close PARAMS ((serial_t scb));
  50.  
  51. /* Open up a real live device for serial I/O */
  52.  
  53. static int
  54. hardwire_open(scb, name)
  55.      serial_t scb;
  56.      const char *name;
  57. {
  58.   scb->fd = open (name, O_RDWR);
  59.   if (scb->fd < 0)
  60.     return -1;
  61.  
  62.   return 0;
  63. }
  64.  
  65. static void
  66. hardwire_raw(scb)
  67.      serial_t scb;
  68. {
  69. #ifdef HAVE_TERMIOS
  70.   struct termios termios;
  71.  
  72.   if (tcgetattr(scb->fd, &termios))
  73.     {
  74.       fprintf(stderr, "tcgetattr failed: %s\n", safe_strerror(errno));
  75.     }
  76.  
  77.   termios.c_iflag = 0;
  78.   termios.c_oflag = 0;
  79.   termios.c_lflag = 0;
  80.   termios.c_cflag &= ~(CSIZE|PARENB);
  81.   termios.c_cflag |= CS8;
  82.   termios.c_cc[VMIN] = 0;
  83.   termios.c_cc[VTIME] = 0;
  84.  
  85.   if (tcsetattr(scb->fd, TCSANOW, &termios))
  86.     {
  87.       fprintf(stderr, "tcsetattr failed: %s\n", safe_strerror(errno));
  88.     }
  89. #endif
  90.  
  91. #ifdef HAVE_TERMIO
  92.   struct termio termio;
  93.  
  94.   if (ioctl (scb->fd, TCGETA, &termio))
  95.     {
  96.       fprintf(stderr, "TCGETA failed: %s\n", safe_strerror(errno));
  97.     }
  98.  
  99.   termio.c_iflag = 0;
  100.   termio.c_oflag = 0;
  101.   termio.c_lflag = 0;
  102.   termio.c_cflag &= ~(CSIZE|PARENB);
  103.   termio.c_cflag |= CS8;
  104.   termio.c_cc[VMIN] = 0;
  105.   termio.c_cc[VTIME] = 0;
  106.  
  107.   if (ioctl (scb->fd, TCSETA, &termio))
  108.     {
  109.       fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno));
  110.     }
  111. #endif
  112.  
  113. #ifdef HAVE_SGTTY
  114.   struct sgttyb sgttyb;
  115.  
  116.   if (ioctl (scb->fd, TIOCGETP, &sgttyb))
  117.     fprintf(stderr, "TIOCGETP failed: %s\n", safe_strerror(errno));
  118.  
  119.   sgttyb.sg_flags |= RAW | ANYP;
  120.   sgttyb.sg_flags &= ~(CBREAK | ECHO);
  121.  
  122.   if (ioctl (scb->fd, TIOCSETP, &sgttyb))
  123.     fprintf(stderr, "TIOCSETP failed: %s\n", safe_strerror(errno));
  124. #endif
  125.  
  126.   scb->current_timeout = 0;
  127. }
  128.  
  129. /* Wait for input on scb, with timeout seconds.  Returns 0 on success,
  130.    otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
  131.  
  132.    For termio{s}, we actually just setup VTIME if necessary, and let the
  133.    timeout occur in the read() in hardwire_read().
  134.  */
  135.  
  136. static int
  137. wait_for(scb, timeout)
  138.      serial_t scb;
  139.      int timeout;
  140. {
  141.   int numfds;
  142.  
  143. #ifdef HAVE_SGTTY
  144.   struct timeval tv;
  145.   fd_set readfds;
  146.  
  147.   FD_ZERO (&readfds);
  148.  
  149.   tv.tv_sec = timeout;
  150.   tv.tv_usec = 0;
  151.  
  152.   FD_SET(scb->fd, &readfds);
  153.  
  154.   if (timeout >= 0)
  155.     numfds = select(scb->fd+1, &readfds, 0, 0, &tv);
  156.   else
  157.     numfds = select(scb->fd+1, &readfds, 0, 0, 0);
  158.  
  159.   if (numfds <= 0)
  160.     if (numfds == 0)
  161.       return SERIAL_TIMEOUT;
  162.     else
  163.       return SERIAL_ERROR;    /* Got an error from select or poll */
  164.  
  165.   return 0;
  166.  
  167. #endif    /* HAVE_SGTTY */
  168.  
  169. #if defined HAVE_TERMIO || defined HAVE_TERMIOS
  170.   if (timeout == scb->current_timeout)
  171.     return 0;
  172.  
  173.   {
  174. #ifdef HAVE_TERMIOS
  175.     struct termios termios;
  176.  
  177.     if (tcgetattr(scb->fd, &termios))
  178.       fprintf(stderr, "wait_for() tcgetattr failed: %s\n", safe_strerror(errno));
  179.  
  180.   termios.c_cc[VTIME] = timeout * 10;
  181.  
  182.   if (tcsetattr(scb->fd, TCSANOW, &termios))
  183.     fprintf(stderr, "wait_for() tcsetattr failed: %s\n", safe_strerror(errno));
  184. #endif    /* HAVE_TERMIOS */
  185.  
  186. #ifdef HAVE_TERMIO
  187.   struct termio termio;
  188.  
  189.   if (ioctl (scb->fd, TCGETA, &termio))
  190.     fprintf(stderr, "wait_for() TCGETA failed: %s\n", safe_strerror(errno));
  191.  
  192.   termio.c_cc[VTIME] = timeout * 10;
  193.  
  194.   if (ioctl (scb->fd, TCSETA, &termio))
  195.       fprintf(stderr, "TCSETA failed: %s\n", safe_strerror(errno));
  196. #endif    /* HAVE_TERMIO */
  197.  
  198.     scb->current_timeout = timeout;
  199.     return 0;
  200.   }
  201. #endif    /* HAVE_TERMIO || HAVE_TERMIOS */
  202. }
  203.  
  204. /* Read a character with user-specified timeout.  TIMEOUT is number of seconds
  205.    to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
  206.    char if successful.  Returns -2 if timeout expired, EOF if line dropped
  207.    dead, or -3 for any other error (see errno in that case). */
  208.  
  209. static int
  210. hardwire_readchar(scb, timeout)
  211.      serial_t scb;
  212.      int timeout;
  213. {
  214.   int status;
  215.  
  216.   if (scb->bufcnt-- > 0)
  217.     return *scb->bufp++;
  218.  
  219.   status = wait_for(scb, timeout);
  220.  
  221.   if (status < 0)
  222.     return status;
  223.  
  224.   scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
  225.  
  226.   if (scb->bufcnt <= 0)
  227.     if (scb->bufcnt == 0)
  228.       return SERIAL_TIMEOUT;    /* 0 chars means timeout [may need to
  229.                    distinguish between EOF & timeouts
  230.                    someday] */
  231.     else
  232.       return SERIAL_ERROR;    /* Got an error from read */
  233.  
  234.   scb->bufcnt--;
  235.   scb->bufp = scb->buf;
  236.   return *scb->bufp++;
  237. }
  238.  
  239. #ifndef B19200
  240. #define B19200 EXTA
  241. #endif
  242.  
  243. #ifndef B38400
  244. #define B38400 EXTB
  245. #endif
  246.  
  247. /* Translate baud rates from integers to damn B_codes.  Unix should
  248.    have outgrown this crap years ago, but even POSIX wouldn't buck it.  */
  249.  
  250. static struct
  251. {
  252.   int rate;
  253.   int code;
  254. }
  255. baudtab[] =
  256. {
  257.   {50, B50},
  258.   {75, B75},
  259.   {110, B110},
  260.   {134, B134},
  261.   {150, B150},
  262.   {200, B200},
  263.   {300, B300},
  264.   {600, B600},
  265.   {1200, B1200},
  266.   {1800, B1800},
  267.   {2400, B2400},
  268.   {4800, B4800},
  269.   {9600, B9600},
  270.   {19200, B19200},
  271.   {38400, B38400},
  272.   {-1, -1},
  273. };
  274.  
  275. static int 
  276. rate_to_code(rate)
  277.      int rate;
  278. {
  279.   int i;
  280.  
  281.   for (i = 0; baudtab[i].rate != -1; i++)
  282.     if (rate == baudtab[i].rate)  
  283.       return baudtab[i].code;
  284.  
  285.   return -1;
  286. }
  287.  
  288. static int
  289. hardwire_setbaudrate(scb, rate)
  290.      serial_t scb;
  291.      int rate;
  292. {
  293. #ifdef HAVE_TERMIOS
  294.   struct termios termios;
  295.  
  296.   if (tcgetattr (scb->fd, &termios))
  297.     return -1;
  298.  
  299.   cfsetospeed (&termios, rate_to_code (rate));
  300.   cfsetispeed (&termios, rate_to_code (rate));
  301.  
  302.   if (tcsetattr (scb->fd, TCSANOW, &termios))
  303.     return -1;
  304. #endif
  305.  
  306. #ifdef HAVE_TERMIO
  307.   struct termio termio;
  308.  
  309.   if (ioctl (scb->fd, TCGETA, &termio))
  310.     return -1;
  311.  
  312. #ifndef CIBAUD
  313. #define CIBAUD CBAUD
  314. #endif
  315.  
  316.   termio.c_cflag &= ~(CBAUD | CIBAUD);
  317.   termio.c_cflag |= rate_to_code (rate);
  318.  
  319.   if (ioctl (scb->fd, TCSETA, &termio))
  320.     return -1;
  321. #endif
  322.  
  323. #ifdef HAVE_SGTTY
  324.   struct sgttyb sgttyb;
  325.  
  326.   if (ioctl (scb->fd, TIOCGETP, &sgttyb))
  327.     return -1;
  328.  
  329.   sgttyb.sg_ispeed = rate_to_code (rate);
  330.   sgttyb.sg_ospeed = rate_to_code (rate);
  331.  
  332.   if (ioctl (scb->fd, TIOCSETP, &sgttyb))
  333.     return -1;
  334. #endif
  335.   return 0;
  336. }
  337.  
  338. static int
  339. hardwire_write(scb, str, len)
  340.      serial_t scb;
  341.      const char *str;
  342.      int len;
  343. {
  344.   int cc;
  345.  
  346.   while (len > 0)
  347.     {
  348.       cc = write(scb->fd, str, len);
  349.  
  350.       if (cc < 0)
  351.     return 1;
  352.       len -= cc;
  353.       str += cc;
  354.     }
  355.   return 0;
  356. }
  357.  
  358. static void
  359. hardwire_restore(scb)
  360.      serial_t scb;
  361. {
  362. }
  363.  
  364. static void
  365. hardwire_close(scb)
  366.      serial_t scb;
  367. {
  368.   if (scb->fd < 0)
  369.     return;
  370.  
  371.   close(scb->fd);
  372.   scb->fd = -1;
  373. }
  374.  
  375. static struct serial_ops hardwire_ops =
  376. {
  377.   "hardwire",
  378.   0,
  379.   hardwire_open,
  380.   hardwire_close,
  381.   hardwire_readchar,
  382.   hardwire_write,
  383.   hardwire_raw,
  384.   hardwire_restore,
  385.   hardwire_setbaudrate
  386. };
  387.  
  388. void
  389. _initialize_ser_hardwire ()
  390. {
  391.   serial_add_interface (&hardwire_ops);
  392. }
  393.