Loading changes/feature15435 0 → 100644 +5 −0 Original line number Diff line number Diff line o Minor features (pluggable Transports): - When launching managed pluggable transports, setup a valid open stdin in the child process that can be used to detect if tor has terminated. The "TOR_PT_EXIT_ON_STDIN_CLOSE" enviornment variable can be used by implementations to detect this new behavior. Resolves ticket 15435. src/common/util.c +67 −14 Original line number Diff line number Diff line Loading @@ -3942,9 +3942,11 @@ process_handle_new(void) process_handle_t *out = tor_malloc_zero(sizeof(process_handle_t)); #ifdef _WIN32 out->stdin_pipe = INVALID_HANDLE_VALUE; out->stdout_pipe = INVALID_HANDLE_VALUE; out->stderr_pipe = INVALID_HANDLE_VALUE; #else out->stdin_pipe = -1; out->stdout_pipe = -1; out->stderr_pipe = -1; #endif Loading Loading @@ -3984,7 +3986,7 @@ process_handle_waitpid_cb(int status, void *arg) #define CHILD_STATE_FORK 3 #define CHILD_STATE_DUPOUT 4 #define CHILD_STATE_DUPERR 5 #define CHILD_STATE_REDIRECT 6 #define CHILD_STATE_DUPIN 6 #define CHILD_STATE_CLOSEFD 7 #define CHILD_STATE_EXEC 8 #define CHILD_STATE_FAILEXEC 9 Loading Loading @@ -4018,6 +4020,8 @@ tor_spawn_background(const char *const filename, const char **argv, HANDLE stdout_pipe_write = NULL; HANDLE stderr_pipe_read = NULL; HANDLE stderr_pipe_write = NULL; HANDLE stdin_pipe_read = NULL; HANDLE stdin_pipe_write = NULL; process_handle_t *process_handle; int status; Loading Loading @@ -4063,6 +4067,20 @@ tor_spawn_background(const char *const filename, const char **argv, return status; } /* Set up pipe for stdin */ if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, &saAttr, 0)) { log_warn(LD_GENERAL, "Failed to create pipe for stdin communication with child process: %s", format_win32_error(GetLastError())); return status; } if (!SetHandleInformation(stderr_pipe_write, HANDLE_FLAG_INHERIT, 0)) { log_warn(LD_GENERAL, "Failed to configure pipe for stdin communication with child " "process: %s", format_win32_error(GetLastError())); return status; } /* Create the child process */ /* Windows expects argv to be a whitespace delimited string, so join argv up Loading @@ -4077,7 +4095,7 @@ tor_spawn_background(const char *const filename, const char **argv, siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = stderr_pipe_write; siStartInfo.hStdOutput = stdout_pipe_write; siStartInfo.hStdInput = NULL; siStartInfo.hStdInput = stdin_pipe_read; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; /* Create the child process */ Loading Loading @@ -4107,6 +4125,7 @@ tor_spawn_background(const char *const filename, const char **argv, /* 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->stdin_pipe = stdin_pipe_write; status = process_handle->status = PROCESS_STATUS_RUNNING; } Loading @@ -4117,6 +4136,7 @@ tor_spawn_background(const char *const filename, const char **argv, pid_t pid; int stdout_pipe[2]; int stderr_pipe[2]; int stdin_pipe[2]; int fd, retval; ssize_t nbytes; process_handle_t *process_handle; Loading @@ -4141,7 +4161,7 @@ tor_spawn_background(const char *const filename, const char **argv, child_state = CHILD_STATE_PIPE; /* Set up pipe for redirecting stdout and stderr of child */ /* Set up pipe for redirecting stdout, stderr, and stdin of child */ retval = pipe(stdout_pipe); if (-1 == retval) { log_warn(LD_GENERAL, Loading @@ -4162,6 +4182,20 @@ tor_spawn_background(const char *const filename, const char **argv, return status; } retval = pipe(stdin_pipe); if (-1 == retval) { log_warn(LD_GENERAL, "Failed to set up pipe for stdin communication with child process: %s", strerror(errno)); close(stdout_pipe[0]); close(stdout_pipe[1]); close(stderr_pipe[0]); close(stderr_pipe[1]); return status; } child_state = CHILD_STATE_MAXFD; #ifdef _SC_OPEN_MAX Loading Loading @@ -4206,13 +4240,11 @@ tor_spawn_background(const char *const filename, const char **argv, if (-1 == retval) goto error; child_state = CHILD_STATE_REDIRECT; child_state = CHILD_STATE_DUPIN; /* Link stdin to /dev/null */ fd = open("/dev/null", O_RDONLY); /* NOT cloexec, obviously. */ if (fd != -1) dup2(fd, STDIN_FILENO); else /* Link child stdin to the read end of the pipe */ retval = dup2(stdin_pipe[0], STDIN_FILENO); if (-1 == retval) goto error; child_state = CHILD_STATE_CLOSEFD; Loading @@ -4221,7 +4253,8 @@ tor_spawn_background(const char *const filename, const char **argv, close(stderr_pipe[1]); close(stdout_pipe[0]); close(stdout_pipe[1]); close(fd); close(stdin_pipe[0]); close(stdin_pipe[1]); /* Close all other fds, including the read end of the pipe */ /* XXX: We should now be doing enough FD_CLOEXEC setting to make Loading Loading @@ -4273,6 +4306,8 @@ tor_spawn_background(const char *const filename, const char **argv, if (-1 == pid) { log_warn(LD_GENERAL, "Failed to fork child process: %s", strerror(errno)); close(stdin_pipe[0]); close(stdin_pipe[1]); close(stdout_pipe[0]); close(stdout_pipe[1]); close(stderr_pipe[0]); Loading Loading @@ -4309,16 +4344,28 @@ tor_spawn_background(const char *const filename, const char **argv, strerror(errno)); } /* Return write end of the stdin pipe to caller, and close the read end */ process_handle->stdin_pipe = stdin_pipe[1]; retval = close(stdin_pipe[0]); if (-1 == retval) { log_warn(LD_GENERAL, "Failed to close read end of stdin pipe in parent process: %s", strerror(errno)); } status = process_handle->status = PROCESS_STATUS_RUNNING; /* Set stdout/stderr pipes to be non-blocking */ /* Set stdin/stdout/stderr pipes to be non-blocking */ if (fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK) < 0 || fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK) < 0) { log_warn(LD_GENERAL, "Failed to set stderror/stdout pipes nonblocking " "in parent process: %s", strerror(errno)); fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK) < 0 || fcntl(process_handle->stdin_pipe, F_SETFL, O_NONBLOCK) < 0) { log_warn(LD_GENERAL, "Failed to set stderror/stdout/stdin pipes " "nonblocking in parent process: %s", strerror(errno)); } /* Open the buffered IO streams */ process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r"); process_handle->stderr_handle = fdopen(process_handle->stderr_pipe, "r"); process_handle->stdin_handle = fdopen(process_handle->stdin_pipe, "r"); *process_handle_out = process_handle; return process_handle->status; Loading Loading @@ -4361,6 +4408,9 @@ tor_process_handle_destroy,(process_handle_t *process_handle, if (process_handle->stderr_pipe) CloseHandle(process_handle->stderr_pipe); if (process_handle->stdin_pipe) CloseHandle(process_handle->stdin_pipe); #else if (process_handle->stdout_handle) fclose(process_handle->stdout_handle); Loading @@ -4368,6 +4418,9 @@ tor_process_handle_destroy,(process_handle_t *process_handle, if (process_handle->stderr_handle) fclose(process_handle->stderr_handle); if (process_handle->stdin_handle) fclose(process_handle->stdin_handle); clear_waitpid_callback(process_handle->waitpid_cb); #endif Loading src/common/util.h +3 −0 Original line number Diff line number Diff line Loading @@ -474,12 +474,15 @@ struct process_handle_t { /** One of the PROCESS_STATUS_* values */ int status; #ifdef _WIN32 HANDLE stdin_pipe; HANDLE stdout_pipe; HANDLE stderr_pipe; PROCESS_INFORMATION pid; #else int stdin_pipe; int stdout_pipe; int stderr_pipe; FILE *stdin_handle; FILE *stdout_handle; FILE *stderr_handle; pid_t pid; Loading src/or/transports.c +5 −0 Original line number Diff line number Diff line Loading @@ -1388,6 +1388,11 @@ create_managed_proxy_environment(const managed_proxy_t *mp) } else { smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT="); } /* All new versions of tor will keep stdin open, so PTs can use it * as a reliable termination detection mechanism. */ smartlist_add_asprintf(envs, "TOR_PT_EXIT_ON_STDIN_CLOSE=1"); } else { /* If ClientTransportPlugin has a HTTPS/SOCKS proxy configured, set the * TOR_PT_PROXY line. Loading src/test/test_util_slow.c +2 −0 Original line number Diff line number Diff line Loading @@ -107,9 +107,11 @@ run_util_spawn_background(const char *argv[], const char *expected_out, #ifdef _WIN32 tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE); tt_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE); tt_assert(process_handle->stdin_pipe != INVALID_HANDLE_VALUE); #else tt_assert(process_handle->stdout_pipe >= 0); tt_assert(process_handle->stderr_pipe >= 0); tt_assert(process_handle->stdin_pipe >= 0); #endif /* Check stdout */ Loading Loading
changes/feature15435 0 → 100644 +5 −0 Original line number Diff line number Diff line o Minor features (pluggable Transports): - When launching managed pluggable transports, setup a valid open stdin in the child process that can be used to detect if tor has terminated. The "TOR_PT_EXIT_ON_STDIN_CLOSE" enviornment variable can be used by implementations to detect this new behavior. Resolves ticket 15435.
src/common/util.c +67 −14 Original line number Diff line number Diff line Loading @@ -3942,9 +3942,11 @@ process_handle_new(void) process_handle_t *out = tor_malloc_zero(sizeof(process_handle_t)); #ifdef _WIN32 out->stdin_pipe = INVALID_HANDLE_VALUE; out->stdout_pipe = INVALID_HANDLE_VALUE; out->stderr_pipe = INVALID_HANDLE_VALUE; #else out->stdin_pipe = -1; out->stdout_pipe = -1; out->stderr_pipe = -1; #endif Loading Loading @@ -3984,7 +3986,7 @@ process_handle_waitpid_cb(int status, void *arg) #define CHILD_STATE_FORK 3 #define CHILD_STATE_DUPOUT 4 #define CHILD_STATE_DUPERR 5 #define CHILD_STATE_REDIRECT 6 #define CHILD_STATE_DUPIN 6 #define CHILD_STATE_CLOSEFD 7 #define CHILD_STATE_EXEC 8 #define CHILD_STATE_FAILEXEC 9 Loading Loading @@ -4018,6 +4020,8 @@ tor_spawn_background(const char *const filename, const char **argv, HANDLE stdout_pipe_write = NULL; HANDLE stderr_pipe_read = NULL; HANDLE stderr_pipe_write = NULL; HANDLE stdin_pipe_read = NULL; HANDLE stdin_pipe_write = NULL; process_handle_t *process_handle; int status; Loading Loading @@ -4063,6 +4067,20 @@ tor_spawn_background(const char *const filename, const char **argv, return status; } /* Set up pipe for stdin */ if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, &saAttr, 0)) { log_warn(LD_GENERAL, "Failed to create pipe for stdin communication with child process: %s", format_win32_error(GetLastError())); return status; } if (!SetHandleInformation(stderr_pipe_write, HANDLE_FLAG_INHERIT, 0)) { log_warn(LD_GENERAL, "Failed to configure pipe for stdin communication with child " "process: %s", format_win32_error(GetLastError())); return status; } /* Create the child process */ /* Windows expects argv to be a whitespace delimited string, so join argv up Loading @@ -4077,7 +4095,7 @@ tor_spawn_background(const char *const filename, const char **argv, siStartInfo.cb = sizeof(STARTUPINFO); siStartInfo.hStdError = stderr_pipe_write; siStartInfo.hStdOutput = stdout_pipe_write; siStartInfo.hStdInput = NULL; siStartInfo.hStdInput = stdin_pipe_read; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; /* Create the child process */ Loading Loading @@ -4107,6 +4125,7 @@ tor_spawn_background(const char *const filename, const char **argv, /* 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->stdin_pipe = stdin_pipe_write; status = process_handle->status = PROCESS_STATUS_RUNNING; } Loading @@ -4117,6 +4136,7 @@ tor_spawn_background(const char *const filename, const char **argv, pid_t pid; int stdout_pipe[2]; int stderr_pipe[2]; int stdin_pipe[2]; int fd, retval; ssize_t nbytes; process_handle_t *process_handle; Loading @@ -4141,7 +4161,7 @@ tor_spawn_background(const char *const filename, const char **argv, child_state = CHILD_STATE_PIPE; /* Set up pipe for redirecting stdout and stderr of child */ /* Set up pipe for redirecting stdout, stderr, and stdin of child */ retval = pipe(stdout_pipe); if (-1 == retval) { log_warn(LD_GENERAL, Loading @@ -4162,6 +4182,20 @@ tor_spawn_background(const char *const filename, const char **argv, return status; } retval = pipe(stdin_pipe); if (-1 == retval) { log_warn(LD_GENERAL, "Failed to set up pipe for stdin communication with child process: %s", strerror(errno)); close(stdout_pipe[0]); close(stdout_pipe[1]); close(stderr_pipe[0]); close(stderr_pipe[1]); return status; } child_state = CHILD_STATE_MAXFD; #ifdef _SC_OPEN_MAX Loading Loading @@ -4206,13 +4240,11 @@ tor_spawn_background(const char *const filename, const char **argv, if (-1 == retval) goto error; child_state = CHILD_STATE_REDIRECT; child_state = CHILD_STATE_DUPIN; /* Link stdin to /dev/null */ fd = open("/dev/null", O_RDONLY); /* NOT cloexec, obviously. */ if (fd != -1) dup2(fd, STDIN_FILENO); else /* Link child stdin to the read end of the pipe */ retval = dup2(stdin_pipe[0], STDIN_FILENO); if (-1 == retval) goto error; child_state = CHILD_STATE_CLOSEFD; Loading @@ -4221,7 +4253,8 @@ tor_spawn_background(const char *const filename, const char **argv, close(stderr_pipe[1]); close(stdout_pipe[0]); close(stdout_pipe[1]); close(fd); close(stdin_pipe[0]); close(stdin_pipe[1]); /* Close all other fds, including the read end of the pipe */ /* XXX: We should now be doing enough FD_CLOEXEC setting to make Loading Loading @@ -4273,6 +4306,8 @@ tor_spawn_background(const char *const filename, const char **argv, if (-1 == pid) { log_warn(LD_GENERAL, "Failed to fork child process: %s", strerror(errno)); close(stdin_pipe[0]); close(stdin_pipe[1]); close(stdout_pipe[0]); close(stdout_pipe[1]); close(stderr_pipe[0]); Loading Loading @@ -4309,16 +4344,28 @@ tor_spawn_background(const char *const filename, const char **argv, strerror(errno)); } /* Return write end of the stdin pipe to caller, and close the read end */ process_handle->stdin_pipe = stdin_pipe[1]; retval = close(stdin_pipe[0]); if (-1 == retval) { log_warn(LD_GENERAL, "Failed to close read end of stdin pipe in parent process: %s", strerror(errno)); } status = process_handle->status = PROCESS_STATUS_RUNNING; /* Set stdout/stderr pipes to be non-blocking */ /* Set stdin/stdout/stderr pipes to be non-blocking */ if (fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK) < 0 || fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK) < 0) { log_warn(LD_GENERAL, "Failed to set stderror/stdout pipes nonblocking " "in parent process: %s", strerror(errno)); fcntl(process_handle->stderr_pipe, F_SETFL, O_NONBLOCK) < 0 || fcntl(process_handle->stdin_pipe, F_SETFL, O_NONBLOCK) < 0) { log_warn(LD_GENERAL, "Failed to set stderror/stdout/stdin pipes " "nonblocking in parent process: %s", strerror(errno)); } /* Open the buffered IO streams */ process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r"); process_handle->stderr_handle = fdopen(process_handle->stderr_pipe, "r"); process_handle->stdin_handle = fdopen(process_handle->stdin_pipe, "r"); *process_handle_out = process_handle; return process_handle->status; Loading Loading @@ -4361,6 +4408,9 @@ tor_process_handle_destroy,(process_handle_t *process_handle, if (process_handle->stderr_pipe) CloseHandle(process_handle->stderr_pipe); if (process_handle->stdin_pipe) CloseHandle(process_handle->stdin_pipe); #else if (process_handle->stdout_handle) fclose(process_handle->stdout_handle); Loading @@ -4368,6 +4418,9 @@ tor_process_handle_destroy,(process_handle_t *process_handle, if (process_handle->stderr_handle) fclose(process_handle->stderr_handle); if (process_handle->stdin_handle) fclose(process_handle->stdin_handle); clear_waitpid_callback(process_handle->waitpid_cb); #endif Loading
src/common/util.h +3 −0 Original line number Diff line number Diff line Loading @@ -474,12 +474,15 @@ struct process_handle_t { /** One of the PROCESS_STATUS_* values */ int status; #ifdef _WIN32 HANDLE stdin_pipe; HANDLE stdout_pipe; HANDLE stderr_pipe; PROCESS_INFORMATION pid; #else int stdin_pipe; int stdout_pipe; int stderr_pipe; FILE *stdin_handle; FILE *stdout_handle; FILE *stderr_handle; pid_t pid; Loading
src/or/transports.c +5 −0 Original line number Diff line number Diff line Loading @@ -1388,6 +1388,11 @@ create_managed_proxy_environment(const managed_proxy_t *mp) } else { smartlist_add_asprintf(envs, "TOR_PT_EXTENDED_SERVER_PORT="); } /* All new versions of tor will keep stdin open, so PTs can use it * as a reliable termination detection mechanism. */ smartlist_add_asprintf(envs, "TOR_PT_EXIT_ON_STDIN_CLOSE=1"); } else { /* If ClientTransportPlugin has a HTTPS/SOCKS proxy configured, set the * TOR_PT_PROXY line. Loading
src/test/test_util_slow.c +2 −0 Original line number Diff line number Diff line Loading @@ -107,9 +107,11 @@ run_util_spawn_background(const char *argv[], const char *expected_out, #ifdef _WIN32 tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE); tt_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE); tt_assert(process_handle->stdin_pipe != INVALID_HANDLE_VALUE); #else tt_assert(process_handle->stdout_pipe >= 0); tt_assert(process_handle->stderr_pipe >= 0); tt_assert(process_handle->stdin_pipe >= 0); #endif /* Check stdout */ Loading