aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorSteven Murdoch <Steven.Murdoch@cl.cam.ac.uk>2011-09-01 13:09:38 +0100
committerSteven Murdoch <Steven.Murdoch@cl.cam.ac.uk>2011-09-01 14:15:54 +0100
commitcfa9ee5fe708539965f46a31b5d2abe4950179af (patch)
tree953e203a0834710140330a4cd6c1c4997148b10d /src/common
parenta500389904c992e492db0c219e5019ed44704c29 (diff)
downloadtor-cfa9ee5fe708539965f46a31b5d2abe4950179af.tar.gz
tor-cfa9ee5fe708539965f46a31b5d2abe4950179af.zip
Fix double-closing a stdio stream
After a stream reached eof, we fclose it, but then test_util_spawn_background_partial_read() reads from it again, which causes an error and thus another fclose(). Some platforms are fine with this, others (e.g. debian-sid-i386) trigger a double-free() error. The actual code used by Tor (log_from_pipe() and tor_check_port_forwarding()) handle this case correctly.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/util.c18
-rw-r--r--src/common/util.h3
2 files changed, 15 insertions, 6 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 7cd9dd8e0e..db6b00f085 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -3583,14 +3583,19 @@ tor_read_all_handle(HANDLE h, char *buf, size_t count,
* <b>process</b> is NULL, the function will return immediately if there is
* nothing more to read. Otherwise data will be read until end of file, or
* <b>count</b> bytes are read. Returns the number of bytes read, or -1 on
- * error. */
+ * error. Sets <b>eof</b> to true if <b>eof</b> is not NULL and the end of the
+ * file has been reached. */
ssize_t
tor_read_all_handle(FILE *h, char *buf, size_t count,
- const process_handle_t *process)
+ const process_handle_t *process,
+ int *eof)
{
size_t numread = 0;
char *retval;
+ if (eof)
+ *eof = 0;
+
if (count > SIZE_T_CEILING || count > SSIZE_T_MAX)
return -1;
@@ -3599,7 +3604,10 @@ tor_read_all_handle(FILE *h, char *buf, size_t count,
retval = fgets(buf+numread, (int)(count-numread), h);
if (NULL == retval) {
if (feof(h)) {
+ log_debug(LD_GENERAL, "fgets() reached end of file");
fclose(h);
+ if (eof)
+ *eof = 1;
break;
} else {
if (EAGAIN == errno) {
@@ -3620,7 +3628,7 @@ tor_read_all_handle(FILE *h, char *buf, size_t count,
numread += strlen(retval);
}
- log_debug(LD_GENERAL, "fgets read %d bytes from handle", (int)numread);
+ log_debug(LD_GENERAL, "fgets() read %d bytes from handle", (int)numread);
return (ssize_t)numread;
}
#endif
@@ -3635,7 +3643,7 @@ tor_read_all_from_process_stdout(const process_handle_t *process_handle,
process_handle);
#else
return tor_read_all_handle(process_handle->stdout_handle, buf, count,
- process_handle);
+ process_handle, NULL);
#endif
}
@@ -3649,7 +3657,7 @@ tor_read_all_from_process_stderr(const process_handle_t *process_handle,
process_handle);
#else
return tor_read_all_handle(process_handle->stderr_handle, buf, count,
- process_handle);
+ process_handle, NULL);
#endif
}
diff --git a/src/common/util.h b/src/common/util.h
index 6211267d05..c8cce39f3c 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -391,7 +391,8 @@ ssize_t tor_read_all_handle(HANDLE h, char *buf, size_t count,
const process_handle_t *process);
#else
ssize_t tor_read_all_handle(FILE *h, char *buf, size_t count,
- const process_handle_t *process);
+ const process_handle_t *process,
+ int *eof);
#endif
ssize_t tor_read_all_from_process_stdout(
const process_handle_t *process_handle, char *buf, size_t count);