|
@@ -3942,9 +3942,11 @@ process_handle_new(void)
|
|
process_handle_t *out = tor_malloc_zero(sizeof(process_handle_t));
|
|
process_handle_t *out = tor_malloc_zero(sizeof(process_handle_t));
|
|
|
|
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
|
|
+ out->stdin_pipe = INVALID_HANDLE_VALUE;
|
|
out->stdout_pipe = INVALID_HANDLE_VALUE;
|
|
out->stdout_pipe = INVALID_HANDLE_VALUE;
|
|
out->stderr_pipe = INVALID_HANDLE_VALUE;
|
|
out->stderr_pipe = INVALID_HANDLE_VALUE;
|
|
#else
|
|
#else
|
|
|
|
+ out->stdin_pipe = -1;
|
|
out->stdout_pipe = -1;
|
|
out->stdout_pipe = -1;
|
|
out->stderr_pipe = -1;
|
|
out->stderr_pipe = -1;
|
|
#endif
|
|
#endif
|
|
@@ -3984,7 +3986,7 @@ process_handle_waitpid_cb(int status, void *arg)
|
|
#define CHILD_STATE_FORK 3
|
|
#define CHILD_STATE_FORK 3
|
|
#define CHILD_STATE_DUPOUT 4
|
|
#define CHILD_STATE_DUPOUT 4
|
|
#define CHILD_STATE_DUPERR 5
|
|
#define CHILD_STATE_DUPERR 5
|
|
-#define CHILD_STATE_REDIRECT 6
|
|
+#define CHILD_STATE_DUPIN 6
|
|
#define CHILD_STATE_CLOSEFD 7
|
|
#define CHILD_STATE_CLOSEFD 7
|
|
#define CHILD_STATE_EXEC 8
|
|
#define CHILD_STATE_EXEC 8
|
|
#define CHILD_STATE_FAILEXEC 9
|
|
#define CHILD_STATE_FAILEXEC 9
|
|
@@ -4018,6 +4020,8 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
HANDLE stdout_pipe_write = NULL;
|
|
HANDLE stdout_pipe_write = NULL;
|
|
HANDLE stderr_pipe_read = NULL;
|
|
HANDLE stderr_pipe_read = NULL;
|
|
HANDLE stderr_pipe_write = NULL;
|
|
HANDLE stderr_pipe_write = NULL;
|
|
|
|
+ HANDLE stdin_pipe_read = NULL;
|
|
|
|
+ HANDLE stdin_pipe_write = NULL;
|
|
process_handle_t *process_handle;
|
|
process_handle_t *process_handle;
|
|
int status;
|
|
int status;
|
|
|
|
|
|
@@ -4063,6 +4067,20 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -4077,7 +4095,7 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
siStartInfo.cb = sizeof(STARTUPINFO);
|
|
siStartInfo.cb = sizeof(STARTUPINFO);
|
|
siStartInfo.hStdError = stderr_pipe_write;
|
|
siStartInfo.hStdError = stderr_pipe_write;
|
|
siStartInfo.hStdOutput = stdout_pipe_write;
|
|
siStartInfo.hStdOutput = stdout_pipe_write;
|
|
- siStartInfo.hStdInput = NULL;
|
|
+ siStartInfo.hStdInput = stdin_pipe_read;
|
|
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
|
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
|
|
|
|
|
|
|
|
|
@@ -4107,6 +4125,7 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
|
|
|
|
process_handle->stdout_pipe = stdout_pipe_read;
|
|
process_handle->stdout_pipe = stdout_pipe_read;
|
|
process_handle->stderr_pipe = stderr_pipe_read;
|
|
process_handle->stderr_pipe = stderr_pipe_read;
|
|
|
|
+ process_handle->stdin_pipe = stdin_pipe_write;
|
|
status = process_handle->status = PROCESS_STATUS_RUNNING;
|
|
status = process_handle->status = PROCESS_STATUS_RUNNING;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4117,6 +4136,7 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
pid_t pid;
|
|
pid_t pid;
|
|
int stdout_pipe[2];
|
|
int stdout_pipe[2];
|
|
int stderr_pipe[2];
|
|
int stderr_pipe[2];
|
|
|
|
+ int stdin_pipe[2];
|
|
int fd, retval;
|
|
int fd, retval;
|
|
ssize_t nbytes;
|
|
ssize_t nbytes;
|
|
process_handle_t *process_handle;
|
|
process_handle_t *process_handle;
|
|
@@ -4141,7 +4161,7 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
|
|
|
|
child_state = CHILD_STATE_PIPE;
|
|
child_state = CHILD_STATE_PIPE;
|
|
|
|
|
|
-
|
|
+
|
|
retval = pipe(stdout_pipe);
|
|
retval = pipe(stdout_pipe);
|
|
if (-1 == retval) {
|
|
if (-1 == retval) {
|
|
log_warn(LD_GENERAL,
|
|
log_warn(LD_GENERAL,
|
|
@@ -4162,6 +4182,20 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
return status;
|
|
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;
|
|
child_state = CHILD_STATE_MAXFD;
|
|
|
|
|
|
#ifdef _SC_OPEN_MAX
|
|
#ifdef _SC_OPEN_MAX
|
|
@@ -4206,13 +4240,11 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
if (-1 == retval)
|
|
if (-1 == retval)
|
|
goto error;
|
|
goto error;
|
|
|
|
|
|
- child_state = CHILD_STATE_REDIRECT;
|
|
+ child_state = CHILD_STATE_DUPIN;
|
|
|
|
|
|
-
|
|
+
|
|
- fd = open("/dev/null", O_RDONLY);
|
|
+ retval = dup2(stdin_pipe[0], STDIN_FILENO);
|
|
- if (fd != -1)
|
|
+ if (-1 == retval)
|
|
- dup2(fd, STDIN_FILENO);
|
|
|
|
- else
|
|
|
|
goto error;
|
|
goto error;
|
|
|
|
|
|
child_state = CHILD_STATE_CLOSEFD;
|
|
child_state = CHILD_STATE_CLOSEFD;
|
|
@@ -4221,7 +4253,8 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
close(stderr_pipe[1]);
|
|
close(stderr_pipe[1]);
|
|
close(stdout_pipe[0]);
|
|
close(stdout_pipe[0]);
|
|
close(stdout_pipe[1]);
|
|
close(stdout_pipe[1]);
|
|
- close(fd);
|
|
+ close(stdin_pipe[0]);
|
|
|
|
+ close(stdin_pipe[1]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -4273,6 +4306,8 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
|
|
|
|
if (-1 == pid) {
|
|
if (-1 == pid) {
|
|
log_warn(LD_GENERAL, "Failed to fork child process: %s", strerror(errno));
|
|
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[0]);
|
|
close(stdout_pipe[1]);
|
|
close(stdout_pipe[1]);
|
|
close(stderr_pipe[0]);
|
|
close(stderr_pipe[0]);
|
|
@@ -4309,16 +4344,28 @@ tor_spawn_background(const char *const filename, const char **argv,
|
|
strerror(errno));
|
|
strerror(errno));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ 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;
|
|
status = process_handle->status = PROCESS_STATUS_RUNNING;
|
|
-
|
|
+
|
|
if (fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK) < 0 ||
|
|
if (fcntl(process_handle->stdout_pipe, F_SETFL, O_NONBLOCK) < 0 ||
|
|
- fcntl(process_handle->stderr_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 "
|
|
+ fcntl(process_handle->stdin_pipe, F_SETFL, O_NONBLOCK) < 0) {
|
|
- "in parent process: %s", strerror(errno));
|
|
+ log_warn(LD_GENERAL, "Failed to set stderror/stdout/stdin pipes "
|
|
|
|
+ "nonblocking in parent process: %s", strerror(errno));
|
|
}
|
|
}
|
|
|
|
|
|
process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r");
|
|
process_handle->stdout_handle = fdopen(process_handle->stdout_pipe, "r");
|
|
process_handle->stderr_handle = fdopen(process_handle->stderr_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;
|
|
*process_handle_out = process_handle;
|
|
return process_handle->status;
|
|
return process_handle->status;
|
|
@@ -4361,6 +4408,9 @@ tor_process_handle_destroy,(process_handle_t *process_handle,
|
|
|
|
|
|
if (process_handle->stderr_pipe)
|
|
if (process_handle->stderr_pipe)
|
|
CloseHandle(process_handle->stderr_pipe);
|
|
CloseHandle(process_handle->stderr_pipe);
|
|
|
|
+
|
|
|
|
+ if (process_handle->stdin_pipe)
|
|
|
|
+ CloseHandle(process_handle->stdin_pipe);
|
|
#else
|
|
#else
|
|
if (process_handle->stdout_handle)
|
|
if (process_handle->stdout_handle)
|
|
fclose(process_handle->stdout_handle);
|
|
fclose(process_handle->stdout_handle);
|
|
@@ -4368,6 +4418,9 @@ tor_process_handle_destroy,(process_handle_t *process_handle,
|
|
if (process_handle->stderr_handle)
|
|
if (process_handle->stderr_handle)
|
|
fclose(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);
|
|
clear_waitpid_callback(process_handle->waitpid_cb);
|
|
#endif
|
|
#endif
|
|
|
|
|