static int wait_for PARAMS ((serial_t scb, int timeout));
static int tcp_readchar PARAMS ((serial_t scb, int timeout));
static int tcp_setbaudrate PARAMS ((serial_t scb, int rate));
+static int tcp_setstopbits PARAMS ((serial_t scb, int num));
static int tcp_write PARAMS ((serial_t scb, const char *str, int len));
-static void tcp_restore PARAMS ((serial_t scb));
+/* FIXME: static void tcp_restore PARAMS ((serial_t scb)); */
static void tcp_close PARAMS ((serial_t scb));
static serial_ttystate tcp_get_tty_state PARAMS ((serial_t scb));
static int tcp_set_tty_state PARAMS ((serial_t scb, serial_ttystate state));
struct sockaddr_in sockaddr;
int tmp;
char hostname[100];
+ struct protoent *protoent;
+ int i;
port_str = strchr (name, ':');
if (!port_str)
error ("tcp_open: No colon in host name!"); /* Shouldn't ever happen */
- tmp = min(port_str - name + 1, sizeof hostname);
- strncpy (hostname, name, tmp - 1); /* Don't want colon */
+ tmp = min (port_str - name, sizeof hostname - 1);
+ strncpy (hostname, name, tmp); /* Don't want colon */
+ hostname[tmp] = '\000'; /* Tie off host name */
port = atoi (port_str + 1);
hostent = gethostbyname (hostname);
if (!hostent)
{
+ fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
errno = ENOENT;
return -1;
}
- scb->fd = socket (PF_INET, SOCK_STREAM, 0);
- if (scb->fd < 0)
- return -1;
+ for (i = 1; i <= 15; i++)
+ {
+ scb->fd = socket (PF_INET, SOCK_STREAM, 0);
+ if (scb->fd < 0)
+ return -1;
- /* Allow rapid reuse of this port. */
- tmp = 1;
- setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp));
+ /* Allow rapid reuse of this port. */
+ tmp = 1;
+ setsockopt (scb->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp));
- /* Enable TCP keep alive process. */
- tmp = 1;
- setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
+ /* Enable TCP keep alive process. */
+ tmp = 1;
+ setsockopt (scb->fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
- sockaddr.sin_family = PF_INET;
- sockaddr.sin_port = htons(port);
- memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
- sizeof (struct in_addr));
+ sockaddr.sin_family = PF_INET;
+ sockaddr.sin_port = htons(port);
+ memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
+ sizeof (struct in_addr));
- if (connect(scb->fd, &sockaddr, sizeof(sockaddr)))
- {
- close(scb->fd);
- return -1;
+ if (!connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof(sockaddr)))
+ break;
+
+ close (scb->fd);
+ scb->fd = -1;
+
+/* We retry for ECONNREFUSED because that is often a temporary condition, which
+ happens when the server is being restarted. */
+
+ if (errno != ECONNREFUSED)
+ return -1;
+
+ sleep (1);
}
+ protoent = getprotobyname ("tcp");
+ if (!protoent)
+ return -1;
+
tmp = 1;
- if (setsockopt (scb->fd, 6, TCP_NODELAY, (char *)&tmp, sizeof(tmp)))
+ if (setsockopt (scb->fd, protoent->p_proto, TCP_NODELAY,
+ (char *)&tmp, sizeof(tmp)))
return -1;
signal(SIGPIPE, SIG_IGN); /* If we don't do this, then GDB simply exits
return 0;
}
+static int
+tcp_return_0 (scb)
+ serial_t scb;
+{
+ return 0;
+}
+
static void
tcp_raw(scb)
serial_t scb;
{
int numfds;
struct timeval tv;
- fd_set readfds;
+ fd_set readfds, exceptfds;
FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
tv.tv_sec = timeout;
tv.tv_usec = 0;
FD_SET(scb->fd, &readfds);
+ FD_SET(scb->fd, &exceptfds);
- if (timeout >= 0)
- numfds = select(scb->fd+1, &readfds, 0, 0, &tv);
- else
- numfds = select(scb->fd+1, &readfds, 0, 0, 0);
-
- if (numfds <= 0)
- if (numfds == 0)
- return SERIAL_TIMEOUT;
- else
- return SERIAL_ERROR; /* Got an error from select or poll */
-
- return 0;
+ while (1)
+ {
+ if (timeout >= 0)
+ numfds = select(scb->fd+1, &readfds, 0, &exceptfds, &tv);
+ else
+ numfds = select(scb->fd+1, &readfds, 0, &exceptfds, 0);
+
+ if (numfds <= 0)
+ if (numfds == 0)
+ return SERIAL_TIMEOUT;
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from select or poll */
+
+ return 0;
+ }
}
/* Read a character with user-specified timeout. TIMEOUT is number of seconds
if (status < 0)
return status;
- scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
+ while (1)
+ {
+ scb->bufcnt = read(scb->fd, scb->buf, BUFSIZ);
+ if (scb->bufcnt != -1 || errno != EINTR)
+ break;
+ }
if (scb->bufcnt <= 0)
if (scb->bufcnt == 0)
return *scb->bufp++;
}
+static int
+tcp_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
+ serial_t scb;
+ serial_ttystate new_ttystate;
+ serial_ttystate old_ttystate;
+{
+ return 0;
+}
+
+static void
+tcp_print_tty_state (scb, ttystate)
+ serial_t scb;
+ serial_ttystate ttystate;
+{
+ /* Nothing to print. */
+ return;
+}
+
static int
tcp_setbaudrate(scb, rate)
serial_t scb;
return 0; /* Never fails! */
}
+static int
+tcp_setstopbits(scb, num)
+ serial_t scb;
+ int num;
+{
+ return 0; /* Never fails! */
+}
+
static int
tcp_write(scb, str, len)
serial_t scb;
tcp_close,
tcp_readchar,
tcp_write,
+ tcp_return_0, /* flush output */
+ tcp_return_0, /* flush input */
+ tcp_return_0, /* send break */
tcp_raw,
tcp_get_tty_state,
tcp_set_tty_state,
+ tcp_print_tty_state,
+ tcp_noflush_set_tty_state,
tcp_setbaudrate,
+ tcp_setstopbits,
};
void