Fix possible infinite loop on pipe/sock_drain()

If the returned value of read/recv is 0 (meaning EOF), we'll end up in an
infinite loop (active wait) until something is written on the pipe which is
not really what we want here especially because those functions are called
from the main thread.

Signed-off-by: David Goulet <dgoulet@ev0ke.net>
This commit is contained in:
David Goulet 2015-01-30 14:59:48 -05:00
parent 44e9dafb67
commit 51f793e37e
2 changed files with 14 additions and 6 deletions

4
changes/bug14554 Normal file
View File

@ -0,0 +1,4 @@
o Major bugfix
- Possibility of an infinite loop if the returned value of the read/recv
was 0. A returned value of 0 means that we've reached the EOF thus the
pipe/sock is drained so return success not an error.

View File

@ -171,10 +171,12 @@ pipe_drain(int fd)
{
char buf[32];
ssize_t r;
while ((r = read_ni(fd, buf, sizeof(buf))) >= 0)
;
if (r == 0 || errno != EAGAIN)
do {
r = read_ni(fd, buf, sizeof(buf));
} while (r > 0);
if (errno != EAGAIN)
return -1;
/* A value of r = 0 means EOF on the fd so successfully drained. */
return 0;
}
#endif
@ -193,10 +195,12 @@ sock_drain(tor_socket_t fd)
{
char buf[32];
ssize_t r;
while ((r = recv_ni(fd, buf, sizeof(buf), 0)) >= 0)
;
if (r == 0 || !ERRNO_IS_EAGAIN(tor_socket_errno(fd)))
do {
r = recv_ni(fd, buf, sizeof(buf), 0);
} while (r > 0);
if (!ERRNO_IS_EAGAIN(tor_socket_errno(fd)))
return -1;
/* A value of r = 0 means EOF on the fd so successfully drained. */
return 0;
}