[tor-commits] [tor/master] Make some utility functions.

nickm at torproject.org nickm at torproject.org
Fri Oct 7 20:03:16 UTC 2011


commit 810a7a5fa0973451881a874a08594937a8274429
Author: George Kadianakis <desnacked at gmail.com>
Date:   Wed Jul 13 18:59:52 2011 +0200

    Make some utility functions.
    
    * Create a function that will get input from a stream, so that we can
      communicate with the managed proxy.
    * Hackish change to tor_spawn_background() so that we can specify an
      environ for our spawn.
---
 src/common/util.c    |   60 +++++++++++++++++++++++++++++++++++++++++++++++--
 src/common/util.h    |   16 +++++++++++-
 src/test/test_util.c |    3 +-
 3 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/src/common/util.c b/src/common/util.c
index a5a6ea3..5f4472b 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2958,7 +2958,7 @@ format_helper_exit_status(unsigned char child_state, int saved_errno,
  */
 int
 tor_spawn_background(const char *const filename, int *stdout_read,
-                     int *stderr_read, const char **argv)
+                     int *stderr_read, const char **argv, const char **envp)
 {
 #ifdef MS_WINDOWS
   (void) filename; (void) stdout_read; (void) stderr_read; (void) argv;
@@ -3068,7 +3068,10 @@ tor_spawn_background(const char *const filename, int *stdout_read,
     /* Call the requested program. We need the cast because
        execvp doesn't define argv as const, even though it
        does not modify the arguments */
-    execvp(filename, (char *const *) argv);
+    if (envp)
+      execve(filename, (char *const *) argv, (char*const*)envp);
+    else
+      execvp(filename, (char *const *) argv);
 
     /* If we got here, the exec or open(/dev/null) failed */
 
@@ -3128,6 +3131,57 @@ tor_spawn_background(const char *const filename, int *stdout_read,
 #endif
 }
 
+/** Reads from <b>stream</b> and stores input in <b>buf_out</b> making
+ *  sure it's below <b>count</b> bytes.
+ *  If the string has a trailing newline, we strip it off.
+ *
+ * This function is specifically created to handle input from managed
+ * proxies, according to the pluggable transports spec. Make sure it
+ * fits your needs before using it.
+ *
+ * Returns:
+ * ST_CLOSED: If the stream is closed.
+ * ST_EAGAIN: If there is nothing to read and we should check back later.
+ * ST_TERM: If something is wrong with the stream.
+ * ST_OKAY: If everything went okay and we got a string in <b>buf_out</b>. */
+enum stream_status
+get_string_from_pipe(FILE *stream, char *buf_out, size_t count)
+{
+  char *retval;
+  size_t len;
+
+  retval = fgets(buf_out, count, stream);
+
+  if (!retval) {
+    if (feof(stream)) {
+      /* Program has closed stream (probably it exited) */
+      /* TODO: check error */
+      return ST_CLOSED;
+    } else {
+      if (EAGAIN == errno) {
+        /* Nothing more to read, try again next time */
+        return ST_EAGAIN;
+      } else {
+        /* There was a problem, abandon this child process */
+        return ST_TERM;
+      }
+    }
+  } else {
+    len = strlen(buf_out);
+    tor_assert(len>0);
+
+    if (buf_out[len - 1] == '\n') {
+      /* Remove the trailing newline */
+      buf_out[len - 1] = '\0';
+    }
+
+    return ST_OKAY;
+  }
+
+  /* We should never get here */
+  return ST_TERM;
+}
+
 /** Read from stream, and send lines to log at the specified log level.
  * Returns 1 if stream is closed normally, -1 if there is a error reading, and
  * 0 otherwise. Handles lines from tor-fw-helper and
@@ -3254,7 +3308,7 @@ tor_check_port_forwarding(const char *filename, int dir_port, int or_port,
     /* Assume tor-fw-helper will succeed, start it later*/
     time_to_run_helper = now + TIME_TO_EXEC_FWHELPER_SUCCESS;
 
-    child_pid = tor_spawn_background(filename, &fd_out, &fd_err, argv);
+    child_pid = tor_spawn_background(filename, &fd_out, &fd_err, argv, NULL);
     if (child_pid < 0) {
       log_warn(LD_GENERAL, "Failed to start port forwarding helper %s",
               filename);
diff --git a/src/common/util.h b/src/common/util.h
index 2974ab7..1b81fa3 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -279,6 +279,16 @@ char *rate_limit_log(ratelim_t *lim, time_t now);
 ssize_t write_all(tor_socket_t fd, const char *buf, size_t count,int isSocket);
 ssize_t read_all(tor_socket_t fd, char *buf, size_t count, int isSocket);
 
+/** Status of an I/O stream. */
+enum stream_status {
+  ST_OKAY,
+  ST_EAGAIN,
+  ST_TERM,
+  ST_CLOSED
+};
+
+enum stream_status get_string_from_pipe(FILE *stream, char *buf, size_t count);
+
 /** Return values from file_status(); see that function's documentation
  * for details. */
 typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR } file_status_t;
@@ -340,14 +350,16 @@ void write_pidfile(char *filename);
 void tor_check_port_forwarding(const char *filename,
                                int dir_port, int or_port, time_t now);
 
+int tor_spawn_background(const char *const filename, int *stdout_read,
+                         int *stderr_read, const char **argv,
+                         const char **envp);
+
 #ifdef MS_WINDOWS
 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) */
-int tor_spawn_background(const char *const filename, int *stdout_read,
-                         int *stderr_read, const char **argv);
 void format_helper_exit_status(unsigned char child_state,
                                int saved_errno, char *hex_errno);
 
diff --git a/src/test/test_util.c b/src/test/test_util.c
index c4769e6..c778faa 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1389,7 +1389,8 @@ run_util_spawn_background(const char *argv[], const char *expected_out,
   char stdout_buf[100], stderr_buf[100];
 
   /* Start the program */
-  retval = tor_spawn_background(argv[0], &stdout_pipe, &stderr_pipe, argv);
+  retval = tor_spawn_background(argv[0], &stdout_pipe, &stderr_pipe,
+                                argv, NULL);
   tt_int_op(retval, >, 0);
   tt_int_op(stdout_pipe, >, 0);
   tt_int_op(stderr_pipe, >, 0);





More information about the tor-commits mailing list