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.
This commit is contained in:
Steven Murdoch
2011-09-01 01:06:12 +01:00
parent 76fde28475
commit 5b8a20ed44
3 changed files with 94 additions and 34 deletions
+60 -12
View File
@@ -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
}
+8 -5
View File
@@ -388,12 +388,15 @@ int tor_get_exit_code(const process_handle_t process_handle,
int tor_split_lines(struct smartlist_t *sl, char *buf, int len);
#ifdef MS_WINDOWS
ssize_t tor_read_all_handle(HANDLE h, char *buf, size_t count,
HANDLE hProcess);
const process_handle_t *process);
#else
ssize_t tor_read_all_handle(FILE *h, char *buf, size_t count,
const process_handle_t *process);
#endif
ssize_t tor_read_all_from_process_stdout(const process_handle_t process_handle,
char *buf, size_t count);
ssize_t tor_read_all_from_process_stderr(const process_handle_t process_handle,
char *buf, size_t count);
ssize_t tor_read_all_from_process_stdout(
const process_handle_t *process_handle, char *buf, size_t count);
ssize_t tor_read_all_from_process_stderr(
const process_handle_t *process_handle, char *buf, size_t count);
char *tor_join_win_cmdline(const char *argv[]);
void format_helper_exit_status(unsigned char child_state,
int saved_errno, char *hex_errno);