summaryrefslogtreecommitdiff
path: root/src/common/util.c
diff options
context:
space:
mode:
authorAlexander Færøy <ahf@torproject.org>2017-03-08 00:12:06 +0100
committerAlexander Færøy <ahf@0x90.dk>2017-03-08 02:08:44 +0100
commit86de065aee642585e092969c69681f7e8847a648 (patch)
tree22df8b955226c3e8d8b2876630bf92a8c86a746e /src/common/util.c
parentad19f1507ac3bfd4b26ae478e61c8ef8c4057f22 (diff)
downloadtor-86de065aee642585e092969c69681f7e8847a648.tar.gz
tor-86de065aee642585e092969c69681f7e8847a648.zip
Use read(2) instead of fgets(3) when reading process output.
This patch modifies `tor_read_all_handle()` to use read(2) instead of fgets(3) when reading the stdout from the child process. This should eliminate the race condition that can be triggered in the 'slow/util/*' tests on slower machines running OpenBSD, FreeBSD and HardenedBSD. See: https://bugs.torproject.org/21654
Diffstat (limited to 'src/common/util.c')
-rw-r--r--src/common/util.c42
1 files changed, 18 insertions, 24 deletions
diff --git a/src/common/util.c b/src/common/util.c
index a69d887e30..e2ad5ffa48 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -5010,7 +5010,7 @@ tor_read_all_handle(FILE *h, char *buf, size_t count,
int *eof)
{
size_t numread = 0;
- char *retval;
+ ssize_t result;
if (eof)
*eof = 0;
@@ -5019,33 +5019,27 @@ tor_read_all_handle(FILE *h, char *buf, size_t count,
return -1;
while (numread != count) {
- /* Use fgets because that is what we use in log_from_pipe() */
- retval = tor_fgets(buf+numread, (int)(count-numread), h);
- if (NULL == retval) {
- if (feof(h)) {
- log_debug(LD_GENERAL, "fgets() reached end of file");
- if (eof)
- *eof = 1;
+ result = read(fileno(h), buf+numread, count-numread);
+
+ if (result == 0) {
+ log_debug(LD_GENERAL, "read() reached end of file");
+ if (eof)
+ *eof = 1;
+ break;
+ } else if (result < 0 && errno == EAGAIN) {
+ if (process)
+ continue;
+ else
break;
- } else {
- if (EAGAIN == errno) {
- if (process)
- continue;
- else
- break;
- } else {
- log_warn(LD_GENERAL, "fgets() from handle failed: %s",
- strerror(errno));
- return -1;
- }
- }
+ } else if (result < 0) {
+ log_warn(LD_GENERAL, "read() failed: %s", strerror(errno));
+ return -1;
}
- tor_assert(retval != NULL);
- tor_assert(strlen(retval) + numread <= count);
- numread += strlen(retval);
+
+ numread += result;
}
- log_debug(LD_GENERAL, "fgets() read %d bytes from handle", (int)numread);
+ log_debug(LD_GENERAL, "read() read %d bytes from handle", (int)numread);
return (ssize_t)numread;
}
#endif