90 lines
2.8 KiB
C
90 lines
2.8 KiB
C
|
// 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_
|