/* Stuff for dealing with the packets which are part of this protocol.
See comment at top of file for details. */
-/* Close/unpush the remote target, and throw a TARGET_CLOSE_ERROR
- error to higher layers. Called when a serial error is detected.
- The exception message is STRING, followed by a colon and a blank,
- the system error message for errno at function entry and final dot
- for output compatibility with throw_perror_with_name. */
-
-static void
-unpush_and_perror (remote_target *target, const char *string)
-{
- int saved_errno = errno;
-
- remote_unpush_target (target);
- throw_error (TARGET_CLOSE_ERROR, "%s: %s.", string,
- safe_strerror (saved_errno));
-}
-
/* Read a single character from the remote end. The current quit
handler is overridden to avoid quitting in the middle of packet
sequence, as that would break communication with the remote server.
int ch;
struct remote_state *rs = get_remote_state ();
- {
- scoped_restore restore_quit_target
- = make_scoped_restore (&curr_quit_handler_target, this);
- scoped_restore restore_quit
- = make_scoped_restore (&quit_handler, ::remote_serial_quit_handler);
+ try
+ {
+ scoped_restore restore_quit_target
+ = make_scoped_restore (&curr_quit_handler_target, this);
+ scoped_restore restore_quit
+ = make_scoped_restore (&quit_handler, ::remote_serial_quit_handler);
- rs->got_ctrlc_during_io = 0;
+ rs->got_ctrlc_during_io = 0;
- ch = serial_readchar (rs->remote_desc, timeout);
+ ch = serial_readchar (rs->remote_desc, timeout);
- if (rs->got_ctrlc_during_io)
- set_quit_flag ();
- }
+ if (rs->got_ctrlc_during_io)
+ set_quit_flag ();
+ }
+ catch (const gdb_exception_error &ex)
+ {
+ remote_unpush_target (this);
+ throw_error (TARGET_CLOSE_ERROR,
+ _("Remote communication error. "
+ "Target disconnected: %s"),
+ ex.what ());
+ }
if (ch >= 0)
return ch;
- switch ((enum serial_rc) ch)
+ if (ch == SERIAL_EOF)
{
- case SERIAL_EOF:
remote_unpush_target (this);
throw_error (TARGET_CLOSE_ERROR, _("Remote connection closed"));
- /* no return */
- case SERIAL_ERROR:
- unpush_and_perror (this, _("Remote communication error. "
- "Target disconnected"));
- /* no return */
- case SERIAL_TIMEOUT:
- break;
}
+
return ch;
}
{
if (GetLastError () != ERROR_IO_PENDING
|| !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
- bytes_read = -1;
+ {
+ ULONGEST err = GetLastError ();
+ CloseHandle (ov.hEvent);
+ throw_winerror_with_name (_("error while reading"), err);
+ }
}
CloseHandle (ov.hEvent);
DWORD bytes_read;
if (pipeline_out == INVALID_HANDLE_VALUE)
- return -1;
+ error (_("could not find file number for pipe"));
if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
- return -1;
+ throw_winerror_with_name (_("could not peek into pipe"), GetLastError ());
if (count > available)
count = available;
if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
- return -1;
+ throw_winerror_with_name (_("could not read from pipe"), GetLastError ());
return bytes_read;
}
/* Need to cast to silence -Wpointer-sign on MinGW, as Winsock's
'recv' takes 'char *' as second argument, while 'scb->buf' is
'unsigned char *'. */
- return recv (scb->fd, (char *) scb->buf, count, 0);
+ int result = recv (scb->fd, (char *) scb->buf, count, 0);
+ if (result == -1 && errno != EINTR)
+ perror_with_name ("error while reading");
+ return result;
}
int