diff options
author | Steven Murdoch <Steven.Murdoch@cl.cam.ac.uk> | 2011-09-01 01:06:12 +0100 |
---|---|---|
committer | Steven Murdoch <Steven.Murdoch@cl.cam.ac.uk> | 2011-09-01 01:43:44 +0100 |
commit | 5b8a20ed447f11cda2e0bf528dd78e41e4b76fa4 (patch) | |
tree | b5b80e82ea6df68b9e6de34966c99185a46de1ac /src/common/util.c | |
parent | 76fde28475a5b977d1fa94d06c116ec39a386ac8 (diff) | |
download | tor-5b8a20ed447f11cda2e0bf528dd78e41e4b76fa4.tar.gz tor-5b8a20ed447f11cda2e0bf528dd78e41e4b76fa4.zip |
Make a version of tor_read_all_handle() for non-Windows platforms
Mainly used for testing reading from subprocesses. To be more generic
we now pass in a pointer to a process_handle_t rather than a Windows-
specific HANDLE.
Diffstat (limited to 'src/common/util.c')
-rw-r--r-- | src/common/util.c | 72 |
1 files changed, 60 insertions, 12 deletions
diff --git a/src/common/util.c b/src/common/util.c index 09eb969c2c..30c298e0dc 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -3522,7 +3522,8 @@ tor_get_exit_code(const process_handle_t process_handle, * only once the process has exited, or <b>count</b> bytes are read. Returns * the number of bytes read, or -1 on error. */ ssize_t -tor_read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess) +tor_read_all_handle(HANDLE h, char *buf, size_t count, + const process_handle_t *process) { size_t numread = 0; BOOL retval; @@ -3544,7 +3545,7 @@ tor_read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess) /* Nothing available: process exited or it is busy */ /* Exit if we don't know whether the process is running */ - if (NULL == hProcess) + if (NULL == process) break; /* The process exited and there's nothing left to read from it */ @@ -3554,7 +3555,8 @@ tor_read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess) /* If process is not running, check for output one more time in case it wrote something after the peek was performed. Otherwise keep on waiting for output */ - byte_count = WaitForSingleObject(hProcess, 0); + tor_assert(process != NULL); + byte_count = WaitForSingleObject(process->pid.hProcess, 0); if (WAIT_TIMEOUT != byte_count) process_exited = TRUE; @@ -3576,31 +3578,77 @@ tor_read_all_handle(HANDLE h, char *buf, size_t count, HANDLE hProcess) } return (ssize_t)numread; } +#else +/** Read from a handle <b>h</b> into <b>buf</b>, up to <b>count</b> bytes. If + * <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. */ +ssize_t +tor_read_all_handle(FILE *h, char *buf, size_t count, + const process_handle_t *process) +{ + size_t numread = 0; + char *retval; + + if (count > SIZE_T_CEILING || count > SSIZE_T_MAX) + return -1; + + while (numread != count) { + /* Use fgets because that is what we use in log_from_pipe() */ + retval = fgets(buf+numread, (int)(count-numread), h); + if (NULL == retval) { + if (feof(h)) { + fclose(h); + break; + } else { + if (EAGAIN == errno) { + if (process) + continue; + else + break; + } else { + log_warn(LD_GENERAL, "fgets() from handle failed: %s", + strerror(errno)); + fclose(h); + return -1; + } + } + } + tor_assert(retval != NULL); + numread += strlen(retval); + } + + log_debug(LD_GENERAL, "fgets read %d bytes from handle", (int)numread); + return (ssize_t)numread; +} #endif /** Read from stdout of a process until the process exits. */ ssize_t -tor_read_all_from_process_stdout(const process_handle_t process_handle, - char *buf, size_t count) +tor_read_all_from_process_stdout(const process_handle_t *process_handle, + char *buf, size_t count) { #ifdef MS_WINDOWS - return tor_read_all_handle(process_handle.stdout_pipe, buf, count, - process_handle.pid.hProcess); + return tor_read_all_handle(process_handle->stdout_pipe, buf, count, + process_handle); #else - return read_all(process_handle.stdout_pipe, buf, count, 0); + return tor_read_all_handle(process_handle->stdout_handle, buf, count, + process_handle); #endif } /** Read from stdout of a process until the process exits. */ ssize_t -tor_read_all_from_process_stderr(const process_handle_t process_handle, +tor_read_all_from_process_stderr(const process_handle_t *process_handle, char *buf, size_t count) { #ifdef MS_WINDOWS - return tor_read_all_handle(process_handle.stderr_pipe, buf, count, - process_handle.pid.hProcess); + return tor_read_all_handle(process_handle->stderr_pipe, buf, count, + process_handle); #else - return read_all(process_handle.stderr_pipe, buf, count, 0); + return tor_read_all_handle(process_handle->stderr_handle, buf, count, + process_handle); #endif } |