diff options
author | Steven Murdoch <Steven.Murdoch@cl.cam.ac.uk> | 2011-07-21 16:34:48 +0100 |
---|---|---|
committer | Steven Murdoch <Steven.Murdoch@cl.cam.ac.uk> | 2011-07-21 16:34:48 +0100 |
commit | 35c89be02b535e2951b695429bd9b255afb2a7b2 (patch) | |
tree | 292e9a1ce5d885d4144c90a457e82412676da18e /src/common | |
parent | 2002d4acdfac823c03cca3ed92de7f60b3272d86 (diff) | |
download | tor-35c89be02b535e2951b695429bd9b255afb2a7b2.tar.gz tor-35c89be02b535e2951b695429bd9b255afb2a7b2.zip |
Generalize process spawning so its test compiles (but fails) in Windows
- pid, stdout/stderr_pipe now encapsulated in process_handle
- read_all replaced by tor_read_all_from_process_stdin/stderr
- waitpid replaced by tor_get_exit_code
Untested on *nix
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/util.c | 78 | ||||
-rw-r--r-- | src/common/util.h | 23 |
2 files changed, 87 insertions, 14 deletions
diff --git a/src/common/util.c b/src/common/util.c index b95ee3a612..5bc7a8017b 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -2978,14 +2978,15 @@ format_helper_exit_status(unsigned char child_state, int saved_errno, * -1. Some parts of this code are based on the POSIX subprocess module from * Python. */ -int -tor_spawn_background(const char *const filename, int *stdout_read, - int *stderr_read, const char **argv) +process_handle_t +tor_spawn_background(const char *const filename, const char **argv) { + process_handle_t process_handle; #ifdef MS_WINDOWS - (void) filename; (void) stdout_read; (void) stderr_read; (void) argv; + (void) filename; (void) argv; log_warn(LD_BUG, "not yet implemented on Windows."); - return -1; + process_handle.status = -1; + return process_handle; #else pid_t pid; int stdout_pipe[2]; @@ -3016,7 +3017,8 @@ tor_spawn_background(const char *const filename, int *stdout_read, log_warn(LD_GENERAL, "Failed to set up pipe for stdout communication with child process: %s", strerror(errno)); - return -1; + process_handle.status = -1; + return process_handle; } retval = pipe(stderr_pipe); @@ -3024,7 +3026,8 @@ tor_spawn_background(const char *const filename, int *stdout_read, log_warn(LD_GENERAL, "Failed to set up pipe for stderr communication with child process: %s", strerror(errno)); - return -1; + process_handle.status = -1; + return process_handle; } child_state = CHILD_STATE_MAXFD; @@ -3109,7 +3112,8 @@ tor_spawn_background(const char *const filename, int *stdout_read, (void) nbytes; _exit(255); - return -1; /* Never reached, but avoids compiler warning */ + process_handle.status = -1; + return process_handle; /* Never reached, but avoids compiler warning */ } /* In parent */ @@ -3120,11 +3124,12 @@ tor_spawn_background(const char *const filename, int *stdout_read, close(stdout_pipe[1]); close(stderr_pipe[0]); close(stderr_pipe[1]); - return -1; + process_handle.status = -1; + return process_handle; } /* Return read end of the pipes to caller, and close write end */ - *stdout_read = stdout_pipe[0]; + process_handle.stdout_pipe = stdout_pipe[0]; retval = close(stdout_pipe[1]); if (-1 == retval) { @@ -3135,7 +3140,7 @@ tor_spawn_background(const char *const filename, int *stdout_read, needs to know about the pid in order to reap it later */ } - *stderr_read = stderr_pipe[0]; + process_handle.stderr_pipe = stderr_pipe[0]; retval = close(stderr_pipe[1]); if (-1 == retval) { @@ -3146,7 +3151,56 @@ tor_spawn_background(const char *const filename, int *stdout_read, needs to know about the pid in order to reap it later */ } - return pid; + process_handle.status = 0; + process_handle.pid = pid; + return process_handle; +#endif +} + +int +tor_get_exit_code(const process_handle_t process_handle) +{ +#ifdef MS_WINDOWS + log_warn(LD_BUG, "not yet implemented on Windows."); + return -1; +#else + int stat_loc; + + retval = waitpid(process_handle.pid, &stat_loc, 0); + if (retval != process_handle.pid) { + log_warn(LD_GENERAL, "waitpid() failed for PID %d: %s", process_handle.pid, + sterror(errno)); + return -1; + } + + if (!WIFEXITED(stat_loc)) { + log_warn(LD_GENERAL, "Process %d did not exit normally", process_handle.pid); + return -1; + } + + return WEXITSTATUS(stat_loc); +#endif // MS_WINDOWS +} + +ssize_t +tor_read_all_from_process_stdin(const process_handle_t process_handle, + char *buf, size_t count) +{ +#ifdef MS_WINDOWS + return -1; +#else + return read_all(process_handle.stdin_pipe, buf, count, 0); +#endif +} + +ssize_t +tor_read_all_from_process_stderr(const process_handle_t process_handle, + char *buf, size_t count) +{ +#ifdef MS_WINDOWS + return -1; +#else + return read_all(process_handle.stderr_pipe, buf, count, 0); #endif } diff --git a/src/common/util.h b/src/common/util.h index 6496c42db8..2cf57a125d 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -347,8 +347,27 @@ HANDLE load_windows_system_library(const TCHAR *library_name); #ifdef UTIL_PRIVATE /* Prototypes for private functions only used by util.c (and unit tests) */ -int tor_spawn_background(const char *const filename, int *stdout_read, - int *stderr_read, const char **argv); + +typedef struct process_handle_s { + int status; +#ifdef MS_WINDOWS + HANDLE stdout_pipe; + HANDLE stderr_pipe; + HANDLE pid; +#else + int stdout_pipe; + int stderr_pipe; + int pid; +#endif // MS_WINDOWS +} process_handle_t; + +process_handle_t tor_spawn_background(const char *const filename, + const char **argv); +int tor_get_exit_code(const process_handle_t pid); +ssize_t tor_read_all_from_process_stdin(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); void format_helper_exit_status(unsigned char child_state, int saved_errno, char *hex_errno); |