gdb/ser-tcp.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "serial.h"
- #include "ser-base.h"
- #include "ser-tcp.h"
- #include "gdbcmd.h"
- #include "cli/cli-decode.h"
- #include "cli/cli-setshow.h"
- #include "filestuff.h"
- #include <sys/types.h>
- #ifdef HAVE_SYS_FILIO_H
- #include <sys/filio.h>
- #endif
- #ifdef HAVE_SYS_IOCTL_H
- #include <sys/ioctl.h>
- #endif
- #include <sys/time.h>
- #ifdef USE_WIN32API
- #include <winsock2.h>
- #ifndef ETIMEDOUT
- #define ETIMEDOUT WSAETIMEDOUT
- #endif
- #define close(fd) closesocket (fd)
- #define ioctl ioctlsocket
- #else
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <sys/socket.h>
- #include <netinet/tcp.h>
- #endif
- #include <signal.h>
- #include "gdb_select.h"
- #ifndef HAVE_SOCKLEN_T
- typedef int socklen_t;
- #endif
- void _initialize_ser_tcp (void);
- static struct cmd_list_element *tcp_set_cmdlist;
- static struct cmd_list_element *tcp_show_cmdlist;
- static int tcp_auto_retry = 1;
- static unsigned int tcp_retry_limit = 15;
- #define POLL_INTERVAL 5
- static int
- wait_for_connect (struct serial *scb, unsigned int *polls)
- {
- struct timeval t;
- int n;
-
- if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
- {
- errno = EINTR;
- return -1;
- }
-
- if (*polls > tcp_retry_limit * POLL_INTERVAL)
- {
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (*polls < POLL_INTERVAL)
- {
- t.tv_sec = 0;
- t.tv_usec = 1000000 / POLL_INTERVAL;
- }
- else
- {
- t.tv_sec = 1;
- t.tv_usec = 0;
- }
- if (scb)
- {
- fd_set rset, wset, eset;
- FD_ZERO (&rset);
- FD_SET (scb->fd, &rset);
- wset = rset;
- eset = rset;
-
- n = select (scb->fd + 1, &rset, &wset, &eset, &t);
- }
- else
-
- n = gdb_select (0, NULL, NULL, NULL, &t);
-
- if (n > 0 || *polls < POLL_INTERVAL)
- (*polls)++;
- else
- (*polls) += POLL_INTERVAL;
- return n;
- }
- int
- net_open (struct serial *scb, const char *name)
- {
- char *port_str, hostname[100];
- int n, port, tmp;
- int use_udp;
- struct hostent *hostent;
- struct sockaddr_in sockaddr;
- #ifdef USE_WIN32API
- u_long ioarg;
- #else
- int ioarg;
- #endif
- unsigned int polls = 0;
- use_udp = 0;
- if (strncmp (name, "udp:", 4) == 0)
- {
- use_udp = 1;
- name = name + 4;
- }
- else if (strncmp (name, "tcp:", 4) == 0)
- name = name + 4;
- port_str = strchr (name, ':');
- if (!port_str)
- error (_("net_open: No colon in host name!"));
- tmp = min (port_str - name, (int) sizeof hostname - 1);
- strncpy (hostname, name, tmp);
- hostname[tmp] = '\000';
- port = atoi (port_str + 1);
-
- if (!hostname[0])
- strcpy (hostname, "localhost");
- hostent = gethostbyname (hostname);
- if (!hostent)
- {
- fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
- errno = ENOENT;
- return -1;
- }
- sockaddr.sin_family = PF_INET;
- sockaddr.sin_port = htons (port);
- memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
- sizeof (struct in_addr));
- retry:
- if (use_udp)
- scb->fd = gdb_socket_cloexec (PF_INET, SOCK_DGRAM, 0);
- else
- scb->fd = gdb_socket_cloexec (PF_INET, SOCK_STREAM, 0);
- if (scb->fd == -1)
- return -1;
-
- ioarg = 1;
- ioctl (scb->fd, FIONBIO, &ioarg);
-
- n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
- if (n < 0)
- {
- #ifdef USE_WIN32API
- int err = WSAGetLastError();
- #else
- int err = errno;
- #endif
-
- if (tcp_auto_retry
- #ifdef USE_WIN32API
- && err == WSAECONNREFUSED
- #else
- && err == ECONNREFUSED
- #endif
- && wait_for_connect (NULL, &polls) >= 0)
- {
- close (scb->fd);
- goto retry;
- }
- if (
- #ifdef USE_WIN32API
-
- err != WSAEWOULDBLOCK
- #else
- err != EINPROGRESS
- #endif
- )
- {
- errno = err;
- net_close (scb);
- return -1;
- }
-
- do
- {
- n = wait_for_connect (scb, &polls);
- }
- while (n == 0);
- if (n < 0)
- {
- net_close (scb);
- return -1;
- }
- }
-
- {
- int res, err;
- socklen_t len;
- len = sizeof (err);
-
- res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
- if (res < 0 || err)
- {
-
- if (tcp_auto_retry
- #ifdef USE_WIN32API
- && err == WSAECONNREFUSED
- #else
- && err == ECONNREFUSED
- #endif
- && wait_for_connect (NULL, &polls) >= 0)
- {
- close (scb->fd);
- goto retry;
- }
- if (err)
- errno = err;
- net_close (scb);
- return -1;
- }
- }
-
- ioarg = 0;
- ioctl (scb->fd, FIONBIO, &ioarg);
- if (use_udp == 0)
- {
-
- tmp = 1;
- setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
- (char *)&tmp, sizeof (tmp));
- }
- #ifdef SIGPIPE
-
- signal (SIGPIPE, SIG_IGN);
- #endif
- return 0;
- }
- void
- net_close (struct serial *scb)
- {
- if (scb->fd == -1)
- return;
- close (scb->fd);
- scb->fd = -1;
- }
- int
- net_read_prim (struct serial *scb, size_t count)
- {
-
- return recv (scb->fd, (void *) scb->buf, count, 0);
- }
- int
- net_write_prim (struct serial *scb, const void *buf, size_t count)
- {
- return send (scb->fd, buf, count, 0);
- }
- int
- ser_tcp_send_break (struct serial *scb)
- {
-
- return (serial_write (scb, "\377\363", 2));
- }
- static void
- set_tcp_cmd (char *args, int from_tty)
- {
- help_list (tcp_set_cmdlist, "set tcp ", all_commands, gdb_stdout);
- }
- static void
- show_tcp_cmd (char *args, int from_tty)
- {
- help_list (tcp_show_cmdlist, "show tcp ", all_commands, gdb_stdout);
- }
- #ifndef USE_WIN32API
- static const struct serial_ops tcp_ops =
- {
- "tcp",
- net_open,
- net_close,
- NULL,
- ser_base_readchar,
- ser_base_write,
- ser_base_flush_output,
- ser_base_flush_input,
- ser_tcp_send_break,
- ser_base_raw,
- ser_base_get_tty_state,
- ser_base_copy_tty_state,
- ser_base_set_tty_state,
- ser_base_print_tty_state,
- ser_base_noflush_set_tty_state,
- ser_base_setbaudrate,
- ser_base_setstopbits,
- ser_base_drain_output,
- ser_base_async,
- net_read_prim,
- net_write_prim
- };
- #endif
- void
- _initialize_ser_tcp (void)
- {
- #ifdef USE_WIN32API
-
- #else
- serial_add_interface (&tcp_ops);
- #endif
- add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\
- TCP protocol specific variables\n\
- Configure variables specific to remote TCP connections"),
- &tcp_set_cmdlist, "set tcp ",
- 0 , &setlist);
- add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\
- TCP protocol specific variables\n\
- Configure variables specific to remote TCP connections"),
- &tcp_show_cmdlist, "show tcp ",
- 0 , &showlist);
- add_setshow_boolean_cmd ("auto-retry", class_obscure,
- &tcp_auto_retry, _("\
- Set auto-retry on socket connect"), _("\
- Show auto-retry on socket connect"),
- NULL, NULL, NULL,
- &tcp_set_cmdlist, &tcp_show_cmdlist);
- add_setshow_uinteger_cmd ("connect-timeout", class_obscure,
- &tcp_retry_limit, _("\
- Set timeout limit in seconds for socket connection"), _("\
- Show timeout limit in seconds for socket connection"), _("\
- If set to \"unlimited\", GDB will keep attempting to establish a\n\
- connection forever, unless interrupted with Ctrl-c.\n\
- The default is 15 seconds."),
- NULL, NULL,
- &tcp_set_cmdlist, &tcp_show_cmdlist);
- }