aboutsummaryrefslogtreecommitdiff
path: root/gdb/ser-tcp.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2023-09-01 12:11:37 -0600
committerTom Tromey <tromey@adacore.com>2023-11-27 12:55:14 -0700
commita2e0acea420cca881296c6fcf58920f3d7c05a45 (patch)
tree54f369a7b5a2ead36e15f14e2d0d154a30286fab /gdb/ser-tcp.c
parentad3cf8c64e6e4794fc48d28c90f20cbbfdc51ca4 (diff)
downloadgdb-a2e0acea420cca881296c6fcf58920f3d7c05a45.zip
gdb-a2e0acea420cca881296c6fcf58920f3d7c05a45.tar.gz
gdb-a2e0acea420cca881296c6fcf58920f3d7c05a45.tar.bz2
Change serial "open" functions to throw exception
remote.c assumes that a failure to open the serial connection will set errno. This is somewhat true, because the Windows code tries to set errno appropriately -- but only somewhat, because it isn't clear that the "pex" code sets it, and the tcp code seems to do the wrong thing. It seems better to simply have the serial open functions throw on error. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30770
Diffstat (limited to 'gdb/ser-tcp.c')
-rw-r--r--gdb/ser-tcp.c79
1 files changed, 42 insertions, 37 deletions
diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c
index 0367a5a..5e36840 100644
--- a/gdb/ser-tcp.c
+++ b/gdb/ser-tcp.c
@@ -84,11 +84,11 @@ static unsigned int tcp_retry_limit = 15;
/* Helper function to wait a while. If SOCK is not -1, wait on its
file descriptor. Otherwise just wait on a timeout, updating
- *POLLS. Returns -1 on timeout or interrupt, otherwise the value of
- select. */
+ *POLLS. Returns -1 on timeout or interrupt and set OUT_ERROR,
+ otherwise the value of select. */
static int
-wait_for_connect (int sock, unsigned int *polls)
+wait_for_connect (int sock, unsigned int *polls, ULONGEST *out_error)
{
struct timeval t;
int n;
@@ -98,14 +98,14 @@ wait_for_connect (int sock, unsigned int *polls)
interrupt. */
if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
{
- errno = EINTR;
+ *out_error = EINTR;
return -1;
}
/* Check for timeout. */
if (*polls > tcp_retry_limit * POLL_INTERVAL)
{
- errno = ETIMEDOUT;
+ *out_error = ETIMEDOUT;
return -1;
}
@@ -155,19 +155,34 @@ wait_for_connect (int sock, unsigned int *polls)
return n;
}
+/* A helper to get the error number for either Windows or POSIX. */
+static ULONGEST
+get_error ()
+{
+#ifdef USE_WIN32API
+ return WSAGetLastError ();
+#else
+ return errno;
+#endif
+}
+
/* Try to connect to the host represented by AINFO. If the connection
- succeeds, return its socket. Otherwise, return -1 and set ERRNO
+ succeeds, return its socket. Otherwise, return -1 and set OUT_ERROR
accordingly. POLLS is used when 'connect' returns EINPROGRESS, and
we need to invoke 'wait_for_connect' to obtain the status. */
static int
-try_connect (const struct addrinfo *ainfo, unsigned int *polls)
+try_connect (const struct addrinfo *ainfo, unsigned int *polls,
+ ULONGEST *out_error)
{
int sock = gdb_socket_cloexec (ainfo->ai_family, ainfo->ai_socktype,
ainfo->ai_protocol);
if (sock < 0)
- return -1;
+ {
+ *out_error = get_error ();
+ return -1;
+ }
/* Set socket nonblocking. */
#ifdef USE_WIN32API
@@ -182,11 +197,7 @@ try_connect (const struct addrinfo *ainfo, unsigned int *polls)
already. */
if (connect (sock, ainfo->ai_addr, ainfo->ai_addrlen) < 0)
{
-#ifdef USE_WIN32API
- int err = WSAGetLastError();
-#else
- int err = errno;
-#endif
+ ULONGEST err = get_error ();
/* If we've got a "connection refused" error, just return
-1. The caller will know what to do. */
@@ -199,7 +210,7 @@ try_connect (const struct addrinfo *ainfo, unsigned int *polls)
)
{
close (sock);
- errno = err;
+ *out_error = err;
return -1;
}
@@ -218,7 +229,7 @@ try_connect (const struct addrinfo *ainfo, unsigned int *polls)
)
{
close (sock);
- errno = err;
+ *out_error = err;
return -1;
}
@@ -226,17 +237,15 @@ try_connect (const struct addrinfo *ainfo, unsigned int *polls)
int n;
do
- n = wait_for_connect (sock, polls);
+ n = wait_for_connect (sock, polls, out_error);
while (n == 0);
if (n < 0)
{
- int saved_errno = errno;
-
/* A negative value here means that we either timed out or
got interrupted by the user. Just return. */
close (sock);
- errno = saved_errno;
+ /* OUT_ERROR was set by wait_for_connect, above. */
return -1;
}
}
@@ -253,16 +262,14 @@ try_connect (const struct addrinfo *ainfo, unsigned int *polls)
if (ret < 0)
{
- int saved_errno = errno;
-
+ *out_error = get_error ();
close (sock);
- errno = saved_errno;
return -1;
}
else if (ret == 0 && err != 0)
{
+ *out_error = err;
close (sock);
- errno = err;
return -1;
}
@@ -272,7 +279,7 @@ try_connect (const struct addrinfo *ainfo, unsigned int *polls)
/* Open a tcp socket. */
-int
+void
net_open (struct serial *scb, const char *name)
{
struct addrinfo hint;
@@ -295,12 +302,7 @@ net_open (struct serial *scb, const char *name)
&hint, &ainfo);
if (r != 0)
- {
- gdb_printf (gdb_stderr, _("%s: cannot resolve name: %s\n"),
- name, gai_strerror (r));
- errno = ENOENT;
- return -1;
- }
+ error (_("%s: cannot resolve name: %s\n"), name, gai_strerror (r));
scoped_free_addrinfo free_ainfo (ainfo);
@@ -311,6 +313,7 @@ net_open (struct serial *scb, const char *name)
'struct addrinfo' that succeed. */
struct addrinfo *success_ainfo = NULL;
unsigned int polls = 0;
+ ULONGEST last_error = 0;
/* Assume the worst. */
scb->fd = -1;
@@ -324,7 +327,7 @@ net_open (struct serial *scb, const char *name)
/* Iterate over the list of possible addresses to connect
to. For each, we'll try to connect and see if it
succeeds. */
- int sock = try_connect (iter, &polls);
+ int sock = try_connect (iter, &polls, &last_error);
if (sock >= 0)
{
@@ -336,9 +339,9 @@ net_open (struct serial *scb, const char *name)
}
else if (
#ifdef USE_WIN32API
- errno == WSAECONNREFUSED
+ last_error == WSAECONNREFUSED
#else
- errno == ECONNREFUSED
+ last_error == ECONNREFUSED
#endif
)
got_connrefused = true;
@@ -353,12 +356,16 @@ net_open (struct serial *scb, const char *name)
while (tcp_auto_retry
&& success_ainfo == NULL
&& got_connrefused
- && wait_for_connect (-1, &polls) >= 0);
+ && wait_for_connect (-1, &polls, &last_error) >= 0);
if (success_ainfo == NULL)
{
net_close (scb);
- return -1;
+#ifdef USE_WIN32API
+ throw_winerror_with_name (_("could not connect"), last_error);
+#else
+ perror_with_name (_("could not connect"), last_error);
+#endif
}
/* Turn off nonblocking. */
@@ -384,8 +391,6 @@ net_open (struct serial *scb, const char *name)
when the remote side dies. */
signal (SIGPIPE, SIG_IGN);
#endif
-
- return 0;
}
void