xref: /dflybsd-src/contrib/gdb-7/gdb/ser-tcp.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
15796c8dcSSimon Schubert /* Serial interface for raw TCP connections on Un*x like systems.
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 "ser-tcp.h"
245796c8dcSSimon Schubert #include "gdbcmd.h"
255796c8dcSSimon Schubert #include "cli/cli-decode.h"
265796c8dcSSimon Schubert #include "cli/cli-setshow.h"
275796c8dcSSimon Schubert 
285796c8dcSSimon Schubert #include <sys/types.h>
295796c8dcSSimon Schubert 
305796c8dcSSimon Schubert #ifdef HAVE_SYS_FILIO_H
315796c8dcSSimon Schubert #include <sys/filio.h>  /* For FIONBIO.  */
325796c8dcSSimon Schubert #endif
335796c8dcSSimon Schubert #ifdef HAVE_SYS_IOCTL_H
345796c8dcSSimon Schubert #include <sys/ioctl.h>  /* For FIONBIO.  */
355796c8dcSSimon Schubert #endif
365796c8dcSSimon Schubert 
375796c8dcSSimon Schubert #include <sys/time.h>
385796c8dcSSimon Schubert 
395796c8dcSSimon Schubert #ifdef USE_WIN32API
405796c8dcSSimon Schubert #include <winsock2.h>
41a45ae5f8SJohn Marino #ifndef ETIMEDOUT
425796c8dcSSimon Schubert #define ETIMEDOUT WSAETIMEDOUT
43a45ae5f8SJohn Marino #endif
445796c8dcSSimon Schubert #define close(fd) closesocket (fd)
455796c8dcSSimon Schubert #define ioctl ioctlsocket
465796c8dcSSimon Schubert #else
475796c8dcSSimon Schubert #include <netinet/in.h>
485796c8dcSSimon Schubert #include <arpa/inet.h>
495796c8dcSSimon Schubert #include <netdb.h>
505796c8dcSSimon Schubert #include <sys/socket.h>
515796c8dcSSimon Schubert #include <netinet/tcp.h>
525796c8dcSSimon Schubert #endif
535796c8dcSSimon Schubert 
545796c8dcSSimon Schubert #include <signal.h>
555796c8dcSSimon Schubert #include "gdb_string.h"
565796c8dcSSimon Schubert #include "gdb_select.h"
575796c8dcSSimon Schubert 
585796c8dcSSimon Schubert #ifndef HAVE_SOCKLEN_T
595796c8dcSSimon Schubert typedef int socklen_t;
605796c8dcSSimon Schubert #endif
615796c8dcSSimon Schubert 
625796c8dcSSimon Schubert void _initialize_ser_tcp (void);
635796c8dcSSimon Schubert 
645796c8dcSSimon Schubert /* For "set tcp" and "show tcp".  */
655796c8dcSSimon Schubert 
665796c8dcSSimon Schubert static struct cmd_list_element *tcp_set_cmdlist;
675796c8dcSSimon Schubert static struct cmd_list_element *tcp_show_cmdlist;
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert /* Whether to auto-retry refused connections.  */
705796c8dcSSimon Schubert 
715796c8dcSSimon Schubert static int tcp_auto_retry = 1;
725796c8dcSSimon Schubert 
735796c8dcSSimon Schubert /* Timeout period for connections, in seconds.  */
745796c8dcSSimon Schubert 
75*ef5ccd6cSJohn Marino static unsigned int tcp_retry_limit = 15;
765796c8dcSSimon Schubert 
77c50c785cSJohn Marino /* How many times per second to poll deprecated_ui_loop_hook.  */
785796c8dcSSimon Schubert 
795796c8dcSSimon Schubert #define POLL_INTERVAL 5
805796c8dcSSimon Schubert 
815796c8dcSSimon Schubert /* Helper function to wait a while.  If SCB is non-null, wait on its
825796c8dcSSimon Schubert    file descriptor.  Otherwise just wait on a timeout, updating *POLLS.
835796c8dcSSimon Schubert    Returns -1 on timeout or interrupt, otherwise the value of select.  */
845796c8dcSSimon Schubert 
855796c8dcSSimon Schubert static int
wait_for_connect(struct serial * scb,int * polls)865796c8dcSSimon Schubert wait_for_connect (struct serial *scb, int *polls)
875796c8dcSSimon Schubert {
885796c8dcSSimon Schubert   struct timeval t;
895796c8dcSSimon Schubert   int n;
905796c8dcSSimon Schubert 
915796c8dcSSimon Schubert   /* While we wait for the connect to complete,
925796c8dcSSimon Schubert      poll the UI so it can update or the user can
935796c8dcSSimon Schubert      interrupt.  */
945796c8dcSSimon Schubert   if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
955796c8dcSSimon Schubert     {
965796c8dcSSimon Schubert       errno = EINTR;
975796c8dcSSimon Schubert       return -1;
985796c8dcSSimon Schubert     }
995796c8dcSSimon Schubert 
1005796c8dcSSimon Schubert   /* Check for timeout.  */
1015796c8dcSSimon Schubert   if (*polls > tcp_retry_limit * POLL_INTERVAL)
1025796c8dcSSimon Schubert     {
1035796c8dcSSimon Schubert       errno = ETIMEDOUT;
1045796c8dcSSimon Schubert       return -1;
1055796c8dcSSimon Schubert     }
1065796c8dcSSimon Schubert 
1075796c8dcSSimon Schubert   /* Back off to polling once per second after the first POLL_INTERVAL
1085796c8dcSSimon Schubert      polls.  */
1095796c8dcSSimon Schubert   if (*polls < POLL_INTERVAL)
1105796c8dcSSimon Schubert     {
1115796c8dcSSimon Schubert       t.tv_sec = 0;
1125796c8dcSSimon Schubert       t.tv_usec = 1000000 / POLL_INTERVAL;
1135796c8dcSSimon Schubert     }
1145796c8dcSSimon Schubert   else
1155796c8dcSSimon Schubert     {
1165796c8dcSSimon Schubert       t.tv_sec = 1;
1175796c8dcSSimon Schubert       t.tv_usec = 0;
1185796c8dcSSimon Schubert     }
1195796c8dcSSimon Schubert 
1205796c8dcSSimon Schubert   if (scb)
1215796c8dcSSimon Schubert     {
1225796c8dcSSimon Schubert       fd_set rset, wset, eset;
123cf7f2e2dSJohn Marino 
1245796c8dcSSimon Schubert       FD_ZERO (&rset);
1255796c8dcSSimon Schubert       FD_SET (scb->fd, &rset);
1265796c8dcSSimon Schubert       wset = rset;
1275796c8dcSSimon Schubert       eset = rset;
1285796c8dcSSimon Schubert 
1295796c8dcSSimon Schubert       /* POSIX systems return connection success or failure by signalling
1305796c8dcSSimon Schubert 	 wset.  Windows systems return success in wset and failure in
1315796c8dcSSimon Schubert 	 eset.
1325796c8dcSSimon Schubert 
1335796c8dcSSimon Schubert 	 We must call select here, rather than gdb_select, because
1345796c8dcSSimon Schubert 	 the serial structure has not yet been initialized - the
1355796c8dcSSimon Schubert 	 MinGW select wrapper will not know that this FD refers
1365796c8dcSSimon Schubert 	 to a socket.  */
1375796c8dcSSimon Schubert       n = select (scb->fd + 1, &rset, &wset, &eset, &t);
1385796c8dcSSimon Schubert     }
1395796c8dcSSimon Schubert   else
1405796c8dcSSimon Schubert     /* Use gdb_select here, since we have no file descriptors, and on
1415796c8dcSSimon Schubert        Windows, plain select doesn't work in that case.  */
1425796c8dcSSimon Schubert     n = gdb_select (0, NULL, NULL, NULL, &t);
1435796c8dcSSimon Schubert 
1445796c8dcSSimon Schubert   /* If we didn't time out, only count it as one poll.  */
1455796c8dcSSimon Schubert   if (n > 0 || *polls < POLL_INTERVAL)
1465796c8dcSSimon Schubert     (*polls)++;
1475796c8dcSSimon Schubert   else
1485796c8dcSSimon Schubert     (*polls) += POLL_INTERVAL;
1495796c8dcSSimon Schubert 
1505796c8dcSSimon Schubert   return n;
1515796c8dcSSimon Schubert }
1525796c8dcSSimon Schubert 
153c50c785cSJohn Marino /* Open a tcp socket.  */
1545796c8dcSSimon Schubert 
1555796c8dcSSimon Schubert int
net_open(struct serial * scb,const char * name)1565796c8dcSSimon Schubert net_open (struct serial *scb, const char *name)
1575796c8dcSSimon Schubert {
1585796c8dcSSimon Schubert   char *port_str, hostname[100];
1595796c8dcSSimon Schubert   int n, port, tmp;
1605796c8dcSSimon Schubert   int use_udp;
1615796c8dcSSimon Schubert   struct hostent *hostent;
1625796c8dcSSimon Schubert   struct sockaddr_in sockaddr;
1635796c8dcSSimon Schubert #ifdef USE_WIN32API
1645796c8dcSSimon Schubert   u_long ioarg;
1655796c8dcSSimon Schubert #else
1665796c8dcSSimon Schubert   int ioarg;
1675796c8dcSSimon Schubert #endif
1685796c8dcSSimon Schubert   int polls = 0;
1695796c8dcSSimon Schubert 
1705796c8dcSSimon Schubert   use_udp = 0;
1715796c8dcSSimon Schubert   if (strncmp (name, "udp:", 4) == 0)
1725796c8dcSSimon Schubert     {
1735796c8dcSSimon Schubert       use_udp = 1;
1745796c8dcSSimon Schubert       name = name + 4;
1755796c8dcSSimon Schubert     }
1765796c8dcSSimon Schubert   else if (strncmp (name, "tcp:", 4) == 0)
1775796c8dcSSimon Schubert     name = name + 4;
1785796c8dcSSimon Schubert 
1795796c8dcSSimon Schubert   port_str = strchr (name, ':');
1805796c8dcSSimon Schubert 
1815796c8dcSSimon Schubert   if (!port_str)
182c50c785cSJohn Marino     error (_("net_open: No colon in host name!"));  /* Shouldn't ever
183c50c785cSJohn Marino 						       happen.  */
1845796c8dcSSimon Schubert 
1855796c8dcSSimon Schubert   tmp = min (port_str - name, (int) sizeof hostname - 1);
186c50c785cSJohn Marino   strncpy (hostname, name, tmp);	/* Don't want colon.  */
187c50c785cSJohn Marino   hostname[tmp] = '\000';	/* Tie off host name.  */
1885796c8dcSSimon Schubert   port = atoi (port_str + 1);
1895796c8dcSSimon Schubert 
190c50c785cSJohn Marino   /* Default hostname is localhost.  */
1915796c8dcSSimon Schubert   if (!hostname[0])
1925796c8dcSSimon Schubert     strcpy (hostname, "localhost");
1935796c8dcSSimon Schubert 
1945796c8dcSSimon Schubert   hostent = gethostbyname (hostname);
1955796c8dcSSimon Schubert   if (!hostent)
1965796c8dcSSimon Schubert     {
1975796c8dcSSimon Schubert       fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
1985796c8dcSSimon Schubert       errno = ENOENT;
1995796c8dcSSimon Schubert       return -1;
2005796c8dcSSimon Schubert     }
2015796c8dcSSimon Schubert 
2025796c8dcSSimon Schubert   sockaddr.sin_family = PF_INET;
2035796c8dcSSimon Schubert   sockaddr.sin_port = htons (port);
2045796c8dcSSimon Schubert   memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
2055796c8dcSSimon Schubert 	  sizeof (struct in_addr));
2065796c8dcSSimon Schubert 
2075796c8dcSSimon Schubert  retry:
2085796c8dcSSimon Schubert 
2095796c8dcSSimon Schubert   if (use_udp)
2105796c8dcSSimon Schubert     scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
2115796c8dcSSimon Schubert   else
2125796c8dcSSimon Schubert     scb->fd = socket (PF_INET, SOCK_STREAM, 0);
2135796c8dcSSimon Schubert 
214cf7f2e2dSJohn Marino   if (scb->fd == -1)
2155796c8dcSSimon Schubert     return -1;
2165796c8dcSSimon Schubert 
217c50c785cSJohn Marino   /* Set socket nonblocking.  */
2185796c8dcSSimon Schubert   ioarg = 1;
2195796c8dcSSimon Schubert   ioctl (scb->fd, FIONBIO, &ioarg);
2205796c8dcSSimon Schubert 
221c50c785cSJohn Marino   /* Use Non-blocking connect.  connect() will return 0 if connected
222c50c785cSJohn Marino      already.  */
2235796c8dcSSimon Schubert   n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
2245796c8dcSSimon Schubert 
2255796c8dcSSimon Schubert   if (n < 0)
2265796c8dcSSimon Schubert     {
2275796c8dcSSimon Schubert #ifdef USE_WIN32API
2285796c8dcSSimon Schubert       int err = WSAGetLastError();
2295796c8dcSSimon Schubert #else
2305796c8dcSSimon Schubert       int err = errno;
2315796c8dcSSimon Schubert #endif
2325796c8dcSSimon Schubert 
2335796c8dcSSimon Schubert       /* Maybe we're waiting for the remote target to become ready to
2345796c8dcSSimon Schubert 	 accept connections.  */
2355796c8dcSSimon Schubert       if (tcp_auto_retry
2365796c8dcSSimon Schubert #ifdef USE_WIN32API
2375796c8dcSSimon Schubert 	  && err == WSAECONNREFUSED
2385796c8dcSSimon Schubert #else
2395796c8dcSSimon Schubert 	  && err == ECONNREFUSED
2405796c8dcSSimon Schubert #endif
2415796c8dcSSimon Schubert 	  && wait_for_connect (NULL, &polls) >= 0)
2425796c8dcSSimon Schubert 	{
2435796c8dcSSimon Schubert 	  close (scb->fd);
2445796c8dcSSimon Schubert 	  goto retry;
2455796c8dcSSimon Schubert 	}
2465796c8dcSSimon Schubert 
2475796c8dcSSimon Schubert       if (
2485796c8dcSSimon Schubert #ifdef USE_WIN32API
2495796c8dcSSimon Schubert 	  /* Under Windows, calling "connect" with a non-blocking socket
2505796c8dcSSimon Schubert 	     results in WSAEWOULDBLOCK, not WSAEINPROGRESS.  */
2515796c8dcSSimon Schubert 	  err != WSAEWOULDBLOCK
2525796c8dcSSimon Schubert #else
2535796c8dcSSimon Schubert 	  err != EINPROGRESS
2545796c8dcSSimon Schubert #endif
2555796c8dcSSimon Schubert 	  )
2565796c8dcSSimon Schubert 	{
2575796c8dcSSimon Schubert 	  errno = err;
2585796c8dcSSimon Schubert 	  net_close (scb);
2595796c8dcSSimon Schubert 	  return -1;
2605796c8dcSSimon Schubert 	}
2615796c8dcSSimon Schubert 
262c50c785cSJohn Marino       /* Looks like we need to wait for the connect.  */
2635796c8dcSSimon Schubert       do
2645796c8dcSSimon Schubert 	{
2655796c8dcSSimon Schubert 	  n = wait_for_connect (scb, &polls);
2665796c8dcSSimon Schubert 	}
2675796c8dcSSimon Schubert       while (n == 0);
2685796c8dcSSimon Schubert       if (n < 0)
2695796c8dcSSimon Schubert 	{
2705796c8dcSSimon Schubert 	  net_close (scb);
2715796c8dcSSimon Schubert 	  return -1;
2725796c8dcSSimon Schubert 	}
2735796c8dcSSimon Schubert     }
2745796c8dcSSimon Schubert 
2755796c8dcSSimon Schubert   /* Got something.  Is it an error?  */
2765796c8dcSSimon Schubert   {
2775796c8dcSSimon Schubert     int res, err;
2785796c8dcSSimon Schubert     socklen_t len;
279cf7f2e2dSJohn Marino 
2805796c8dcSSimon Schubert     len = sizeof (err);
2815796c8dcSSimon Schubert     /* On Windows, the fourth parameter to getsockopt is a "char *";
2825796c8dcSSimon Schubert        on UNIX systems it is generally "void *".  The cast to "void *"
2835796c8dcSSimon Schubert        is OK everywhere, since in C "void *" can be implicitly
2845796c8dcSSimon Schubert        converted to any pointer type.  */
2855796c8dcSSimon Schubert     res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
2865796c8dcSSimon Schubert     if (res < 0 || err)
2875796c8dcSSimon Schubert       {
2885796c8dcSSimon Schubert 	/* Maybe the target still isn't ready to accept the connection.  */
2895796c8dcSSimon Schubert 	if (tcp_auto_retry
2905796c8dcSSimon Schubert #ifdef USE_WIN32API
2915796c8dcSSimon Schubert 	    && err == WSAECONNREFUSED
2925796c8dcSSimon Schubert #else
2935796c8dcSSimon Schubert 	    && err == ECONNREFUSED
2945796c8dcSSimon Schubert #endif
2955796c8dcSSimon Schubert 	    && wait_for_connect (NULL, &polls) >= 0)
2965796c8dcSSimon Schubert 	  {
2975796c8dcSSimon Schubert 	    close (scb->fd);
2985796c8dcSSimon Schubert 	    goto retry;
2995796c8dcSSimon Schubert 	  }
3005796c8dcSSimon Schubert 	if (err)
3015796c8dcSSimon Schubert 	  errno = err;
3025796c8dcSSimon Schubert 	net_close (scb);
3035796c8dcSSimon Schubert 	return -1;
3045796c8dcSSimon Schubert       }
3055796c8dcSSimon Schubert   }
3065796c8dcSSimon Schubert 
307c50c785cSJohn Marino   /* Turn off nonblocking.  */
3085796c8dcSSimon Schubert   ioarg = 0;
3095796c8dcSSimon Schubert   ioctl (scb->fd, FIONBIO, &ioarg);
3105796c8dcSSimon Schubert 
3115796c8dcSSimon Schubert   if (use_udp == 0)
3125796c8dcSSimon Schubert     {
3135796c8dcSSimon Schubert       /* Disable Nagle algorithm.  Needed in some cases.  */
3145796c8dcSSimon Schubert       tmp = 1;
3155796c8dcSSimon Schubert       setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
3165796c8dcSSimon Schubert 		  (char *)&tmp, sizeof (tmp));
3175796c8dcSSimon Schubert     }
3185796c8dcSSimon Schubert 
3195796c8dcSSimon Schubert #ifdef SIGPIPE
3205796c8dcSSimon Schubert   /* If we don't do this, then GDB simply exits
3215796c8dcSSimon Schubert      when the remote side dies.  */
3225796c8dcSSimon Schubert   signal (SIGPIPE, SIG_IGN);
3235796c8dcSSimon Schubert #endif
3245796c8dcSSimon Schubert 
3255796c8dcSSimon Schubert   return 0;
3265796c8dcSSimon Schubert }
3275796c8dcSSimon Schubert 
3285796c8dcSSimon Schubert void
net_close(struct serial * scb)3295796c8dcSSimon Schubert net_close (struct serial *scb)
3305796c8dcSSimon Schubert {
331cf7f2e2dSJohn Marino   if (scb->fd == -1)
3325796c8dcSSimon Schubert     return;
3335796c8dcSSimon Schubert 
3345796c8dcSSimon Schubert   close (scb->fd);
3355796c8dcSSimon Schubert   scb->fd = -1;
3365796c8dcSSimon Schubert }
3375796c8dcSSimon Schubert 
3385796c8dcSSimon Schubert int
net_read_prim(struct serial * scb,size_t count)3395796c8dcSSimon Schubert net_read_prim (struct serial *scb, size_t count)
3405796c8dcSSimon Schubert {
3415796c8dcSSimon Schubert   return recv (scb->fd, scb->buf, count, 0);
3425796c8dcSSimon Schubert }
3435796c8dcSSimon Schubert 
3445796c8dcSSimon Schubert int
net_write_prim(struct serial * scb,const void * buf,size_t count)3455796c8dcSSimon Schubert net_write_prim (struct serial *scb, const void *buf, size_t count)
3465796c8dcSSimon Schubert {
3475796c8dcSSimon Schubert   return send (scb->fd, buf, count, 0);
3485796c8dcSSimon Schubert }
3495796c8dcSSimon Schubert 
3505796c8dcSSimon Schubert int
ser_tcp_send_break(struct serial * scb)3515796c8dcSSimon Schubert ser_tcp_send_break (struct serial *scb)
3525796c8dcSSimon Schubert {
3535796c8dcSSimon Schubert   /* Send telnet IAC and BREAK characters.  */
3545796c8dcSSimon Schubert   return (serial_write (scb, "\377\363", 2));
3555796c8dcSSimon Schubert }
3565796c8dcSSimon Schubert 
3575796c8dcSSimon Schubert /* Support for "set tcp" and "show tcp" commands.  */
3585796c8dcSSimon Schubert 
3595796c8dcSSimon Schubert static void
set_tcp_cmd(char * args,int from_tty)3605796c8dcSSimon Schubert set_tcp_cmd (char *args, int from_tty)
3615796c8dcSSimon Schubert {
3625796c8dcSSimon Schubert   help_list (tcp_set_cmdlist, "set tcp ", -1, gdb_stdout);
3635796c8dcSSimon Schubert }
3645796c8dcSSimon Schubert 
3655796c8dcSSimon Schubert static void
show_tcp_cmd(char * args,int from_tty)3665796c8dcSSimon Schubert show_tcp_cmd (char *args, int from_tty)
3675796c8dcSSimon Schubert {
3685796c8dcSSimon Schubert   help_list (tcp_show_cmdlist, "show tcp ", -1, gdb_stdout);
3695796c8dcSSimon Schubert }
3705796c8dcSSimon Schubert 
3715796c8dcSSimon Schubert 
3725796c8dcSSimon Schubert void
_initialize_ser_tcp(void)3735796c8dcSSimon Schubert _initialize_ser_tcp (void)
3745796c8dcSSimon Schubert {
3755796c8dcSSimon Schubert #ifdef USE_WIN32API
3765796c8dcSSimon Schubert   /* Do nothing; the TCP serial operations will be initialized in
3775796c8dcSSimon Schubert      ser-mingw.c.  */
3785796c8dcSSimon Schubert #else
3795796c8dcSSimon Schubert   struct serial_ops *ops;
380cf7f2e2dSJohn Marino 
3815796c8dcSSimon Schubert   ops = XMALLOC (struct serial_ops);
3825796c8dcSSimon Schubert   memset (ops, 0, sizeof (struct serial_ops));
3835796c8dcSSimon Schubert   ops->name = "tcp";
3845796c8dcSSimon Schubert   ops->next = 0;
3855796c8dcSSimon Schubert   ops->open = net_open;
3865796c8dcSSimon Schubert   ops->close = net_close;
3875796c8dcSSimon Schubert   ops->readchar = ser_base_readchar;
3885796c8dcSSimon Schubert   ops->write = ser_base_write;
3895796c8dcSSimon Schubert   ops->flush_output = ser_base_flush_output;
3905796c8dcSSimon Schubert   ops->flush_input = ser_base_flush_input;
3915796c8dcSSimon Schubert   ops->send_break = ser_tcp_send_break;
3925796c8dcSSimon Schubert   ops->go_raw = ser_base_raw;
3935796c8dcSSimon Schubert   ops->get_tty_state = ser_base_get_tty_state;
394c50c785cSJohn Marino   ops->copy_tty_state = ser_base_copy_tty_state;
3955796c8dcSSimon Schubert   ops->set_tty_state = ser_base_set_tty_state;
3965796c8dcSSimon Schubert   ops->print_tty_state = ser_base_print_tty_state;
3975796c8dcSSimon Schubert   ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
3985796c8dcSSimon Schubert   ops->setbaudrate = ser_base_setbaudrate;
3995796c8dcSSimon Schubert   ops->setstopbits = ser_base_setstopbits;
4005796c8dcSSimon Schubert   ops->drain_output = ser_base_drain_output;
4015796c8dcSSimon Schubert   ops->async = ser_base_async;
4025796c8dcSSimon Schubert   ops->read_prim = net_read_prim;
4035796c8dcSSimon Schubert   ops->write_prim = net_write_prim;
4045796c8dcSSimon Schubert   serial_add_interface (ops);
4055796c8dcSSimon Schubert #endif /* USE_WIN32API */
4065796c8dcSSimon Schubert 
4075796c8dcSSimon Schubert   add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\
4085796c8dcSSimon Schubert TCP protocol specific variables\n\
4095796c8dcSSimon Schubert Configure variables specific to remote TCP connections"),
4105796c8dcSSimon Schubert 		  &tcp_set_cmdlist, "set tcp ",
4115796c8dcSSimon Schubert 		  0 /* allow-unknown */, &setlist);
4125796c8dcSSimon Schubert   add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\
4135796c8dcSSimon Schubert TCP protocol specific variables\n\
4145796c8dcSSimon Schubert Configure variables specific to remote TCP connections"),
4155796c8dcSSimon Schubert 		  &tcp_show_cmdlist, "show tcp ",
4165796c8dcSSimon Schubert 		  0 /* allow-unknown */, &showlist);
4175796c8dcSSimon Schubert 
4185796c8dcSSimon Schubert   add_setshow_boolean_cmd ("auto-retry", class_obscure,
4195796c8dcSSimon Schubert 			   &tcp_auto_retry, _("\
4205796c8dcSSimon Schubert Set auto-retry on socket connect"), _("\
4215796c8dcSSimon Schubert Show auto-retry on socket connect"),
4225796c8dcSSimon Schubert 			   NULL, NULL, NULL,
4235796c8dcSSimon Schubert 			   &tcp_set_cmdlist, &tcp_show_cmdlist);
4245796c8dcSSimon Schubert 
4255796c8dcSSimon Schubert   add_setshow_uinteger_cmd ("connect-timeout", class_obscure,
4265796c8dcSSimon Schubert 			    &tcp_retry_limit, _("\
4275796c8dcSSimon Schubert Set timeout limit for socket connection"), _("\
4285796c8dcSSimon Schubert Show timeout limit for socket connection"),
4295796c8dcSSimon Schubert 			   NULL, NULL, NULL,
4305796c8dcSSimon Schubert 			   &tcp_set_cmdlist, &tcp_show_cmdlist);
4315796c8dcSSimon Schubert }
432