From d6c18c5804f12f8f4428abce11fc47c64d2a0dd0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 25 Nov 2011 16:47:25 -0500 Subject: [PATCH] Make process_handle_t private and fix some unit tests Let's *not* expose more cross-platform-compatibility structures, or expect code to use them right. Also, don't fclose() stdout_handle and stdin_handle until we do tor_process_handle_destroy, or we risk a double-fclose. --- src/common/util.c | 137 ++++++++++++++++++++++++++++--------------- src/common/util.h | 17 ++++-- src/or/transports.c | 17 +++--- src/test/test_util.c | 56 ++++++++++-------- 4 files changed, 141 insertions(+), 86 deletions(-) diff --git a/src/common/util.c b/src/common/util.c index b6b3c7aa8a..efda6c07f3 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -3165,7 +3165,7 @@ int tor_terminate_process(process_handle_t *process_handle) { #ifdef MS_WINDOWS - if (tor_get_exit_code(*process_handle, 0, NULL) == PROCESS_EXIT_RUNNING) { + if (tor_get_exit_code(process_handle, 0, NULL) == PROCESS_EXIT_RUNNING) { HANDLE handle; /* If the signal is outside of what GenerateConsoleCtrlEvent can use, attempt to open and terminate the process. */ @@ -3197,6 +3197,34 @@ tor_process_get_pid(process_handle_t *process_handle) #endif } +#ifdef MS_WINDOWS +HANDLE +tor_process_get_stdout_pipe(process_handle_t *process_handle) +{ + return process_handle->stdout_pipe; +} +#else +FILE * +tor_process_get_stdout_pipe(process_handle_t *process_handle) +{ + return process_handle->stdout_handle; +} +#endif + +static process_handle_t * +process_handle_new(void) +{ + process_handle_t *out = tor_malloc_zero(sizeof(process_handle_t)); + +#ifndef MS_WINDOWS + out->stdout_pipe = -1; + out->stderr_pipe = -1; +#endif + + return out; +} + +/*DOCDOC*/ #define CHILD_STATE_INIT 0 #define CHILD_STATE_PIPE 1 #define CHILD_STATE_MAXFD 2 @@ -3234,13 +3262,15 @@ tor_spawn_background(const char *const filename, const char **argv, #else const char **envp, #endif - process_handle_t *process_handle) + process_handle_t **process_handle_out) { #ifdef MS_WINDOWS HANDLE stdout_pipe_read = NULL; HANDLE stdout_pipe_write = NULL; HANDLE stderr_pipe_read = NULL; HANDLE stderr_pipe_write = NULL; + process_handle_t *process_handle; + int status; STARTUPINFO siStartInfo; BOOL retval = FALSE; @@ -3250,30 +3280,26 @@ tor_spawn_background(const char *const filename, const char **argv, (void)envp; // Unused on Windows - /* process_handle must not be NULL */ - tor_assert(process_handle != NULL); - saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; /* TODO: should we set explicit security attributes? (#2046, comment 5) */ saAttr.lpSecurityDescriptor = NULL; /* Assume failure to start process */ - memset(process_handle, 0, sizeof(process_handle_t)); - process_handle->status = PROCESS_STATUS_ERROR; + status = PROCESS_STATUS_ERROR; /* Set up pipe for stdout */ if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, &saAttr, 0)) { log_warn(LD_GENERAL, "Failed to create pipe for stdout communication with child process: %s", format_win32_error(GetLastError())); - return process_handle->status; + return status; } if (!SetHandleInformation(stdout_pipe_read, HANDLE_FLAG_INHERIT, 0)) { log_warn(LD_GENERAL, "Failed to configure pipe for stdout communication with child " "process: %s", format_win32_error(GetLastError())); - return process_handle->status; + return status; } /* Set up pipe for stderr */ @@ -3281,13 +3307,13 @@ tor_spawn_background(const char *const filename, const char **argv, log_warn(LD_GENERAL, "Failed to create pipe for stderr communication with child process: %s", format_win32_error(GetLastError())); - return process_handle->status; + return status; } if (!SetHandleInformation(stderr_pipe_read, HANDLE_FLAG_INHERIT, 0)) { log_warn(LD_GENERAL, "Failed to configure pipe for stderr communication with child " "process: %s", format_win32_error(GetLastError())); - return process_handle->status; + return status; } /* Create the child process */ @@ -3296,6 +3322,9 @@ tor_spawn_background(const char *const filename, const char **argv, */ joined_argv = tor_join_win_cmdline(argv); + process_handle = process_handle_new(); + process_handle->status = status; + ZeroMemory(&(process_handle->pid), sizeof(PROCESS_INFORMATION)); ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); @@ -3326,22 +3355,25 @@ tor_spawn_background(const char *const filename, const char **argv, log_warn(LD_GENERAL, "Failed to create child process %s: %s", filename?filename:argv[0], format_win32_error(GetLastError())); + tor_free(process_handle); } else { /* TODO: Close hProcess and hThread in process_handle->pid? */ process_handle->stdout_pipe = stdout_pipe_read; process_handle->stderr_pipe = stderr_pipe_read; - process_handle->status = PROCESS_STATUS_RUNNING; + status = process_handle->status = PROCESS_STATUS_RUNNING; } /* TODO: Close pipes on exit */ - - return process_handle->status; + *process_handle_out = process_handle; + return status; #else // MS_WINDOWS pid_t pid; int stdout_pipe[2]; int stderr_pipe[2]; int fd, retval; ssize_t nbytes; + process_handle_t *process_handle; + int status; const char *error_message = SPAWN_ERROR_MESSAGE; size_t error_message_length; @@ -3354,9 +3386,7 @@ tor_spawn_background(const char *const filename, const char **argv, static int max_fd = -1; - /* Assume failure to start */ - memset(process_handle, 0, sizeof(process_handle_t)); - process_handle->status = PROCESS_STATUS_ERROR; + status = PROCESS_STATUS_ERROR; /* We do the strlen here because strlen() is not signal handler safe, and we are not allowed to use unsafe functions between fork and exec */ @@ -3370,7 +3400,7 @@ tor_spawn_background(const char *const filename, const char **argv, log_warn(LD_GENERAL, "Failed to set up pipe for stdout communication with child process: %s", strerror(errno)); - return process_handle->status; + return status; } retval = pipe(stderr_pipe); @@ -3378,7 +3408,7 @@ tor_spawn_background(const char *const filename, const char **argv, log_warn(LD_GENERAL, "Failed to set up pipe for stderr communication with child process: %s", strerror(errno)); - return process_handle->status; + return status; } child_state = CHILD_STATE_MAXFD; @@ -3468,7 +3498,7 @@ tor_spawn_background(const char *const filename, const char **argv, _exit(255); /* Never reached, but avoids compiler warning */ - return process_handle->status; + return status; } /* In parent */ @@ -3479,9 +3509,11 @@ tor_spawn_background(const char *const filename, const char **argv, close(stdout_pipe[1]); close(stderr_pipe[0]); close(stderr_pipe[1]); - return process_handle->status; + return status; } + process_handle = process_handle_new(); + process_handle->status = status; process_handle->pid = pid; /* TODO: If the child process forked but failed to exec, waitpid it */ @@ -3505,7 +3537,7 @@ tor_spawn_background(const char *const filename, const char **argv, strerror(errno)); } - process_handle->status = PROCESS_STATUS_RUNNING; + status = process_handle->status = PROCESS_STATUS_RUNNING; /* Set stdout/stderr pipes to be non-blocking */ fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK); fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK); @@ -3513,6 +3545,7 @@ tor_spawn_background(const char *const filename, const char **argv, process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r"); process_handle->stderr_handle = fdopen(process_handle->stderr_pipe, "r"); + *process_handle_out = process_handle; return process_handle->status; #endif // MS_WINDOWS } @@ -3525,6 +3558,9 @@ void tor_process_handle_destroy(process_handle_t *process_handle, int also_terminate_process) { + if (!process_handle) + return; + if (also_terminate_process) { if (tor_terminate_process(process_handle) < 0) { log_notice(LD_GENERAL, "Failed to terminate process with PID '%d'", @@ -3551,6 +3587,7 @@ tor_process_handle_destroy(process_handle_t *process_handle, fclose(process_handle->stderr_handle); #endif + memset(process_handle, 0x0f, sizeof(process_handle_t)); tor_free(process_handle); } @@ -3565,7 +3602,7 @@ tor_process_handle_destroy(process_handle_t *process_handle, * probably not work in Tor, because waitpid() is called in main.c to reap any * terminated child processes.*/ int -tor_get_exit_code(const process_handle_t process_handle, +tor_get_exit_code(const process_handle_t *process_handle, int block, int *exit_code) { #ifdef MS_WINDOWS @@ -3574,14 +3611,14 @@ tor_get_exit_code(const process_handle_t process_handle, if (block) { /* Wait for the process to exit */ - retval = WaitForSingleObject(process_handle.pid.hProcess, INFINITE); + retval = WaitForSingleObject(process_handle->pid.hProcess, INFINITE); if (retval != WAIT_OBJECT_0) { log_warn(LD_GENERAL, "WaitForSingleObject() failed (%d): %s", (int)retval, format_win32_error(GetLastError())); return PROCESS_EXIT_ERROR; } } else { - retval = WaitForSingleObject(process_handle.pid.hProcess, 0); + retval = WaitForSingleObject(process_handle->pid.hProcess, 0); if (WAIT_TIMEOUT == retval) { /* Process has not exited */ return PROCESS_EXIT_RUNNING; @@ -3593,7 +3630,7 @@ tor_get_exit_code(const process_handle_t process_handle, } if (exit_code != NULL) { - success = GetExitCodeProcess(process_handle.pid.hProcess, + success = GetExitCodeProcess(process_handle->pid.hProcess, (PDWORD)exit_code); if (!success) { log_warn(LD_GENERAL, "GetExitCodeProcess() failed: %s", @@ -3605,19 +3642,19 @@ tor_get_exit_code(const process_handle_t process_handle, int stat_loc; int retval; - retval = waitpid(process_handle.pid, &stat_loc, block?0:WNOHANG); + retval = waitpid(process_handle->pid, &stat_loc, block?0:WNOHANG); if (!block && 0 == retval) { /* Process has not exited */ return PROCESS_EXIT_RUNNING; - } else if (retval != process_handle.pid) { - log_warn(LD_GENERAL, "waitpid() failed for PID %d: %s", process_handle.pid, + } else if (retval != process_handle->pid) { + log_warn(LD_GENERAL, "waitpid() failed for PID %d: %s", process_handle->pid, strerror(errno)); return PROCESS_EXIT_ERROR; } if (!WIFEXITED(stat_loc)) { log_warn(LD_GENERAL, "Process %d did not exit normally", - process_handle.pid); + process_handle->pid); return PROCESS_EXIT_ERROR; } @@ -3719,7 +3756,6 @@ tor_read_all_handle(FILE *h, char *buf, size_t count, if (NULL == retval) { if (feof(h)) { log_debug(LD_GENERAL, "fgets() reached end of file"); - fclose(h); if (eof) *eof = 1; break; @@ -3732,7 +3768,6 @@ tor_read_all_handle(FILE *h, char *buf, size_t count, } else { log_warn(LD_GENERAL, "fgets() from handle failed: %s", strerror(errno)); - fclose(h); return -1; } } @@ -3892,12 +3927,10 @@ log_from_pipe(FILE *stream, int severity, const char *executable, r = get_string_from_pipe(stream, buf, sizeof(buf) - 1); if (r == IO_STREAM_CLOSED) { - fclose(stream); return 1; } else if (r == IO_STREAM_EAGAIN) { return 0; } else if (r == IO_STREAM_TERM) { - fclose(stream); return -1; } @@ -4005,7 +4038,7 @@ tor_check_port_forwarding(const char *filename, int dir_port, int or_port, /* Static variables are initialized to zero, so child_handle.status=0 * which corresponds to it not running on startup */ - static process_handle_t child_handle; + static process_handle_t *child_handle=NULL; static time_t time_to_run_helper = 0; int stdout_status, stderr_status, retval; @@ -4031,18 +4064,26 @@ tor_check_port_forwarding(const char *filename, int dir_port, int or_port, argv[9] = NULL; /* Start the child, if it is not already running */ - if (child_handle.status != PROCESS_STATUS_RUNNING && + if ((!child_handle || child_handle->status != PROCESS_STATUS_RUNNING) && time_to_run_helper < now) { + int status; + /* Assume tor-fw-helper will succeed, start it later*/ time_to_run_helper = now + TIME_TO_EXEC_FWHELPER_SUCCESS; + if (child_handle) { + tor_process_handle_destroy(child_handle, 1); + child_handle = NULL; + } + #ifdef MS_WINDOWS /* Passing NULL as lpApplicationName makes Windows search for the .exe */ - tor_spawn_background(NULL, argv, NULL, &child_handle); + status = tor_spawn_background(NULL, argv, NULL, &child_handle); #else - tor_spawn_background(filename, argv, NULL, &child_handle); + status = tor_spawn_background(filename, argv, NULL, &child_handle); #endif - if (PROCESS_STATUS_ERROR == child_handle.status) { + + if (PROCESS_STATUS_ERROR == status) { log_warn(LD_GENERAL, "Failed to start port forwarding helper %s", filename); time_to_run_helper = now + TIME_TO_EXEC_FWHELPER_FAIL; @@ -4051,22 +4092,22 @@ tor_check_port_forwarding(const char *filename, int dir_port, int or_port, log_info(LD_GENERAL, "Started port forwarding helper (%s) with pid '%d'", - filename, tor_process_get_pid(&child_handle)); + filename, tor_process_get_pid(child_handle)); } /* If child is running, read from its stdout and stderr) */ - if (PROCESS_STATUS_RUNNING == child_handle.status) { + if (child_handle && PROCESS_STATUS_RUNNING == child_handle->status) { /* Read from stdout/stderr and log result */ retval = 0; #ifdef MS_WINDOWS - stdout_status = log_from_handle(child_handle.stdout_pipe, LOG_INFO); - stderr_status = log_from_handle(child_handle.stderr_pipe, LOG_WARN); + stdout_status = log_from_handle(child_handle->stdout_pipe, LOG_INFO); + stderr_status = log_from_handle(child_handle->stderr_pipe, LOG_WARN); /* If we got this far (on Windows), the process started */ retval = 0; #else - stdout_status = log_from_pipe(child_handle.stdout_handle, + stdout_status = log_from_pipe(child_handle->stdout_handle, LOG_INFO, filename, &retval); - stderr_status = log_from_pipe(child_handle.stderr_handle, + stderr_status = log_from_pipe(child_handle->stderr_handle, LOG_WARN, filename, &retval); #endif if (retval) { @@ -4079,7 +4120,7 @@ tor_check_port_forwarding(const char *filename, int dir_port, int or_port, /* There was a failure */ retval = -1; #ifdef MS_WINDOWS - else if (tor_get_exit_code(child_handle, 0, NULL) != + else if (!child_handle || tor_get_exit_code(child_handle, 0, NULL) != PROCESS_EXIT_RUNNING) { /* process has exited or there was an error */ /* TODO: Do something with the process return value */ @@ -4102,10 +4143,10 @@ tor_check_port_forwarding(const char *filename, int dir_port, int or_port, if (0 != retval) { if (1 == retval) { log_info(LD_GENERAL, "Port forwarding helper terminated"); - child_handle.status = PROCESS_STATUS_NOTRUNNING; + child_handle->status = PROCESS_STATUS_NOTRUNNING; } else { log_warn(LD_GENERAL, "Failed to read from port forwarding helper"); - child_handle.status = PROCESS_STATUS_ERROR; + child_handle->status = PROCESS_STATUS_ERROR; } /* TODO: The child might not actually be finished (maybe it failed or diff --git a/src/common/util.h b/src/common/util.h index a9002254e7..f5e8deb661 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -356,14 +356,14 @@ void write_pidfile(char *filename); void tor_check_port_forwarding(const char *filename, int dir_port, int or_port, time_t now); -typedef struct process_handle_s process_handle_t; +typedef struct process_handle_t process_handle_t; int tor_spawn_background(const char *const filename, const char **argv, #ifdef MS_WINDOWS LPVOID envp, #else const char **envp, #endif - process_handle_t *process_handle); + process_handle_t **process_handle_out); #define SPAWN_ERROR_MESSAGE "ERR: Failed to spawn background process - code " @@ -377,7 +377,10 @@ HANDLE load_windows_system_library(const TCHAR *library_name); #define PROCESS_STATUS_NOTRUNNING 0 #define PROCESS_STATUS_RUNNING 1 #define PROCESS_STATUS_ERROR -1 -struct process_handle_s { + +#ifdef UTIL_PRIVATE +/*DOCDOC*/ +struct process_handle_t { int status; #ifdef MS_WINDOWS HANDLE stdout_pipe; @@ -391,12 +394,13 @@ struct process_handle_s { pid_t pid; #endif // MS_WINDOWS }; +#endif /* Return values of tor_get_exit_code() */ #define PROCESS_EXIT_RUNNING 1 #define PROCESS_EXIT_EXITED 0 #define PROCESS_EXIT_ERROR -1 -int tor_get_exit_code(const process_handle_t process_handle, +int tor_get_exit_code(const process_handle_t *process_handle, int block, int *exit_code); int tor_split_lines(struct smartlist_t *sl, char *buf, int len); #ifdef MS_WINDOWS @@ -414,6 +418,11 @@ ssize_t tor_read_all_from_process_stderr( char *tor_join_win_cmdline(const char *argv[]); int tor_process_get_pid(process_handle_t *process_handle); +#ifdef MS_WINDOWS +HANDLE tor_process_get_stdout_pipe(process_handle_t *process_handle); +#else +FILE *tor_process_get_stdout_pipe(process_handle_t *process_handle); +#endif int tor_terminate_process(process_handle_t *process_handle); void tor_process_handle_destroy(process_handle_t *process_handle, diff --git a/src/or/transports.c b/src/or/transports.c index c38b027e1d..5e96b39a32 100644 --- a/src/or/transports.c +++ b/src/or/transports.c @@ -239,9 +239,7 @@ proxy_prepare_for_restart(managed_proxy_t *mp) /* destroy the process handle and terminate the process. */ tor_process_handle_destroy(mp->process_handle, 1); - - /* create process handle for the upcoming new process. */ - mp->process_handle = tor_malloc_zero(sizeof(process_handle_t)); + mp->process_handle = NULL; /* destroy all its old transports. we no longer use them. */ SMARTLIST_FOREACH_BEGIN(mp->transports, const char *, t_name) { @@ -274,7 +272,7 @@ launch_managed_proxy(managed_proxy_t *mp) /* Passing NULL as lpApplicationName makes Windows search for the .exe */ retval = tor_spawn_background(NULL, (const char **)mp->argv, envp, - mp->process_handle); + &mp->process_handle); tor_free(envp); @@ -291,7 +289,7 @@ launch_managed_proxy(managed_proxy_t *mp) } retval = tor_spawn_background(mp->argv[0], (const char **)mp->argv, - (const char **)envp, mp->process_handle); + (const char **)envp, &mp->process_handle); /* free the memory allocated by set_managed_proxy_environment(). */ free_execve_args(envp); @@ -371,8 +369,9 @@ configure_proxy(managed_proxy_t *mp) } tor_assert(mp->conf_state != PT_PROTO_INFANT); + tor_assert(mp->process_handle); - pos = tor_read_all_handle(mp->process_handle->stdout_pipe, + pos = tor_read_all_handle(tor_process_get_stdout_pipe(mp->process_handle), stdout_buf, sizeof(stdout_buf) - 1, NULL); if (pos < 0) { log_notice(LD_GENERAL, "Failed to read data from managed proxy"); @@ -426,9 +425,10 @@ configure_proxy(managed_proxy_t *mp) } tor_assert(mp->conf_state != PT_PROTO_INFANT); + tor_assert(mp->process_handle); while (1) { - r = get_string_from_pipe(mp->process_handle->stdout_handle, + r = get_string_from_pipe(tor_process_get_stdout_pipe(mp->process_handle), stdout_buf, sizeof(stdout_buf) - 1); if (r == IO_STREAM_OKAY) { /* got a line; handle it! */ @@ -550,6 +550,7 @@ managed_proxy_destroy(managed_proxy_t *mp, free_execve_args(mp->argv); tor_process_handle_destroy(mp->process_handle, also_terminate_process); + mp->process_handle = NULL; tor_free(mp); } @@ -1119,8 +1120,6 @@ managed_proxy_create(const smartlist_t *transport_list, SMARTLIST_FOREACH(transport_list, const char *, transport, add_transport_to_proxy(transport, mp)); - mp->process_handle = tor_malloc_zero(sizeof(process_handle_t)); - /* register the managed proxy */ if (!managed_proxy_list) managed_proxy_list = smartlist_create(); diff --git a/src/test/test_util.c b/src/test/test_util.c index 64bf52e7b1..93f11cd208 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -1388,27 +1388,29 @@ run_util_spawn_background(const char *argv[], const char *expected_out, { int retval, exit_code; ssize_t pos; - process_handle_t process_handle; + process_handle_t *process_handle=NULL; char stdout_buf[100], stderr_buf[100]; + int status; /* Start the program */ #ifdef MS_WINDOWS - tor_spawn_background(NULL, argv, NULL, &process_handle); + status = tor_spawn_background(NULL, argv, NULL, &process_handle); #else - tor_spawn_background(argv[0], argv, NULL, &process_handle); + status = tor_spawn_background(argv[0], argv, NULL, &process_handle); #endif - tt_int_op(process_handle.status, ==, expected_status); - - /* If the process failed to start, don't bother continuing */ - if (process_handle.status == PROCESS_STATUS_ERROR) + tt_int_op(status, ==, expected_status); + if (status == PROCESS_STATUS_ERROR) return; - tt_int_op(process_handle.stdout_pipe, >, 0); - tt_int_op(process_handle.stderr_pipe, >, 0); + tt_assert(process_handle != NULL); + tt_int_op(process_handle->status, ==, expected_status); + + tt_int_op(process_handle->stdout_pipe, >, 0); + tt_int_op(process_handle->stderr_pipe, >, 0); /* Check stdout */ - pos = tor_read_all_from_process_stdout(&process_handle, stdout_buf, + pos = tor_read_all_from_process_stdout(process_handle, stdout_buf, sizeof(stdout_buf) - 1); tt_assert(pos >= 0); stdout_buf[pos] = '\0'; @@ -1422,7 +1424,7 @@ run_util_spawn_background(const char *argv[], const char *expected_out, // TODO: Make test-child exit with something other than 0 /* Check stderr */ - pos = tor_read_all_from_process_stderr(&process_handle, stderr_buf, + pos = tor_read_all_from_process_stderr(process_handle, stderr_buf, sizeof(stderr_buf) - 1); tt_assert(pos >= 0); stderr_buf[pos] = '\0'; @@ -1430,7 +1432,8 @@ run_util_spawn_background(const char *argv[], const char *expected_out, tt_int_op(pos, ==, strlen(expected_err)); done: - ; + if (process_handle) + tor_process_handle_destroy(process_handle, 1); } /** Check that we can launch a process and read the output */ @@ -1489,7 +1492,8 @@ test_util_spawn_background_partial_read(void *ptr) int retval, exit_code; ssize_t pos = -1; - process_handle_t process_handle; + process_handle_t *process_handle=NULL; + int status; char stdout_buf[100], stderr_buf[100]; #ifdef MS_WINDOWS const char *argv[] = {"test-child.exe", "--test", NULL}; @@ -1510,21 +1514,23 @@ test_util_spawn_background_partial_read(void *ptr) /* Start the program */ #ifdef MS_WINDOWS - tor_spawn_background(NULL, argv, NULL, &process_handle); + status = tor_spawn_background(NULL, argv, NULL, &process_handle); #else - tor_spawn_background(argv[0], argv, NULL, &process_handle); + status = tor_spawn_background(argv[0], argv, NULL, &process_handle); #endif - tt_int_op(process_handle.status, ==, expected_status); + tt_int_op(status, ==, expected_status); + tt_assert(process_handle); + tt_int_op(process_handle->status, ==, expected_status); /* Check stdout */ - for (expected_out_ctr =0; expected_out[expected_out_ctr] != NULL;) { + for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) { #ifdef MS_WINDOWS - pos = tor_read_all_handle(process_handle.stdout_pipe, stdout_buf, + pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf, sizeof(stdout_buf) - 1, NULL); #else /* Check that we didn't read the end of file last time */ tt_assert(!eof); - pos = tor_read_all_handle(process_handle.stdout_handle, stdout_buf, + pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf, sizeof(stdout_buf) - 1, NULL, &eof); #endif log_info(LD_GENERAL, "tor_read_all_handle() returned %d", (int)pos); @@ -1542,16 +1548,16 @@ test_util_spawn_background_partial_read(void *ptr) /* The process should have exited without writing more */ #ifdef MS_WINDOWS - pos = tor_read_all_handle(process_handle.stdout_pipe, stdout_buf, + pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf, sizeof(stdout_buf) - 1, - &process_handle); + process_handle); tt_int_op(pos, ==, 0); #else if (!eof) { /* We should have got all the data, but maybe not the EOF flag */ - pos = tor_read_all_handle(process_handle.stdout_handle, stdout_buf, + pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf, sizeof(stdout_buf) - 1, - &process_handle, &eof); + process_handle, &eof); tt_int_op(pos, ==, 0); tt_assert(eof); } @@ -1566,7 +1572,7 @@ test_util_spawn_background_partial_read(void *ptr) // TODO: Make test-child exit with something other than 0 /* Check stderr */ - pos = tor_read_all_from_process_stderr(&process_handle, stderr_buf, + pos = tor_read_all_from_process_stderr(process_handle, stderr_buf, sizeof(stderr_buf) - 1); tt_assert(pos >= 0); stderr_buf[pos] = '\0'; @@ -1574,7 +1580,7 @@ test_util_spawn_background_partial_read(void *ptr) tt_int_op(pos, ==, strlen(expected_err)); done: - ; + tor_process_handle_destroy(process_handle, 1); } /**