root/tools/android/forwarder2/common.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Common helper functions/classes used both in the host and device forwarder.

#ifndef TOOLS_ANDROID_FORWARDER2_COMMON_H_
#define TOOLS_ANDROID_FORWARDER2_COMMON_H_

#include <stdarg.h>
#include <stdio.h>
#include <errno.h>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"

// Preserving errno for Close() is important because the function is very often
// used in cleanup code, after an error occurred, and it is very easy to pass an
// invalid file descriptor to close() in this context, or more rarely, a
// spurious signal might make close() return -1 + setting errno to EINTR,
// masking the real reason for the original error. This leads to very unpleasant
// debugging sessions.
#define PRESERVE_ERRNO_HANDLE_EINTR(Func)                     \
  do {                                                        \
    int local_errno = errno;                                  \
    (void) HANDLE_EINTR(Func);                                \
    errno = local_errno;                                      \
  } while (false);

// Wrapper around RAW_LOG() which is signal-safe. The only purpose of this macro
// is to avoid documenting uses of RawLog().
#define SIGNAL_SAFE_LOG(Level, Msg) \
  RAW_LOG(Level, Msg);

namespace forwarder2 {

// Note that the two following functions are not signal-safe.

// Chromium logging-aware implementation of libc's perror().
void PError(const char* msg);

// Closes the provided file descriptor and logs an error if it failed.
void CloseFD(int fd);

// Helps build a formatted C-string allocated in a fixed-size array. This is
// useful in signal handlers where base::StringPrintf() can't be used safely
// (due to its use of LOG()).
template <int BufferSize>
class FixedSizeStringBuilder {
 public:
  FixedSizeStringBuilder() {
    Reset();
  }

  const char* buffer() const { return buffer_; }

  void Reset() {
    buffer_[0] = 0;
    write_ptr_ = buffer_;
  }

  // Returns the number of bytes appended to the underlying buffer or -1 if it
  // failed.
  int Append(const char* format, ...) PRINTF_FORMAT(/* + 1 for 'this' */ 2, 3) {
    if (write_ptr_ >= buffer_ + BufferSize)
      return -1;
    va_list ap;
    va_start(ap, format);
    const int bytes_written = vsnprintf(
        write_ptr_, BufferSize - (write_ptr_ - buffer_), format, ap);
    va_end(ap);
    if (bytes_written > 0)
      write_ptr_ += bytes_written;
    return bytes_written;
  }

 private:
  char* write_ptr_;
  char buffer_[BufferSize];

  COMPILE_ASSERT(BufferSize >= 1, Size_of_buffer_must_be_at_least_one);
  DISALLOW_COPY_AND_ASSIGN(FixedSizeStringBuilder);
};

}  // namespace forwarder2

#endif  // TOOLS_ANDROID_FORWARDER2_COMMON_H_

/* [<][>][^][v][top][bottom][index][help] */