Chromium Code Reviews| Index: runtime/bin/process.h |
| diff --git a/runtime/bin/process.h b/runtime/bin/process.h |
| index 8e82f394aa7d8eac25b69d262f1cb36937508708..ccc80c89574e1d00dd054e6bc4a367cc7a199491 100644 |
| --- a/runtime/bin/process.h |
| +++ b/runtime/bin/process.h |
| @@ -6,13 +6,41 @@ |
| #define BIN_PROCESS_H_ |
| #include "bin/builtin.h" |
| +#include "bin/io_buffer.h" |
| #include "bin/thread.h" |
| #include "platform/globals.h" |
| +#include "platform/utils.h" |
| namespace dart { |
| namespace bin { |
| +class ProcessResult { |
| + public: |
| + ProcessResult() : exit_code_(0) {} |
| + |
| + void set_stdout_data(Dart_Handle stdout_data) { |
| + stdout_data_ = stdout_data; |
| + } |
| + void set_stderr_data(Dart_Handle stderr_data) { |
| + stderr_data_ = stderr_data; |
| + } |
| + |
| + void set_exit_code(intptr_t exit_code) { exit_code_ = exit_code; } |
| + |
| + Dart_Handle stdout_data() { return stdout_data_; } |
| + Dart_Handle stderr_data() { return stderr_data_; } |
| + intptr_t exit_code() { return exit_code_; } |
| + |
| + private: |
| + Dart_Handle stdout_data_; |
| + Dart_Handle stderr_data_; |
| + intptr_t exit_code_; |
| + |
| + DISALLOW_ALLOCATION(); |
| +}; |
| + |
| + |
| class Process { |
| public: |
| // Start a new process providing access to stdin, stdout, stderr and |
| @@ -30,6 +58,13 @@ class Process { |
| intptr_t* exit_handler, |
| char** os_error_message); |
| + static bool Wait(intptr_t id, |
| + intptr_t in, |
| + intptr_t out, |
| + intptr_t err, |
| + intptr_t exit_handler, |
| + ProcessResult* result); |
| + |
| // Kill a process with a given pid. |
| static bool Kill(intptr_t id, int signal); |
| @@ -62,6 +97,101 @@ class Process { |
| DISALLOW_IMPLICIT_CONSTRUCTORS(Process); |
| }; |
| + |
| +// Utility class for collecting the output when running a process |
| +// synchronously by using Process::Wait. This class is sub-classed in |
| +// the platform specific files to implement reading into the buffers |
| +// allocated. |
| +class BufferListBase { |
| + protected: |
| + static const intptr_t kBufferSize = 16 * 1024; |
| + |
| + class BufferListNode { |
| + public: |
| + explicit BufferListNode(intptr_t size) { |
| + data_ = new uint8_t[size]; |
| + if (data_ == NULL) FATAL("Allocation failed"); |
| + next_ = NULL; |
| + } |
| + |
| + ~BufferListNode() { |
| + delete[] data_; |
| + } |
| + |
| + uint8_t* data_; |
| + BufferListNode* next_; |
| + |
| + private: |
| + DISALLOW_IMPLICIT_CONSTRUCTORS(BufferListNode); |
| + }; |
| + |
| + public: |
| + BufferListBase() : head_(NULL), tail_(NULL), data_size_(0), free_size_(0) {} |
| + ~BufferListBase() { |
| + ASSERT(head_ == NULL); |
| + ASSERT(tail_ == NULL); |
| + } |
| + |
| + // Returns the collected data as a Uint8List. If an error occours an |
| + // error handle is returned. |
| + Dart_Handle GetData() { |
| + uint8_t* buffer; |
| + intptr_t buffer_position = 0; |
| + Dart_Handle result = IOBuffer::Allocate(data_size_, &buffer); |
| + if (Dart_IsError(result)) { |
| + Free(); |
| + return result; |
| + } |
| + for (BufferListNode* current = head_; |
| + current != NULL; |
| + current = current->next_) { |
| + intptr_t to_copy = dart::Utils::Minimum(data_size_, kBufferSize); |
| + memmove(buffer + buffer_position, current->data_, to_copy); |
| + buffer_position += to_copy; |
| + data_size_ -= to_copy; |
| + } |
| + ASSERT(data_size_ == 0); |
| + Free(); |
| + return result; |
| + } |
| + |
| + protected: |
| + void Allocate() { |
| + ASSERT(free_size_ == 0); |
| + BufferListNode* node = new BufferListNode(kBufferSize); |
| + if (head_ == NULL) { |
| + head_ = node; |
| + tail_ = node; |
| + } else { |
| + ASSERT(tail_->next_ == NULL); |
| + tail_->next_ = node; |
| + tail_ = node; |
| + } |
| + free_size_ = kBufferSize; |
| + } |
| + |
| + void Free() { |
| + for (BufferListNode* current = head_; |
| + current != NULL; |
| + current = current->next_) { |
| + } |
|
Bill Hesse
2013/08/13 08:34:48
Something seems missing in this for loop.
Søren Gjesse
2013/08/13 13:00:43
Added
delete current;
|
| + head_ = NULL; |
| + tail_ = NULL; |
| + data_size_ = 0; |
| + free_size_ = 0; |
| + } |
| + |
| + // Linked list for data collected. |
| + BufferListNode* head_; |
| + BufferListNode* tail_; |
| + |
| + // Number of bytes of data collected in the linked list. |
| + intptr_t data_size_; |
| + |
| + // Number of free bytes in the last node in the list. |
| + intptr_t free_size_; |
| +}; |
| + |
| } // namespace bin |
| } // namespace dart |