aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/util.c95
-rw-r--r--src/common/util.h20
2 files changed, 89 insertions, 26 deletions
diff --git a/src/common/util.c b/src/common/util.c
index c44a4aa3b..b6b3c7aa8 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -3159,25 +3159,41 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
/* Maximum number of file descriptors, if we cannot get it via sysconf() */
#define DEFAULT_MAX_FD 256
-/** Terminate process running at PID <b>pid</b>.
+/** Terminate the process of <b>process_handle</b>.
* Code borrowed from Python's os.kill. */
int
-tor_terminate_process(pid_t pid)
+tor_terminate_process(process_handle_t *process_handle)
{
#ifdef MS_WINDOWS
- HANDLE handle;
- /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
- attempt to open and terminate the process. */
- handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
- if (!handle)
- return -1;
+ 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. */
+ handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE,
+ process_handle->pid.dwProcessId);
+ if (!handle)
+ return -1;
- if (!TerminateProcess(handle, 0))
- return -1;
- else
- return 0;
+ if (!TerminateProcess(handle, 0))
+ return -1;
+ else
+ return 0;
+ }
#else /* Unix */
- return kill(pid, SIGTERM);
+ return kill(process_handle->pid, SIGTERM);
+#endif
+
+ return -1;
+}
+
+/** Return the Process ID of <b>process_handle</b>. */
+int
+tor_process_get_pid(process_handle_t *process_handle)
+{
+#ifdef MS_WINDOWS
+ return (int) process_handle->pid.dwProcessId;
+#else
+ return (int) process_handle->pid;
#endif
}
@@ -3213,7 +3229,11 @@ tor_terminate_process(pid_t pid)
*/
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)
{
#ifdef MS_WINDOWS
@@ -3295,7 +3315,7 @@ tor_spawn_background(const char *const filename, const char **argv,
/*(TODO: set CREATE_NEW CONSOLE/PROCESS_GROUP to make GetExitCodeProcess()
* work?) */
0, // creation flags
- NULL, // use parent's environment
+ envp, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&(process_handle->pid)); // receives PROCESS_INFORMATION
@@ -3497,6 +3517,43 @@ tor_spawn_background(const char *const filename, const char **argv,
#endif // MS_WINDOWS
}
+/** Destroy all resources allocated by the process handle in
+ * <b>process_handle</b>.
+ * If <b>also_terminate_process</b> is true, also terminate the
+ * process of the process handle. */
+void
+tor_process_handle_destroy(process_handle_t *process_handle,
+ int also_terminate_process)
+{
+ if (also_terminate_process) {
+ if (tor_terminate_process(process_handle) < 0) {
+ log_notice(LD_GENERAL, "Failed to terminate process with PID '%d'",
+ tor_process_get_pid(process_handle));
+ } else {
+ log_info(LD_GENERAL, "Terminated process with PID '%d'",
+ tor_process_get_pid(process_handle));
+ }
+ }
+
+ process_handle->status = PROCESS_STATUS_NOTRUNNING;
+
+#ifdef MS_WINDOWS
+ if (process_handle->stdout_pipe)
+ CloseHandle(process_handle->stdout_pipe);
+
+ if (process_handle->stderr_pipe)
+ CloseHandle(process_handle->stderr_pipe);
+#else
+ if (process_handle->stdout_handle)
+ fclose(process_handle->stdout_handle);
+
+ if (process_handle->stderr_handle)
+ fclose(process_handle->stderr_handle);
+#endif
+
+ tor_free(process_handle);
+}
+
/** Get the exit code of a process specified by <b>process_handle</b> and store
* it in <b>exit_code</b>, if set to a non-NULL value. If <b>block</b> is set
* to true, the call will block until the process has exited. Otherwise if
@@ -3991,14 +4048,10 @@ tor_check_port_forwarding(const char *filename, int dir_port, int or_port,
time_to_run_helper = now + TIME_TO_EXEC_FWHELPER_FAIL;
return;
}
-#ifdef MS_WINDOWS
- log_info(LD_GENERAL,
- "Started port forwarding helper (%s)", filename);
-#else
+
log_info(LD_GENERAL,
- "Started port forwarding helper (%s) with pid %d", filename,
- child_handle.pid);
-#endif
+ "Started port forwarding helper (%s) with pid '%d'",
+ filename, tor_process_get_pid(&child_handle));
}
/* If child is running, read from its stdout and stderr) */
diff --git a/src/common/util.h b/src/common/util.h
index b8725740c..a9002254e 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -356,10 +356,14 @@ void write_pidfile(char *filename);
void tor_check_port_forwarding(const char *filename,
int dir_port, int or_port, time_t now);
-int tor_terminate_process(pid_t pid);
typedef struct process_handle_s process_handle_t;
int tor_spawn_background(const char *const filename, const char **argv,
- const char **envp, process_handle_t *process_handle);
+#ifdef MS_WINDOWS
+ LPVOID envp,
+#else
+ const char **envp,
+#endif
+ process_handle_t *process_handle);
#define SPAWN_ERROR_MESSAGE "ERR: Failed to spawn background process - code "
@@ -367,9 +371,6 @@ int tor_spawn_background(const char *const filename, const char **argv,
HANDLE load_windows_system_library(const TCHAR *library_name);
#endif
-#ifdef UTIL_PRIVATE
-/* Prototypes for private functions only used by util.c (and unit tests) */
-
/* Values of process_handle_t.status. PROCESS_STATUS_NOTRUNNING must be
* 0 because tor_check_port_forwarding depends on this being the initial
* statue of the static instance of process_handle_t */
@@ -412,6 +413,15 @@ 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[]);
+int tor_process_get_pid(process_handle_t *process_handle);
+
+int tor_terminate_process(process_handle_t *process_handle);
+void tor_process_handle_destroy(process_handle_t *process_handle,
+ int also_terminate_process);
+
+#ifdef UTIL_PRIVATE
+/* Prototypes for private functions only used by util.c (and unit tests) */
+
void format_helper_exit_status(unsigned char child_state,
int saved_errno, char *hex_errno);