File: logging_posix.cc

package info (click to toggle)
android-platform-tools 34.0.5-12
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 150,900 kB
  • sloc: cpp: 805,786; java: 293,500; ansic: 128,288; xml: 127,491; python: 41,481; sh: 14,245; javascript: 9,665; cs: 3,846; asm: 2,049; makefile: 1,917; yacc: 440; awk: 368; ruby: 183; sql: 140; perl: 88; lex: 67
file content (127 lines) | stat: -rw-r--r-- 3,388 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2019 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.

#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <cstdlib>
#include <iostream>
#include <sstream>

#include "platform/impl/logging.h"
#include "platform/impl/logging_test.h"
#include "util/trace_logging.h"

namespace openscreen {
namespace {

int g_log_fd = STDERR_FILENO;
LogLevel g_log_level = LogLevel::kWarning;
std::vector<std::string>* g_log_messages_for_test = nullptr;

std::ostream& operator<<(std::ostream& os, const LogLevel& level) {
  const char* level_string = "";
  switch (level) {
    case LogLevel::kVerbose:
      level_string = "VERBOSE";
      break;
    case LogLevel::kInfo:
      level_string = "INFO";
      break;
    case LogLevel::kWarning:
      level_string = "WARNING";
      break;
    case LogLevel::kError:
      level_string = "ERROR";
      break;
    case LogLevel::kFatal:
      level_string = "FATAL";
      break;
  }
  os << level_string;
  return os;
}

}  // namespace

void SetLogFifoOrDie(const char* filename) {
  if (g_log_fd != STDERR_FILENO) {
    close(g_log_fd);
    g_log_fd = STDERR_FILENO;
  }

  // Note: The use of OSP_CHECK/OSP_LOG_* here will log to stderr.
  struct stat st = {};
  int open_result = -1;
  if (stat(filename, &st) == -1 && errno == ENOENT) {
    if (mkfifo(filename, 0644) == 0) {
      open_result = open(filename, O_WRONLY);
      OSP_CHECK_NE(open_result, -1)
          << "open(" << filename << ") failed: " << strerror(errno);
    } else {
      OSP_LOG_FATAL << "mkfifo(" << filename << ") failed: " << strerror(errno);
    }
  } else if (S_ISFIFO(st.st_mode)) {
    open_result = open(filename, O_WRONLY);
    OSP_CHECK_NE(open_result, -1)
        << "open(" << filename << ") failed: " << strerror(errno);
  } else {
    OSP_LOG_FATAL << "not a FIFO special file: " << filename;
  }

  // Direct all logging to the opened FIFO file.
  g_log_fd = open_result;
}

void SetLogLevel(LogLevel level) {
  g_log_level = level;
}

LogLevel GetLogLevel() {
  return g_log_level;
}

bool IsLoggingOn(LogLevel level, const char* file) {
  // Possible future enhancement: Use glob patterns passed on the command-line
  // to use a different logging level for certain files, like in Chromium.
  return level >= g_log_level;
}

void LogWithLevel(LogLevel level,
                  const char* file,
                  int line,
                  std::stringstream message) {
  if (level < g_log_level)
    return;

  std::stringstream ss;
  ss << "[" << level << ":" << file << "(" << line << "):T" << std::hex
     << TRACE_CURRENT_ID << "] " << message.rdbuf() << '\n';
  const auto ss_str = ss.str();
  const auto bytes_written = write(g_log_fd, ss_str.c_str(), ss_str.size());
  OSP_DCHECK(bytes_written);
  if (g_log_messages_for_test) {
    g_log_messages_for_test->push_back(ss_str);
  }
}

[[noreturn]] void Break() {
// Generally this will just resolve to an abort anyways, but gives the
// compiler a chance to peform a more appropriate, target specific trap
// as appropriate.
#if defined(_DEBUG)
  __builtin_trap();
#else
  std::abort();
#endif
}

void SetLogBufferForTest(std::vector<std::string>* messages) {
  g_log_messages_for_test = messages;
}

}  // namespace openscreen