-/* Read a character with user-specified timeout. TIMEOUT is number of seconds
- to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
- char if successful. Returns -2 if timeout expired, EOF if line dropped
- dead, or -3 for any other error (see errno in that case). */
+/* Read any error output we might have. */
+
+static void
+ser_base_read_error_fd (struct serial *scb, int close_fd)
+{
+ if (scb->error_fd != -1)
+ {
+ ssize_t s;
+ char buf[GDB_MI_MSG_WIDTH + 1];
+
+ for (;;)
+ {
+ char *current;
+ char *newline;
+ int to_read = GDB_MI_MSG_WIDTH;
+ int num_bytes = -1;
+
+ if (scb->ops->avail)
+ num_bytes = (scb->ops->avail)(scb, scb->error_fd);
+
+ if (num_bytes != -1)
+ to_read = (num_bytes < to_read) ? num_bytes : to_read;
+
+ if (to_read == 0)
+ break;
+
+ s = read (scb->error_fd, &buf, to_read);
+ if ((s == -1) || (s == 0 && !close_fd))
+ break;
+
+ if (s == 0 && close_fd)
+ {
+ /* End of file. */
+ if (serial_is_async_p (scb))
+ delete_file_handler (scb->error_fd);
+ close (scb->error_fd);
+ scb->error_fd = -1;
+ break;
+ }
+
+ /* In theory, embedded newlines are not a problem.
+ But for MI, we want each output line to have just
+ one newline for legibility. So output things
+ in newline chunks. */
+ gdb_assert (s > 0 && s <= GDB_MI_MSG_WIDTH);
+ buf[s] = '\0';
+ current = buf;
+ while ((newline = strstr (current, "\n")) != NULL)
+ {
+ *newline = '\0';
+ fputs_unfiltered (current, gdb_stderr);
+ fputs_unfiltered ("\n", gdb_stderr);
+ current = newline + 1;
+ }
+
+ fputs_unfiltered (current, gdb_stderr);
+ }
+ }
+}
+
+/* Event-loop callback for a serial's error_fd. Flushes any error
+ output we might have. */
+
+static void
+handle_error_fd (int error, gdb_client_data client_data)
+{
+ serial *scb = (serial *) client_data;
+
+ ser_base_read_error_fd (scb, 0);
+}
+
+/* Read a character with user-specified timeout. TIMEOUT is number of
+ seconds to wait, or -1 to wait forever. Use timeout of 0 to effect
+ a poll. Returns char if successful. Returns SERIAL_TIMEOUT if
+ timeout expired, SERIAL_EOF if line dropped dead, or SERIAL_ERROR
+ for any other error (see errno in that case). */