1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Common helper functions/classes used both in the host and device forwarder. 6 7#ifndef TOOLS_ANDROID_FORWARDER2_COMMON_H_ 8#define TOOLS_ANDROID_FORWARDER2_COMMON_H_ 9 10#include <stdarg.h> 11#include <stdio.h> 12#include <errno.h> 13 14#include "base/basictypes.h" 15#include "base/compiler_specific.h" 16#include "base/logging.h" 17#include "base/posix/eintr_wrapper.h" 18 19// Preserving errno for Close() is important because the function is very often 20// used in cleanup code, after an error occurred, and it is very easy to pass an 21// invalid file descriptor to close() in this context, or more rarely, a 22// spurious signal might make close() return -1 + setting errno to EINTR, 23// masking the real reason for the original error. This leads to very unpleasant 24// debugging sessions. 25#define PRESERVE_ERRNO_HANDLE_EINTR(Func) \ 26 do { \ 27 int local_errno = errno; \ 28 (void) HANDLE_EINTR(Func); \ 29 errno = local_errno; \ 30 } while (false); 31 32// Wrapper around RAW_LOG() which is signal-safe. The only purpose of this macro 33// is to avoid documenting uses of RawLog(). 34#define SIGNAL_SAFE_LOG(Level, Msg) \ 35 RAW_LOG(Level, Msg); 36 37namespace forwarder2 { 38 39// Note that the two following functions are not signal-safe. 40 41// Chromium logging-aware implementation of libc's perror(). 42void PError(const char* msg); 43 44// Closes the provided file descriptor and logs an error if it failed. 45void CloseFD(int fd); 46 47// Helps build a formatted C-string allocated in a fixed-size array. This is 48// useful in signal handlers where base::StringPrintf() can't be used safely 49// (due to its use of LOG()). 50template <int BufferSize> 51class FixedSizeStringBuilder { 52 public: 53 FixedSizeStringBuilder() { 54 Reset(); 55 } 56 57 const char* buffer() const { return buffer_; } 58 59 void Reset() { 60 buffer_[0] = 0; 61 write_ptr_ = buffer_; 62 } 63 64 // Returns the number of bytes appended to the underlying buffer or -1 if it 65 // failed. 66 int Append(const char* format, ...) PRINTF_FORMAT(/* + 1 for 'this' */ 2, 3) { 67 if (write_ptr_ >= buffer_ + BufferSize) 68 return -1; 69 va_list ap; 70 va_start(ap, format); 71 const int bytes_written = vsnprintf( 72 write_ptr_, BufferSize - (write_ptr_ - buffer_), format, ap); 73 va_end(ap); 74 if (bytes_written > 0) 75 write_ptr_ += bytes_written; 76 return bytes_written; 77 } 78 79 private: 80 char* write_ptr_; 81 char buffer_[BufferSize]; 82 83 COMPILE_ASSERT(BufferSize >= 1, Size_of_buffer_must_be_at_least_one); 84 DISALLOW_COPY_AND_ASSIGN(FixedSizeStringBuilder); 85}; 86 87} // namespace forwarder2 88 89#endif // TOOLS_ANDROID_FORWARDER2_COMMON_H_ 90