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