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:
parent
93692b589d
commit
75ee59252d
|
@ -1,3 +1,11 @@
|
|||
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.
|
||||
|
||||
2016-04-12 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* remote.c (remote_pass_ctrlc): New function.
|
||||
|
|
|
@ -164,7 +164,13 @@ fd_event (int error, void *context)
|
|||
pull characters out of the buffer. See also
|
||||
generic_readchar(). */
|
||||
int nr;
|
||||
nr = scb->ops->read_prim (scb, BUFSIZ);
|
||||
|
||||
do
|
||||
{
|
||||
nr = scb->ops->read_prim (scb, BUFSIZ);
|
||||
}
|
||||
while (nr < 0 && errno == EINTR);
|
||||
|
||||
if (nr == 0)
|
||||
{
|
||||
scb->bufcnt = SERIAL_EOF;
|
||||
|
@ -358,7 +364,11 @@ do_ser_base_readchar (struct serial *scb, int timeout)
|
|||
if (status < 0)
|
||||
return status;
|
||||
|
||||
status = scb->ops->read_prim (scb, BUFSIZ);
|
||||
do
|
||||
{
|
||||
status = scb->ops->read_prim (scb, BUFSIZ);
|
||||
}
|
||||
while (status < 0 && errno == EINTR);
|
||||
|
||||
if (status <= 0)
|
||||
{
|
||||
|
@ -448,7 +458,11 @@ ser_base_write (struct serial *scb, const void *buf, size_t count)
|
|||
cc = scb->ops->write_prim (scb, str, count);
|
||||
|
||||
if (cc < 0)
|
||||
return 1;
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
count -= cc;
|
||||
str += cc;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue