Fix inconsistent handling of EINTR in ser-*.c backends

- If serial->write_prim returns EINTR, ser_bas_write returns it to the
  caller.  This just looks wrong to me -- part of the output may have
  already been sent, and there's no way for the caller to know that,
  and thus no way for a caller to handle a partial write correctly.

- While ser-unix.c:ser_unix_read_prim retries on EINTR,
  ser-tcp.c:net_read_prim does not.

This commit moves EINTR handling to the ser_base_write and
ser_base_readchar level, so all serial backends (at least those that
use it) end up handling EINTR consistently.

gdb/ChangeLog:
2016-04-12  Pedro Alves  <palves@redhat.com>

	* ser-base.c (fd_event): Retry read_prim on EINTR.
	(do_ser_base_readchar): Retry read_prim on EINTR.
	(ser_base_write): Retry write_prim on EINTR.
	* ser-unix.c (ser_unix_read_prim): Don't retry on EINTR here.
	(ser_unix_write_prim): Remove comment.
This commit is contained in:
Pedro Alves
2016-04-12 16:49:31 +01:00
parent 93692b589d
commit 75ee59252d
3 changed files with 26 additions and 14 deletions

View File

@ -1002,21 +1002,11 @@ when debugging using remote targets."),
int
ser_unix_read_prim (struct serial *scb, size_t count)
{
int status;
while (1)
{
status = read (scb->fd, scb->buf, count);
if (status != -1 || errno != EINTR)
break;
}
return status;
return read (scb->fd, scb->buf, count);
}
int
ser_unix_write_prim (struct serial *scb, const void *buf, size_t len)
{
/* ??? Historically, GDB has not retried calls to "write" that
result in EINTR. */
return write (scb->fd, buf, len);
}