home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / GDB / GDB-4.13 / GDB-4 / gdb-4.13 / gdb / ser-tcp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-02  |  6.8 KB  |  322 lines

  1. /* Serial interface for raw TCP connections 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 <sys/types.h>
  23. #include <sys/time.h>
  24. #include <netinet/in.h>
  25. #include <arpa/inet.h>
  26. #include <netdb.h>
  27. #include <sys/socket.h>
  28. #include <netinet/tcp.h>
  29. #include "signals.h"
  30.  
  31. struct tcp_ttystate
  32. {
  33.   int bogus;
  34. };
  35.  
  36. static int tcp_open PARAMS ((serial_t scb, const char *name));
  37. static void tcp_raw PARAMS ((serial_t scb));
  38. static int wait_for PARAMS ((serial_t scb, int timeout));
  39. static int tcp_readchar PARAMS ((serial_t scb, int timeout));
  40. static int tcp_setbaudrate PARAMS ((serial_t scb, int rate));
  41. static int tcp_write PARAMS ((serial_t scb, const char *str, int len));
  42. /* FIXME: static void tcp_restore PARAMS ((serial_t scb)); */
  43. static void tcp_close PARAMS ((serial_t scb));
  44. static serial_ttystate tcp_get_tty_state PARAMS ((serial_t scb));
  45. static int tcp_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
  46.  
  47. /* Open up a raw tcp socket */
  48.  
  49. static int
  50. tcp_open(scb, name)
  51.      serial_t scb;
  52.      const char *name;
  53. {
  54.   char *port_str;
  55.   int port;
  56.   struct hostent *hostent;
  57.   struct sockaddr_in sockaddr;
  58.   int tmp;
  59.   char hostname[100];
  60.   struct protoent *protoent;
  61.  
  62.   port_str = strchr (name, ':');
  63.  
  64.   if (!port_str)
  65.     error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */
  66.  
  67.   tmp = min (port_str - name, sizeof hostname - 1);
  68.   strncpy (hostname, name, tmp); /* Don't want colon */
  69.   hostname[tmp] = '\000';    /* Tie off host name */
  70.   port = atoi (port_str + 1);
  71.  
  72.   hostent = gethostbyname (hostname);
  73.  
  74.   if (!hostent)
  75.     {
  76.       fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
  77.       errno = ENOENT;
  78.       return -1;
  79.     }
  80.  
  81.   scb->fd = socket (PF_INET, SOCK_STREAM, 0);
  82.   if (scb->fd < 0)
  83.     return -1;
  84.  
  85.   /* Allow rapid reuse of this port. */
  86.   tmp = 1;
  87.   setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp));
  88.  
  89.   /* Enable TCP keep alive process. */
  90.   tmp = 1;
  91.   setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
  92.  
  93.   sockaddr.sin_family = PF_INET;
  94.   sockaddr.sin_port = htons(port);
  95.   memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
  96.       sizeof (struct in_addr));
  97.  
  98.   if (connect (scb->fd, &sockaddr, sizeof(sockaddr)))
  99.     {
  100.       close(scb->fd);
  101.       scb->fd = -1;
  102.       return -1;
  103.     }
  104.  
  105.   protoent = getprotobyname ("tcp");
  106.   if (!protoent)
  107.     return -1;
  108.  
  109.   tmp = 1;
  110.   if (setsockopt (scb->fd, protoent->p_proto, TCP_NODELAY,
  111.           (char *)&tmp, sizeof(tmp)))
  112.     return -1;
  113.  
  114.   signal(SIGPIPE, SIG_IGN);    /* If we don't do this, then GDB simply exits
  115.                    when the remote side dies.  */
  116.  
  117.   return 0;
  118. }
  119.  
  120. static serial_ttystate
  121. tcp_get_tty_state(scb)
  122.      serial_t scb;
  123. {
  124.   struct tcp_ttystate *state;
  125.  
  126.   state = (struct tcp_ttystate *)xmalloc(sizeof *state);
  127.  
  128.   return (serial_ttystate)state;
  129. }
  130.  
  131. static int
  132. tcp_set_tty_state(scb, ttystate)
  133.      serial_t scb;
  134.      serial_ttystate ttystate;
  135. {
  136.   struct tcp_ttystate *state;
  137.  
  138.   state = (struct tcp_ttystate *)ttystate;
  139.  
  140.   return 0;
  141. }
  142.  
  143. static int
  144. tcp_return_0 (scb)
  145.      serial_t scb;
  146. {
  147.   return 0;
  148. }
  149.  
  150. static void
  151. tcp_raw(scb)
  152.      serial_t scb;
  153. {
  154.   return;            /* Always in raw mode */
  155. }
  156.  
  157. /* Wait for input on scb, with timeout seconds.  Returns 0 on success,
  158.    otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
  159.  
  160.    For termio{s}, we actually just setup VTIME if necessary, and let the
  161.    timeout occur in the read() in tcp_read().
  162.  */
  163.  
  164. static int
  165. wait_for(scb, timeout)
  166.      serial_t scb;
  167.      int timeout;
  168. {
  169.   int numfds;
  170.   struct timeval tv;
  171.   fd_set readfds, exceptfds;
  172.  
  173.   FD_ZERO (&readfds);
  174.   FD_ZERO (&exceptfds);
  175.  
  176.   tv.tv_sec = timeout;
  177.   tv.tv_usec = 0;
  178.  
  179.   FD_SET(scb->fd, &readfds);
  180.   FD_SET(scb->fd, &exceptfds);
  181.  
  182.   while (1)
  183.     {
  184.       if (timeout >= 0)
  185.     numfds = select(scb->fd+1, &readfds, 0, &exceptfds, &tv);
  186.       else
  187.     numfds = select(scb->fd+1, &readfds, 0, &exceptfds, 0);
  188.  
  189.       if (numfds <= 0)
  190.     if (numfds == 0)
  191.       return SERIAL_TIMEOUT;
  192.     else if (errno == EINTR)
  193.       continue;
  194.     else
  195.       return SERIAL_ERROR;    /* Got an error from select or poll */
  196.  
  197.       return 0;
  198.     }
  199. }
  200.  
  201. /* Read a character with user-specified timeout.  TIMEOUT is number of seconds
  202.    to wait, or -1 to wait forever.  Use timeout of 0 to effect a poll.  Returns
  203.    char if successful.  Returns -2 if timeout expired, EOF if line dropped
  204.    dead, or -3 for any other error (see errno in that case). */
  205.  
  206. static int
  207. tcp_readchar(scb, timeout)
  208.      serial_t scb;
  209.      int timeout;
  210. {
  211.   int status;
  212.  
  213.   if (scb->bufcnt-- > 0)
  214.     return *scb->bufp++;
  215.  
  216.   status = wait_for(scb, timeout);
  217.  
  218.   if (status < 0)
  219.     return status;
  220.  
  221.   while (1)
  222.     {
  223.       scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
  224.       if (scb->bufcnt != -1 || errno != EINTR)
  225.     break;
  226.     }
  227.  
  228.   if (scb->bufcnt <= 0)
  229.     if (scb->bufcnt == 0)
  230.       return SERIAL_TIMEOUT;    /* 0 chars means timeout [may need to
  231.                    distinguish between EOF & timeouts
  232.                    someday] */
  233.     else
  234.       return SERIAL_ERROR;    /* Got an error from read */
  235.  
  236.   scb->bufcnt--;
  237.   scb->bufp = scb->buf;
  238.   return *scb->bufp++;
  239. }
  240.  
  241. static int
  242. tcp_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
  243.      serial_t scb;
  244.      serial_ttystate new_ttystate;
  245.      serial_ttystate old_ttystate;
  246. {
  247.   return 0;
  248. }
  249.  
  250. static void
  251. tcp_print_tty_state (scb, ttystate)
  252.      serial_t scb;
  253.      serial_ttystate ttystate;
  254. {
  255.   /* Nothing to print.  */
  256.   return;
  257. }
  258.  
  259. static int
  260. tcp_setbaudrate(scb, rate)
  261.      serial_t scb;
  262.      int rate;
  263. {
  264.   return 0;            /* Never fails! */
  265. }
  266.  
  267. static int
  268. tcp_write(scb, str, len)
  269.      serial_t scb;
  270.      const char *str;
  271.      int len;
  272. {
  273.   int cc;
  274.  
  275.   while (len > 0)
  276.     {
  277.       cc = write(scb->fd, str, len);
  278.  
  279.       if (cc < 0)
  280.     return 1;
  281.       len -= cc;
  282.       str += cc;
  283.     }
  284.   return 0;
  285. }
  286.  
  287. static void
  288. tcp_close(scb)
  289.      serial_t scb;
  290. {
  291.   if (scb->fd < 0)
  292.     return;
  293.  
  294.   close(scb->fd);
  295.   scb->fd = -1;
  296. }
  297.  
  298. static struct serial_ops tcp_ops =
  299. {
  300.   "tcp",
  301.   0,
  302.   tcp_open,
  303.   tcp_close,
  304.   tcp_readchar,
  305.   tcp_write,
  306.   tcp_return_0, /* flush output */
  307.   tcp_return_0, /* flush input */
  308.   tcp_return_0, /* send break */
  309.   tcp_raw,
  310.   tcp_get_tty_state,
  311.   tcp_set_tty_state,
  312.   tcp_print_tty_state,
  313.   tcp_noflush_set_tty_state,
  314.   tcp_setbaudrate,
  315. };
  316.  
  317. void
  318. _initialize_ser_tcp ()
  319. {
  320.   serial_add_interface (&tcp_ops);
  321. }
  322.