diff options
author | David Goulet <dgoulet@ev0ke.net> | 2015-01-30 14:59:48 -0500 |
---|---|---|
committer | David Goulet <dgoulet@ev0ke.net> | 2015-01-30 15:05:18 -0500 |
commit | 51f793e37e55b29700f76ca9cdb3199e636bb51d (patch) | |
tree | e8d628a7662d51a41258a5215035f0dd5c26873f /src/common/compat_threads.c | |
parent | 44e9dafb67370aa6fb163cda150a80466f668111 (diff) | |
download | tor-51f793e37e55b29700f76ca9cdb3199e636bb51d.tar.gz tor-51f793e37e55b29700f76ca9cdb3199e636bb51d.zip |
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>
Diffstat (limited to 'src/common/compat_threads.c')
-rw-r--r-- | src/common/compat_threads.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c index d2d929e430..ff8dc1ca61 100644 --- a/src/common/compat_threads.c +++ b/src/common/compat_threads.c @@ -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; } |