[tor-commits] [tor/master] Introduce get_lines_from_handle().

nickm at torproject.org nickm at torproject.org
Thu Sep 6 14:14:30 UTC 2012


commit 03e89f0b72ede5ec37c76de840f04579b8d118c3
Author: George Kadianakis <desnacked at riseup.net>
Date:   Thu Jun 7 19:07:13 2012 +0300

    Introduce get_lines_from_handle().
    
    get_lines_from_handle() is a multiplatform function which drains lines
    from a stream and stuffs it into a smartlist. It's useful for
    line-based protocols, like the one managed proxy and the tor-fw-helper
    protocols.
---
 src/common/util.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/common/util.h |   10 +++++++
 2 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/src/common/util.c b/src/common/util.c
index ce67252..6e23c96 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -4369,6 +4369,50 @@ tor_split_lines(smartlist_t *sl, char *buf, int len)
 }
 
 #ifdef _WIN32
+
+/** Return a smartlist containing lines outputted from
+ *  <b>handle</b>. Return NULL on error, and set
+ *  <b>stream_status_out</b> appropriately. */
+smartlist_t *
+tor_get_lines_from_handle(HANDLE *handle,
+                          enum stream_status *stream_status_out)
+{
+  int pos;
+  char stdout_buf[600] = {0};
+  smartlist_t *lines = NULL;
+
+  tor_assert(stream_status);
+
+  *stream_status = IO_STREAM_TERM;
+
+  pos = tor_read_all_handle(handle, stdout_buf, sizeof(stdout_buf) - 1, NULL);
+  if (pos < 0) {
+    *stream_status = IO_STREAM_TERM;
+    return NULL;
+  }
+  if (pos == 0) {
+    *stream_status = IO_STREAM_EAGAIN;
+    return NULL;
+  }
+
+  /* End with a null even if there isn't a \r\n at the end */
+  /* TODO: What if this is a partial line? */
+  stdout_buf[pos] = '\0';
+
+  /* Split up the buffer */
+  lines = smartlist_new();
+  tor_split_lines(lines, stdout_buf, pos);
+
+  /* Currently 'lines' is populated with strings residing on the
+     stack. Replace them with their exact copies on the heap: */
+  SMARTLIST_FOREACH(lines, char *, line,
+                    SMARTLIST_REPLACE_CURRENT(lines, line, tor_strdup(line)));
+
+  *stream_status = IO_STREAM_OKAY;
+
+  return lines;
+}
+
 /** Read from stream, and send lines to log at the specified log level.
  * Returns -1 if there is a error reading, and 0 otherwise.
  * If the generated stream is flushed more often than on new lines, or
@@ -4416,6 +4460,33 @@ log_from_handle(HANDLE *pipe, int severity)
 
 #else
 
+/** Return a smartlist containing lines outputted from
+ *  <b>handle</b>. Return NULL on error, and set <b>stream_status</b>
+ *  appropriately. */
+smartlist_t *
+tor_get_lines_from_handle(FILE *handle, enum stream_status *stream_status_out)
+{
+  enum stream_status stream_status;
+  char stdout_buf[400];
+  smartlist_t *lines = NULL;
+
+  while (1) {
+    memset(stdout_buf, 0, sizeof(stdout_buf));
+
+    stream_status = get_string_from_pipe(handle,
+                                         stdout_buf, sizeof(stdout_buf) - 1);
+    if (stream_status != IO_STREAM_OKAY)
+      goto done;
+
+    if (!lines) lines = smartlist_new();
+    smartlist_add(lines, tor_strdup(stdout_buf));
+  }
+
+ done:
+  *stream_status_out = stream_status;
+  return lines;
+}
+
 /** 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
diff --git a/src/common/util.h b/src/common/util.h
index c059730..69335ed 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -464,6 +464,16 @@ HANDLE tor_process_get_stdout_pipe(process_handle_t *process_handle);
 FILE *tor_process_get_stdout_pipe(process_handle_t *process_handle);
 #endif
 
+#ifdef _WIN32
+struct smartlist_t *
+tor_get_lines_from_handle(HANDLE *handle,
+                          enum stream_status *stream_status);
+#else
+struct smartlist_t *
+tor_get_lines_from_handle(FILE *handle,
+                          enum stream_status *stream_status);
+#endif
+
 int tor_terminate_process(process_handle_t *process_handle);
 void tor_process_handle_destroy(process_handle_t *process_handle,
                                 int also_terminate_process);





More information about the tor-commits mailing list