diff options
author | George Kadianakis <desnacked@riseup.net> | 2012-06-07 19:07:13 +0300 |
---|---|---|
committer | George Kadianakis <desnacked@riseup.net> | 2012-09-05 18:02:27 +0300 |
commit | 03e89f0b72ede5ec37c76de840f04579b8d118c3 (patch) | |
tree | c4235543aae4034af4a0706d5fa45e95c5943970 | |
parent | e8be040016a279d5cbef38fa5328cc2eb0de2c46 (diff) | |
download | tor-03e89f0b72ede5ec37c76de840f04579b8d118c3.tar tor-03e89f0b72ede5ec37c76de840f04579b8d118c3.tar.gz |
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.
-rw-r--r-- | src/common/util.c | 71 | ||||
-rw-r--r-- | 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 ce6725285..6e23c962d 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 c059730db..69335eddb 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); |