summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorSteven Murdoch <Steven.Murdoch@cl.cam.ac.uk>2011-07-21 16:34:48 +0100
committerSteven Murdoch <Steven.Murdoch@cl.cam.ac.uk>2011-07-21 16:34:48 +0100
commit35c89be02b535e2951b695429bd9b255afb2a7b2 (patch)
tree292e9a1ce5d885d4144c90a457e82412676da18e /src/common
parent2002d4acdfac823c03cca3ed92de7f60b3272d86 (diff)
downloadtor-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.c78
-rw-r--r--src/common/util.h23
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);