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