| Index: gdb/ser-base.c
|
| diff --git a/gdb/ser-base.c b/gdb/ser-base.c
|
| index 2f12dfcdc172fc1a0c1e550473a12b24145fa431..d07dcf3e4809d8610498ddb07342191f46ccb765 100644
|
| --- a/gdb/ser-base.c
|
| +++ b/gdb/ser-base.c
|
| @@ -1,7 +1,6 @@
|
| /* Generic serial interface functions.
|
|
|
| - Copyright (C) 1992-1996, 1998-2001, 2003-2012 Free Software
|
| - Foundation, Inc.
|
| + Copyright (C) 1992-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -24,7 +23,8 @@
|
| #include "event-loop.h"
|
|
|
| #include "gdb_select.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| +#include "gdb_assert.h"
|
| #include <sys/time.h>
|
| #ifdef USE_WIN32API
|
| #include <winsock2.h>
|
| @@ -242,6 +242,64 @@ ser_base_wait_for (struct serial *scb, int timeout)
|
| }
|
| }
|
|
|
| +/* 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. */
|
| + 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);
|
| + }
|
| + }
|
| +}
|
| +
|
| /* 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
|
| @@ -292,6 +350,11 @@ do_ser_base_readchar (struct serial *scb, int timeout)
|
| status = SERIAL_TIMEOUT;
|
| break;
|
| }
|
| +
|
| + /* We also need to check and consume the stderr because it could
|
| + come before the stdout for some stubs. If we just sit and wait
|
| + for stdout, we would hit a deadlock for that case. */
|
| + ser_base_read_error_fd (scb, 0);
|
| }
|
|
|
| if (status < 0)
|
| @@ -362,54 +425,9 @@ generic_readchar (struct serial *scb, int timeout,
|
| }
|
| }
|
| }
|
| - /* Read any error output we might have. */
|
| - if (scb->error_fd != -1)
|
| - {
|
| - ssize_t s;
|
| - char buf[81];
|
| -
|
| - for (;;)
|
| - {
|
| - char *current;
|
| - char *newline;
|
| - int to_read = 80;
|
| -
|
| - 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)
|
| - break;
|
| - if (s == 0)
|
| - {
|
| - /* EOF */
|
| - 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. */
|
| - 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);
|
| - }
|
| - }
|
| + /* Read any error output we might have. */
|
| + ser_base_read_error_fd (scb, 1);
|
|
|
| reschedule (scb);
|
| return ch;
|
| @@ -422,17 +440,18 @@ ser_base_readchar (struct serial *scb, int timeout)
|
| }
|
|
|
| int
|
| -ser_base_write (struct serial *scb, const char *str, int len)
|
| +ser_base_write (struct serial *scb, const void *buf, size_t count)
|
| {
|
| + const char *str = buf;
|
| int cc;
|
|
|
| - while (len > 0)
|
| + while (count > 0)
|
| {
|
| - cc = scb->ops->write_prim (scb, str, len);
|
| + cc = scb->ops->write_prim (scb, str, count);
|
|
|
| if (cc < 0)
|
| return 1;
|
| - len -= cc;
|
| + count -= cc;
|
| str += cc;
|
| }
|
| return 0;
|
|
|