From 51f793e37e55b29700f76ca9cdb3199e636bb51d Mon Sep 17 00:00:00 2001 From: David Goulet Date: Fri, 30 Jan 2015 14:59:48 -0500 Subject: 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 --- src/common/compat_threads.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'src') 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; } -- cgit v1.2.3-54-g00ecf From 2c41f120481b7b14fcf0ef3aaf78d84f47178cb7 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Fri, 30 Jan 2015 15:18:40 -0500 Subject: Fix: check r < 0 before checking errno Signed-off-by: David Goulet --- src/common/compat_threads.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c index ff8dc1ca61..15648d2851 100644 --- a/src/common/compat_threads.c +++ b/src/common/compat_threads.c @@ -174,7 +174,7 @@ pipe_drain(int fd) do { r = read_ni(fd, buf, sizeof(buf)); } while (r > 0); - if (errno != EAGAIN) + if (r < 0 && errno != EAGAIN) return -1; /* A value of r = 0 means EOF on the fd so successfully drained. */ return 0; @@ -198,7 +198,7 @@ sock_drain(tor_socket_t fd) do { r = recv_ni(fd, buf, sizeof(buf), 0); } while (r > 0); - if (!ERRNO_IS_EAGAIN(tor_socket_errno(fd))) + if (r < 0 && !ERRNO_IS_EAGAIN(tor_socket_errno(fd))) return -1; /* A value of r = 0 means EOF on the fd so successfully drained. */ return 0; -- cgit v1.2.3-54-g00ecf