diff options
author | Christopher Ferris <cferris@google.com> | 2017-08-22 11:24:09 -0700 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2017-08-22 13:17:28 -0700 |
commit | 92476407115f4431c5888c02cdb5f476b26e393a (patch) | |
tree | d1724f23f16883ab14e7fca02054973635bc6141 /libc/async_safe/async_safe_log.cpp | |
parent | 3ce8834e53304b66e5b0d0d56bc0efea1a172e95 (diff) |
Refactor BufferOutputStream.
- Rewrite BufferOutputStream to handle 0 sized buffers and to get rid
of an unnecessary loop.
- Add tests to verify overflow corner cases.
- Implement async_safe_format_buffer to call async_safe_format_buffer_va_list
instead of duplicate the code.
Test: Ran new unit tests, booted on angler.
Change-Id: I7fb13e209f5b7443d212f55aab4b05ff2e0e8219
Diffstat (limited to 'libc/async_safe/async_safe_log.cpp')
-rw-r--r-- | libc/async_safe/async_safe_log.cpp | 63 |
1 files changed, 27 insertions, 36 deletions
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp index 99ff0c7f9..d81ef34ce 100644 --- a/libc/async_safe/async_safe_log.cpp +++ b/libc/async_safe/async_safe_log.cpp @@ -60,43 +60,36 @@ enum AndroidEventLogType { struct BufferOutputStream { public: - BufferOutputStream(char* buffer, size_t size) : total(0) { - buffer_ = buffer; - end_ = buffer + size - 1; - pos_ = buffer_; - pos_[0] = '\0'; + BufferOutputStream(char* buffer, size_t size) : total(0), pos_(buffer), avail_(size) { + if (avail_ > 0) pos_[0] = '\0'; } - - ~BufferOutputStream() {} + ~BufferOutputStream() = default; void Send(const char* data, int len) { if (len < 0) { len = strlen(data); } - total += len; - while (len > 0) { - int avail = end_ - pos_; - if (avail == 0) { - return; - } - if (avail > len) { - avail = len; - } - memcpy(pos_, data, avail); - pos_ += avail; - pos_[0] = '\0'; - len -= avail; + if (avail_ <= 1) { + // No space to put anything else. + return; } + + if (static_cast<size_t>(len) >= avail_) { + len = avail_ - 1; + } + memcpy(pos_, data, len); + pos_ += len; + pos_[0] = '\0'; + avail_ -= len; } size_t total; private: - char* buffer_; char* pos_; - char* end_; + size_t avail_; }; struct FdOutputStream { @@ -107,16 +100,15 @@ struct FdOutputStream { if (len < 0) { len = strlen(data); } - total += len; while (len > 0) { - int rc = TEMP_FAILURE_RETRY(write(fd_, data, len)); - if (rc == -1) { + ssize_t bytes = TEMP_FAILURE_RETRY(write(fd_, data, len)); + if (bytes == -1) { return; } - data += rc; - len -= rc; + data += bytes; + len -= bytes; } } @@ -409,15 +401,6 @@ static void out_vformat(Out& o, const char* format, va_list args) { } } -int async_safe_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) { - BufferOutputStream os(buffer, buffer_size); - va_list args; - va_start(args, format); - out_vformat(os, format, args); - va_end(args); - return os.total; -} - int async_safe_format_buffer_va_list(char* buffer, size_t buffer_size, const char* format, va_list args) { BufferOutputStream os(buffer, buffer_size); @@ -425,6 +408,14 @@ int async_safe_format_buffer_va_list(char* buffer, size_t buffer_size, const cha return os.total; } +int async_safe_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) { + va_list args; + va_start(args, format); + int buffer_len = async_safe_format_buffer_va_list(buffer, buffer_size, format, args); + va_end(args); + return buffer_len; +} + int async_safe_format_fd(int fd, const char* format, ...) { FdOutputStream os(fd); va_list args; |