update to libbase-242728
BUG=chromium:331128 TEST=`FEATURES=test emerge-x86-alex platform2` works TEST=`cbuildbot chromiumos-sdk` works CQ-DEPEND=CL:185131 Change-Id: Ia03a6ea7aaf6b4ee5d9c512ebf7080c0c28920f1 Reviewed-on: https://chromium-review.googlesource.com/185150 Reviewed-by: Ben Chan <benchan@chromium.org> Commit-Queue: Mike Frysinger <vapier@chromium.org> Tested-by: Mike Frysinger <vapier@chromium.org>
This commit is contained in:
parent
01ca40d690
commit
a557c1187f
22 changed files with 134 additions and 121 deletions
|
|
@ -15,9 +15,9 @@
|
|||
#include <base/file_util.h>
|
||||
#include <base/logging.h>
|
||||
#include <base/rand_util.h>
|
||||
#include <base/string_number_conversions.h>
|
||||
#include <base/string_util.h>
|
||||
#include <base/stringprintf.h>
|
||||
#include <base/strings/string_number_conversions.h>
|
||||
#include <base/strings/string_util.h>
|
||||
#include <base/strings/stringprintf.h>
|
||||
#include "chromeos/process.h"
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "chromeos/dbus/dbus.h"
|
||||
|
|
@ -55,6 +55,9 @@ const char kRunning64[] = " running task ";
|
|||
const char kSymbolAndOffsetRE[] =
|
||||
"([[:alpha:]._$][[:alnum:]._$]*)\\+0x([[:xdigit:]]+)/0x([[:xdigit:]]+)";
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
|
||||
namespace {
|
||||
|
||||
// Extract a string delimited by the given character, from the given offset
|
||||
|
|
@ -108,7 +111,7 @@ bool GetDriErrorState(const chromeos::dbus::Proxy &proxy,
|
|||
|
||||
if (written < 0 || (gsize)written != len) {
|
||||
LOG(ERROR) << "Could not write file " << error_state_path.value();
|
||||
file_util::Delete(error_state_path, false);
|
||||
base::DeleteFile(error_state_path, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -312,7 +315,7 @@ bool WriteKernelTaskStates(const chromeos::dbus::Proxy &proxy,
|
|||
|
||||
std::vector<std::string> task_sates;
|
||||
if (!GetKernelTaskStates(proxy, &task_sates)) {
|
||||
file_util::Delete(task_states_path, false);
|
||||
base::DeleteFile(task_states_path, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -368,10 +371,10 @@ bool GetAdditionalLogs(const FilePath &log_path) {
|
|||
tar_process.AddArg(task_states_path.BaseName().value());
|
||||
int res = tar_process.Run();
|
||||
|
||||
file_util::Delete(error_state_path, false);
|
||||
file_util::Delete(task_states_path, false);
|
||||
base::DeleteFile(error_state_path, false);
|
||||
base::DeleteFile(task_states_path, false);
|
||||
|
||||
if (res || !file_util::PathExists(log_path)) {
|
||||
if (res || !base::PathExists(log_path)) {
|
||||
LOG(ERROR) << "Could not tar file " << log_path.value();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -411,7 +414,7 @@ bool ChromeCollector::HandleCrash(const std::string &file_path,
|
|||
FilePath log_path = GetCrashPath(dir, dump_basename, "log.tar.xz");
|
||||
|
||||
std::string data;
|
||||
if (!file_util::ReadFileToString(FilePath(file_path), &data)) {
|
||||
if (!base::ReadFileToString(FilePath(file_path), &data)) {
|
||||
LOG(ERROR) << "Can't read crash log: " << file_path.c_str();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -424,15 +427,15 @@ bool ChromeCollector::HandleCrash(const std::string &file_path,
|
|||
if (GetAdditionalLogs(log_path)) {
|
||||
int64 minidump_size = 0;
|
||||
int64 log_size = 0;
|
||||
if (file_util::GetFileSize(minidump_path, &minidump_size) &&
|
||||
file_util::GetFileSize(log_path, &log_size) &&
|
||||
if (base::GetFileSize(minidump_path, &minidump_size) &&
|
||||
base::GetFileSize(log_path, &log_size) &&
|
||||
minidump_size > 0 && log_size > 0 &&
|
||||
minidump_size + log_size < kDefaultMaxUploadBytes) {
|
||||
AddCrashMetaData("log", log_path.value());
|
||||
} else {
|
||||
LOG(INFO) << "Skipping logs upload to prevent discarding minidump "
|
||||
"because of report size limit < " << minidump_size + log_size;
|
||||
file_util::Delete(log_path, false);
|
||||
base::DeleteFile(log_path, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "crash-reporter/crash_collector.h"
|
||||
#include "gtest/gtest_prod.h" // for FRIEND_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/string_split.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "chromeos/test_helpers.h"
|
||||
#include "crash-reporter/chrome_collector.h"
|
||||
|
|
@ -49,8 +49,7 @@ class ChromeCollectorTest : public ::testing::Test {
|
|||
void ExpectFileEquals(const char *golden,
|
||||
const char *file_path) {
|
||||
std::string contents;
|
||||
EXPECT_TRUE(file_util::ReadFileToString(FilePath(file_path),
|
||||
&contents));
|
||||
EXPECT_TRUE(base::ReadFileToString(FilePath(file_path), &contents));
|
||||
EXPECT_EQ(golden, contents);
|
||||
}
|
||||
|
||||
|
|
@ -121,7 +120,7 @@ TEST_F(ChromeCollectorTest, File) {
|
|||
EXPECT_TRUE(meta.find("value3=ok") != std::string::npos);
|
||||
ExpectFileEquals("12345\n789\n12345",
|
||||
dir.Append("base-foo.txt.other").value().c_str());
|
||||
file_util::Delete(dir.Append("base-foo.txt.other"), false);
|
||||
base::DeleteFile(dir.Append("base-foo.txt.other"), false);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
],
|
||||
},
|
||||
},
|
||||
'variables': {
|
||||
'libbase_ver': 242728,
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'libcrash',
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@
|
|||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "base/string_split.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/stringprintf.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chromeos/cryptohome.h"
|
||||
#include "chromeos/dbus/dbus.h"
|
||||
#include "chromeos/dbus/service_constants.h"
|
||||
|
|
@ -73,6 +73,7 @@ static const uid_t kRootGroup = 0;
|
|||
const int CrashCollector::kMaxCrashDirectorySize = 32;
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
|
||||
CrashCollector::CrashCollector()
|
||||
: forced_crash_directory_(NULL),
|
||||
|
|
@ -283,7 +284,7 @@ bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid,
|
|||
&directory_owner,
|
||||
&directory_group);
|
||||
|
||||
if (!file_util::PathExists(*crash_directory)) {
|
||||
if (!base::PathExists(*crash_directory)) {
|
||||
// Create the spool directory with the appropriate mode (regardless of
|
||||
// umask) and ownership.
|
||||
mode_t old_mask = umask(0);
|
||||
|
|
@ -297,7 +298,7 @@ bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid,
|
|||
umask(old_mask);
|
||||
}
|
||||
|
||||
if (!file_util::PathExists(*crash_directory)) {
|
||||
if (!base::PathExists(*crash_directory)) {
|
||||
LOG(ERROR) << "Unable to create crash directory "
|
||||
<< crash_directory->value().c_str();
|
||||
return false;
|
||||
|
|
@ -353,7 +354,7 @@ bool CrashCollector::GetExecutableBaseNameFromPid(pid_t pid,
|
|||
if (!GetSymlinkTarget(exe_path, &target)) {
|
||||
LOG(INFO) << "GetSymlinkTarget failed - Path " << process_path.value()
|
||||
<< " DirectoryExists: "
|
||||
<< file_util::DirectoryExists(process_path);
|
||||
<< base::DirectoryExists(process_path);
|
||||
// Try to further diagnose exe readlink failure cause.
|
||||
struct stat buf;
|
||||
int stat_result = stat(exe_path.value().c_str(), &buf);
|
||||
|
|
@ -422,7 +423,7 @@ bool CrashCollector::ReadKeyValueFile(
|
|||
const char separator,
|
||||
std::map<std::string, std::string> *dictionary) {
|
||||
std::string contents;
|
||||
if (!file_util::ReadFileToString(path, &contents)) {
|
||||
if (!base::ReadFileToString(path, &contents)) {
|
||||
return false;
|
||||
}
|
||||
typedef std::vector<std::string> StringVector;
|
||||
|
|
@ -507,7 +508,7 @@ void CrashCollector::WriteCrashMetaData(const FilePath &meta_path,
|
|||
version = i->second;
|
||||
}
|
||||
int64 payload_size = -1;
|
||||
file_util::GetFileSize(FilePath(payload_path), &payload_size);
|
||||
base::GetFileSize(FilePath(payload_path), &payload_size);
|
||||
std::string meta_data = StringPrintf("%sexec_name=%s\n"
|
||||
"ver=%s\n"
|
||||
"payload=%s\n"
|
||||
|
|
@ -527,7 +528,7 @@ void CrashCollector::WriteCrashMetaData(const FilePath &meta_path,
|
|||
}
|
||||
|
||||
bool CrashCollector::IsCrashTestInProgress() {
|
||||
return file_util::PathExists(FilePath(kCrashTestInProgressPath));
|
||||
return base::PathExists(FilePath(kCrashTestInProgressPath));
|
||||
}
|
||||
|
||||
bool CrashCollector::IsDeveloperImage() {
|
||||
|
|
@ -535,7 +536,7 @@ bool CrashCollector::IsDeveloperImage() {
|
|||
// for developer images.
|
||||
if (IsCrashTestInProgress())
|
||||
return false;
|
||||
return file_util::PathExists(FilePath(kLeaveCoreFile));
|
||||
return base::PathExists(FilePath(kLeaveCoreFile));
|
||||
}
|
||||
|
||||
bool CrashCollector::ShouldHandleChromeCrashes() {
|
||||
|
|
@ -546,7 +547,7 @@ bool CrashCollector::ShouldHandleChromeCrashes() {
|
|||
// Check if there's an override to indicate we should indeed collect
|
||||
// chrome crashes. This allows the crashes to still be tracked when
|
||||
// they occur in autotests. See "crosbug.com/17987".
|
||||
if (file_util::PathExists(FilePath(kCollectChromeFile)))
|
||||
if (base::PathExists(FilePath(kCollectChromeFile)))
|
||||
return true;
|
||||
}
|
||||
// We default to ignoring chrome crashes.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "gtest/gtest_prod.h" // for FRIEND_TEST
|
||||
|
||||
// User crash collector.
|
||||
|
|
|
|||
|
|
@ -10,14 +10,15 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/stringprintf.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "chromeos/test_helpers.h"
|
||||
#include "crash-reporter/crash_collector.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
using chromeos::FindLog;
|
||||
using ::testing::Return;
|
||||
|
||||
|
|
@ -36,12 +37,12 @@ class CrashCollectorTest : public ::testing::Test {
|
|||
collector_.Initialize(CountCrash,
|
||||
IsMetrics);
|
||||
test_dir_ = FilePath("test");
|
||||
file_util::CreateDirectory(test_dir_);
|
||||
base::CreateDirectory(test_dir_);
|
||||
chromeos::ClearLog();
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
file_util::Delete(test_dir_, true);
|
||||
base::DeleteFile(test_dir_, true);
|
||||
}
|
||||
|
||||
bool CheckHasCapacity();
|
||||
|
|
@ -291,7 +292,7 @@ TEST_F(CrashCollectorTest, MetaData) {
|
|||
kPayload, strlen(kPayload)));
|
||||
collector_.AddCrashMetaData("foo", "bar");
|
||||
collector_.WriteCrashMetaData(meta_file, "kernel", payload_file.value());
|
||||
EXPECT_TRUE(file_util::ReadFileToString(meta_file, &contents));
|
||||
EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
|
||||
const char kExpectedMeta[] =
|
||||
"foo=bar\n"
|
||||
"exec_name=kernel\n"
|
||||
|
|
@ -310,24 +311,24 @@ TEST_F(CrashCollectorTest, MetaData) {
|
|||
ASSERT_EQ(0,
|
||||
symlink(kMetaFileBasename,
|
||||
meta_symlink_path.value().c_str()));
|
||||
ASSERT_TRUE(file_util::PathExists(meta_symlink_path));
|
||||
ASSERT_TRUE(base::PathExists(meta_symlink_path));
|
||||
chromeos::ClearLog();
|
||||
collector_.WriteCrashMetaData(meta_symlink_path,
|
||||
"kernel",
|
||||
payload_file.value());
|
||||
// Target metadata contents should have stayed the same.
|
||||
contents.clear();
|
||||
EXPECT_TRUE(file_util::ReadFileToString(meta_file, &contents));
|
||||
EXPECT_TRUE(base::ReadFileToString(meta_file, &contents));
|
||||
EXPECT_EQ(kExpectedMeta, contents);
|
||||
EXPECT_TRUE(FindLog("Unable to write"));
|
||||
|
||||
// Test target of dangling symlink is not created.
|
||||
file_util::Delete(meta_file, false);
|
||||
ASSERT_FALSE(file_util::PathExists(meta_file));
|
||||
base::DeleteFile(meta_file, false);
|
||||
ASSERT_FALSE(base::PathExists(meta_file));
|
||||
chromeos::ClearLog();
|
||||
collector_.WriteCrashMetaData(meta_symlink_path, "kernel",
|
||||
payload_file.value());
|
||||
EXPECT_FALSE(file_util::PathExists(meta_file));
|
||||
EXPECT_FALSE(base::PathExists(meta_file));
|
||||
EXPECT_TRUE(FindLog("Unable to write"));
|
||||
}
|
||||
|
||||
|
|
@ -339,18 +340,18 @@ TEST_F(CrashCollectorTest, GetLogContents) {
|
|||
ASSERT_TRUE(
|
||||
file_util::WriteFile(config_file,
|
||||
kConfigContents, strlen(kConfigContents)));
|
||||
file_util::Delete(FilePath(output_file), false);
|
||||
base::DeleteFile(FilePath(output_file), false);
|
||||
EXPECT_FALSE(collector_.GetLogContents(config_file,
|
||||
"barfoo",
|
||||
output_file));
|
||||
EXPECT_FALSE(file_util::PathExists(output_file));
|
||||
file_util::Delete(FilePath(output_file), false);
|
||||
EXPECT_FALSE(base::PathExists(output_file));
|
||||
base::DeleteFile(FilePath(output_file), false);
|
||||
EXPECT_TRUE(collector_.GetLogContents(config_file,
|
||||
"foobar",
|
||||
output_file));
|
||||
ASSERT_TRUE(file_util::PathExists(output_file));
|
||||
ASSERT_TRUE(base::PathExists(output_file));
|
||||
std::string contents;
|
||||
EXPECT_TRUE(file_util::ReadFileToString(output_file, &contents));
|
||||
EXPECT_TRUE(base::ReadFileToString(output_file, &contents));
|
||||
EXPECT_EQ("hello world\n", contents);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
#include <base/file_util.h>
|
||||
#include <base/command_line.h>
|
||||
#include <base/logging.h>
|
||||
#include <base/string_split.h>
|
||||
#include <base/string_util.h>
|
||||
#include <base/stringprintf.h>
|
||||
#include <base/strings/string_split.h>
|
||||
#include <base/strings/string_util.h>
|
||||
#include <base/strings/stringprintf.h>
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "crash-reporter/chrome_collector.h"
|
||||
#include "crash-reporter/kernel_collector.h"
|
||||
|
|
@ -61,6 +61,7 @@ enum CrashKinds {
|
|||
static MetricsLibrary s_metrics_lib;
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
|
||||
static bool IsFeedbackAllowed() {
|
||||
return s_metrics_lib.AreMetricsEnabled();
|
||||
|
|
@ -221,8 +222,8 @@ static int HandleKernelWarning(KernelWarningCollector
|
|||
static int GenerateKernelSignature(KernelCollector *kernel_collector) {
|
||||
std::string kcrash_contents;
|
||||
std::string signature;
|
||||
if (!file_util::ReadFileToString(FilePath(FLAGS_generate_kernel_signature),
|
||||
&kcrash_contents)) {
|
||||
if (!base::ReadFileToString(FilePath(FLAGS_generate_kernel_signature),
|
||||
&kcrash_contents)) {
|
||||
fprintf(stderr, "Could not read file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -259,8 +260,7 @@ static void OpenStandardFileDescriptors() {
|
|||
int main(int argc, char *argv[]) {
|
||||
OpenStandardFileDescriptors();
|
||||
google::ParseCommandLineFlags(&argc, &argv, true);
|
||||
FilePath my_path(argv[0]);
|
||||
file_util::AbsolutePath(&my_path);
|
||||
FilePath my_path = base::MakeAbsoluteFilePath(FilePath(argv[0]));
|
||||
s_metrics_lib.Init();
|
||||
CommandLine::Init(argc, argv);
|
||||
chromeos::OpenLog(my_path.BaseName().value().c_str(), true);
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/stringprintf.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
|
||||
static const char kDefaultKernelStackSignature[] =
|
||||
"kernel-UnspecifiedStackSignature";
|
||||
|
|
@ -46,6 +46,7 @@ static const char *s_pc_regex[] = {
|
|||
};
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
|
||||
COMPILE_ASSERT(arraysize(s_pc_regex) == KernelCollector::archCount,
|
||||
missing_arch_pc_regexp);
|
||||
|
|
@ -79,7 +80,7 @@ bool KernelCollector::ReadRecordToString(std::string *contents,
|
|||
|
||||
FilePath ramoops_record;
|
||||
GetRamoopsRecordPath(&ramoops_record, current_record);
|
||||
if (!file_util::ReadFileToString(ramoops_record, &record)) {
|
||||
if (!base::ReadFileToString(ramoops_record, &record)) {
|
||||
LOG(ERROR) << "Unable to open " << ramoops_record.value();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -87,7 +88,7 @@ bool KernelCollector::ReadRecordToString(std::string *contents,
|
|||
if (record_re.FullMatch(record, &captured)){
|
||||
// Found a match, append it to the content, and remove from pstore.
|
||||
contents->append(captured);
|
||||
file_util::Delete(ramoops_record, false);
|
||||
base::DeleteFile(ramoops_record, false);
|
||||
*record_found = true;
|
||||
} else {
|
||||
*record_found = false;
|
||||
|
|
@ -115,7 +116,7 @@ bool KernelCollector::LoadParameters() {
|
|||
FilePath ramoops_record;
|
||||
GetRamoopsRecordPath(&ramoops_record, count);
|
||||
|
||||
if (!file_util::PathExists(ramoops_record))
|
||||
if (!base::PathExists(ramoops_record))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -234,7 +235,7 @@ bool KernelCollector::Enable() {
|
|||
else {
|
||||
FilePath ramoops_record;
|
||||
GetRamoopsRecordPath(&ramoops_record, 0);
|
||||
if (!file_util::PathExists(ramoops_record)) {
|
||||
if (!base::PathExists(ramoops_record)) {
|
||||
LOG(WARNING) << "Kernel does not support crash dumping";
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "crash-reporter/crash_collector.h"
|
||||
#include "gtest/gtest_prod.h" // for FRIEND_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/stringprintf.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "chromeos/test_helpers.h"
|
||||
#include "crash-reporter/kernel_collector.h"
|
||||
|
|
@ -19,6 +19,7 @@ static const char kTestKCrash[] = "test/kcrash";
|
|||
static const char kTestCrashDirectory[] = "test/crash_directory";
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
using chromeos::FindLog;
|
||||
using chromeos::GetLog;
|
||||
|
||||
|
|
@ -69,7 +70,7 @@ TEST_F(KernelCollectorTest, ComputeKernelStackSignatureBase) {
|
|||
}
|
||||
|
||||
TEST_F(KernelCollectorTest, LoadPreservedDump) {
|
||||
ASSERT_FALSE(file_util::PathExists(test_kcrash_));
|
||||
ASSERT_FALSE(base::PathExists(test_kcrash_));
|
||||
std::string dump;
|
||||
dump.clear();
|
||||
|
||||
|
|
@ -272,9 +273,9 @@ TEST_F(KernelCollectorTest, CollectOK) {
|
|||
ASSERT_NE(std::string::npos, end_pos);
|
||||
filename = filename.substr(0, end_pos);
|
||||
ASSERT_EQ(0, filename.find(kTestCrashDirectory));
|
||||
ASSERT_TRUE(file_util::PathExists(FilePath(filename)));
|
||||
ASSERT_TRUE(base::PathExists(FilePath(filename)));
|
||||
std::string contents;
|
||||
ASSERT_TRUE(file_util::ReadFileToString(FilePath(filename), &contents));
|
||||
ASSERT_TRUE(base::ReadFileToString(FilePath(filename), &contents));
|
||||
ASSERT_EQ("something", contents);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_number_conversions.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/stringprintf.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
|
||||
namespace {
|
||||
const char kExecName[] = "kernel-warning";
|
||||
|
|
@ -18,6 +18,9 @@ const pid_t kKernelPid = 0;
|
|||
const uid_t kRootUid = 0;
|
||||
} // namespace
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
|
||||
KernelWarningCollector::KernelWarningCollector() {
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +30,7 @@ KernelWarningCollector::~KernelWarningCollector() {
|
|||
bool KernelWarningCollector::LoadKernelWarning(std::string *content,
|
||||
std::string *hash_string) {
|
||||
FilePath kernel_warning_path(kKernelWarningPath);
|
||||
if (!file_util::ReadFileToString(kernel_warning_path, content)) {
|
||||
if (!base::ReadFileToString(kernel_warning_path, content)) {
|
||||
LOG(ERROR) << "Could not open " << kKernelWarningPath;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
#include "base/command_line.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/string_number_conversions.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/string_tokenizer.h"
|
||||
#include "base/values.h"
|
||||
#include "chromeos/dbus/dbus.h"
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#include "base/basictypes.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/string_split.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chromeos/process.h"
|
||||
|
||||
static const char kCollectUdevSignature[] = "crash_reporter-udev-collection";
|
||||
|
|
@ -77,7 +77,7 @@ bool UdevCollector::HandleCrash(const std::string &udev_event) {
|
|||
int process_result = gzip_process.Run();
|
||||
FilePath crash_path_zipped = FilePath(crash_path.value() + ".gz");
|
||||
// If the zip file was not created, use the uncompressed file.
|
||||
if (process_result != 0 || !file_util::PathExists(crash_path_zipped))
|
||||
if (process_result != 0 || !base::PathExists(crash_path_zipped))
|
||||
LOG(ERROR) << "Could not create zip file " << crash_path_zipped.value();
|
||||
else
|
||||
crash_path = crash_path_zipped;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "crash-reporter/crash_collector.h"
|
||||
#include "gtest/gtest_prod.h" // for FRIEND_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/file_enumerator.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "chromeos/test_helpers.h"
|
||||
|
|
@ -32,9 +33,8 @@ bool IsMetrics() {
|
|||
|
||||
// Returns the number of compressed crash log files found in the given path.
|
||||
int GetNumLogFiles(const FilePath& path) {
|
||||
file_util::FileEnumerator enumerator(path, false,
|
||||
file_util::FileEnumerator::FILES,
|
||||
"*.log.gz");
|
||||
base::FileEnumerator enumerator(path, false, base::FileEnumerator::FILES,
|
||||
"*.log.gz");
|
||||
int num_files = 0;
|
||||
for (FilePath file_path = enumerator.Next();
|
||||
!file_path.value().empty();
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ UncleanShutdownCollector::~UncleanShutdownCollector() {
|
|||
|
||||
bool UncleanShutdownCollector::Enable() {
|
||||
FilePath file_path(unclean_shutdown_file_);
|
||||
file_util::CreateDirectory(file_path.DirName());
|
||||
base::CreateDirectory(file_path.DirName());
|
||||
if (file_util::WriteFile(file_path, "", 0) != 0) {
|
||||
LOG(ERROR) << "Unable to create shutdown check file";
|
||||
return false;
|
||||
|
|
@ -37,19 +37,19 @@ bool UncleanShutdownCollector::Enable() {
|
|||
}
|
||||
|
||||
bool UncleanShutdownCollector::DeleteUncleanShutdownFiles() {
|
||||
if (!file_util::Delete(FilePath(unclean_shutdown_file_), false)) {
|
||||
if (!base::DeleteFile(FilePath(unclean_shutdown_file_), false)) {
|
||||
LOG(ERROR) << "Failed to delete unclean shutdown file "
|
||||
<< unclean_shutdown_file_;
|
||||
return false;
|
||||
}
|
||||
// Delete power manager state file if it exists.
|
||||
file_util::Delete(powerd_suspended_file_, false);
|
||||
base::DeleteFile(powerd_suspended_file_, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UncleanShutdownCollector::Collect() {
|
||||
FilePath unclean_file_path(unclean_shutdown_file_);
|
||||
if (!file_util::PathExists(unclean_file_path)) {
|
||||
if (!base::PathExists(unclean_file_path)) {
|
||||
return false;
|
||||
}
|
||||
LOG(WARNING) << "Last shutdown was not clean";
|
||||
|
|
@ -72,7 +72,7 @@ bool UncleanShutdownCollector::Disable() {
|
|||
|
||||
bool UncleanShutdownCollector::DeadBatteryCausedUncleanShutdown() {
|
||||
// Check for case of battery running out while suspended.
|
||||
if (file_util::PathExists(powerd_suspended_file_)) {
|
||||
if (base::PathExists(powerd_suspended_file_)) {
|
||||
LOG(INFO) << "Unclean shutdown occurred while suspended. Not counting "
|
||||
<< "toward unclean shutdown statistic.";
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "crash-reporter/crash_collector.h"
|
||||
#include "gtest/gtest_prod.h" // for FRIEND_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "base/file_util.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "chromeos/test_helpers.h"
|
||||
#include "crash-reporter/unclean_shutdown_collector.h"
|
||||
|
|
@ -37,7 +37,7 @@ class UncleanShutdownCollectorTest : public ::testing::Test {
|
|||
rmdir(kTestDirectory);
|
||||
test_unclean_ = FilePath(kTestUnclean);
|
||||
collector_.unclean_shutdown_file_ = kTestUnclean;
|
||||
file_util::Delete(test_unclean_, true);
|
||||
base::DeleteFile(test_unclean_, true);
|
||||
// Set up an alternate power manager state file as well
|
||||
collector_.powerd_suspended_file_ = FilePath(kTestSuspended);
|
||||
chromeos::ClearLog();
|
||||
|
|
@ -55,13 +55,13 @@ class UncleanShutdownCollectorTest : public ::testing::Test {
|
|||
|
||||
TEST_F(UncleanShutdownCollectorTest, EnableWithoutParent) {
|
||||
ASSERT_TRUE(collector_.Enable());
|
||||
ASSERT_TRUE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_TRUE(base::PathExists(test_unclean_));
|
||||
}
|
||||
|
||||
TEST_F(UncleanShutdownCollectorTest, EnableWithParent) {
|
||||
mkdir(kTestDirectory, 0777);
|
||||
ASSERT_TRUE(collector_.Enable());
|
||||
ASSERT_TRUE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_TRUE(base::PathExists(test_unclean_));
|
||||
}
|
||||
|
||||
TEST_F(UncleanShutdownCollectorTest, EnableCannotWrite) {
|
||||
|
|
@ -72,9 +72,9 @@ TEST_F(UncleanShutdownCollectorTest, EnableCannotWrite) {
|
|||
|
||||
TEST_F(UncleanShutdownCollectorTest, CollectTrue) {
|
||||
ASSERT_TRUE(collector_.Enable());
|
||||
ASSERT_TRUE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_TRUE(base::PathExists(test_unclean_));
|
||||
ASSERT_TRUE(collector_.Collect());
|
||||
ASSERT_FALSE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_FALSE(base::PathExists(test_unclean_));
|
||||
ASSERT_EQ(1, s_crashes);
|
||||
ASSERT_TRUE(FindLog("Last shutdown was not clean"));
|
||||
}
|
||||
|
|
@ -86,20 +86,20 @@ TEST_F(UncleanShutdownCollectorTest, CollectFalse) {
|
|||
|
||||
TEST_F(UncleanShutdownCollectorTest, CollectDeadBatterySuspended) {
|
||||
ASSERT_TRUE(collector_.Enable());
|
||||
ASSERT_TRUE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_TRUE(base::PathExists(test_unclean_));
|
||||
file_util::WriteFile(collector_.powerd_suspended_file_, "", 0);
|
||||
ASSERT_FALSE(collector_.Collect());
|
||||
ASSERT_FALSE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_FALSE(file_util::PathExists(collector_.powerd_suspended_file_));
|
||||
ASSERT_FALSE(base::PathExists(test_unclean_));
|
||||
ASSERT_FALSE(base::PathExists(collector_.powerd_suspended_file_));
|
||||
ASSERT_EQ(0, s_crashes);
|
||||
ASSERT_TRUE(FindLog("Unclean shutdown occurred while suspended."));
|
||||
}
|
||||
|
||||
TEST_F(UncleanShutdownCollectorTest, Disable) {
|
||||
ASSERT_TRUE(collector_.Enable());
|
||||
ASSERT_TRUE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_TRUE(base::PathExists(test_unclean_));
|
||||
ASSERT_TRUE(collector_.Disable());
|
||||
ASSERT_FALSE(file_util::PathExists(test_unclean_));
|
||||
ASSERT_FALSE(base::PathExists(test_unclean_));
|
||||
ASSERT_FALSE(collector_.Collect());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@
|
|||
#include "base/logging.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/string_split.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/stringprintf.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "chromeos/process.h"
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "gflags/gflags.h"
|
||||
|
|
@ -54,6 +54,7 @@ const char *UserCollector::kUserId = "Uid:\t";
|
|||
const char *UserCollector::kGroupId = "Gid:\t";
|
||||
|
||||
using base::FilePath;
|
||||
using base::StringPrintf;
|
||||
|
||||
UserCollector::UserCollector()
|
||||
: generate_diagnostics_(false),
|
||||
|
|
@ -200,9 +201,9 @@ void UserCollector::EnqueueCollectionErrorLog(pid_t pid,
|
|||
// the error log. We cannot just append to files because we need
|
||||
// to always create new files to prevent attack.
|
||||
std::string diag_log_contents;
|
||||
file_util::ReadFileToString(diag_log_path, &diag_log_contents);
|
||||
base::ReadFileToString(diag_log_path, &diag_log_contents);
|
||||
error_log.append(diag_log_contents);
|
||||
file_util::Delete(diag_log_path, false);
|
||||
base::DeleteFile(diag_log_path, false);
|
||||
}
|
||||
FilePath log_path = GetCrashPath(crash_path, dump_basename, "log");
|
||||
FilePath meta_path = GetCrashPath(crash_path, dump_basename, "meta");
|
||||
|
|
@ -217,12 +218,12 @@ void UserCollector::EnqueueCollectionErrorLog(pid_t pid,
|
|||
|
||||
bool UserCollector::CopyOffProcFiles(pid_t pid,
|
||||
const FilePath &container_dir) {
|
||||
if (!file_util::CreateDirectory(container_dir)) {
|
||||
if (!base::CreateDirectory(container_dir)) {
|
||||
PLOG(ERROR) << "Could not create " << container_dir.value().c_str();
|
||||
return false;
|
||||
}
|
||||
FilePath process_path = GetProcessPath(pid);
|
||||
if (!file_util::PathExists(process_path)) {
|
||||
if (!base::PathExists(process_path)) {
|
||||
LOG(ERROR) << "Path " << process_path.value() << " does not exist";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -234,8 +235,8 @@ bool UserCollector::CopyOffProcFiles(pid_t pid,
|
|||
"status"
|
||||
};
|
||||
for (unsigned i = 0; i < arraysize(proc_files); ++i) {
|
||||
if (!file_util::CopyFile(process_path.Append(proc_files[i]),
|
||||
container_dir.Append(proc_files[i]))) {
|
||||
if (!base::CopyFile(process_path.Append(proc_files[i]),
|
||||
container_dir.Append(proc_files[i]))) {
|
||||
LOG(ERROR) << "Could not copy " << proc_files[i] << " file";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -247,7 +248,7 @@ bool UserCollector::ValidateProcFiles(const FilePath &container_dir) const {
|
|||
// Check if the maps file is empty, which could be due to the crashed
|
||||
// process being reaped by the kernel before finishing a core dump.
|
||||
int64 file_size = 0;
|
||||
if (!file_util::GetFileSize(container_dir.Append("maps"), &file_size)) {
|
||||
if (!base::GetFileSize(container_dir.Append("maps"), &file_size)) {
|
||||
LOG(ERROR) << "Could not get the size of maps file";
|
||||
return false;
|
||||
}
|
||||
|
|
@ -267,7 +268,7 @@ UserCollector::ErrorType UserCollector::ValidateCoreFile(
|
|||
}
|
||||
|
||||
char e_ident[EI_NIDENT];
|
||||
bool read_ok = file_util::ReadFromFD(fd, e_ident, sizeof(e_ident));
|
||||
bool read_ok = base::ReadFromFD(fd, e_ident, sizeof(e_ident));
|
||||
HANDLE_EINTR(close(fd));
|
||||
if (!read_ok) {
|
||||
LOG(ERROR) << "Could not read header of core file";
|
||||
|
|
@ -304,7 +305,7 @@ bool UserCollector::GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid,
|
|||
}
|
||||
|
||||
uid_t uid;
|
||||
if (file_util::ReadFileToString(process_path.Append("status"), &status)) {
|
||||
if (base::ReadFileToString(process_path.Append("status"), &status)) {
|
||||
std::vector<std::string> status_lines;
|
||||
base::SplitString(status, '\n', &status_lines);
|
||||
|
||||
|
|
@ -330,7 +331,7 @@ bool UserCollector::GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid,
|
|||
} else {
|
||||
LOG(ERROR) << "Could not read status file and kernel did not supply UID";
|
||||
LOG(INFO) << "Path " << process_path.value() << " DirectoryExists: "
|
||||
<< file_util::DirectoryExists(process_path);
|
||||
<< base::DirectoryExists(process_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -344,13 +345,13 @@ bool UserCollector::GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid,
|
|||
bool UserCollector::CopyStdinToCoreFile(const FilePath &core_path) {
|
||||
// Copy off all stdin to a core file.
|
||||
FilePath stdin_path("/dev/fd/0");
|
||||
if (file_util::CopyFile(stdin_path, core_path)) {
|
||||
if (base::CopyFile(stdin_path, core_path)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PLOG(ERROR) << "Could not write core file";
|
||||
// If the file system was full, make sure we remove any remnants.
|
||||
file_util::Delete(core_path, false);
|
||||
base::DeleteFile(core_path, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -375,14 +376,14 @@ bool UserCollector::RunCoreToMinidump(const FilePath &core_path,
|
|||
int errorlevel = core2md.Run();
|
||||
|
||||
std::string output;
|
||||
file_util::ReadFileToString(output_path, &output);
|
||||
base::ReadFileToString(output_path, &output);
|
||||
if (errorlevel != 0) {
|
||||
LOG(ERROR) << "Problem during " << kCoreToMinidumpConverterPath
|
||||
<< " [result=" << errorlevel << "]: " << output;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_util::PathExists(minidump_path)) {
|
||||
if (!base::PathExists(minidump_path)) {
|
||||
LOG(ERROR) << "Minidump file " << minidump_path.value()
|
||||
<< " was not created";
|
||||
return false;
|
||||
|
|
@ -443,7 +444,7 @@ UserCollector::ErrorType UserCollector::ConvertAndEnqueueCrash(
|
|||
// Delete a pre-existing directory from crash reporter that may have
|
||||
// been left around for diagnostics from a failed conversion attempt.
|
||||
// If we don't, existing files can cause forking to fail.
|
||||
file_util::Delete(container_dir, true);
|
||||
base::DeleteFile(container_dir, true);
|
||||
std::string dump_basename = FormatDumpBasename(exec, time(NULL), pid);
|
||||
FilePath core_path = GetCrashPath(crash_path, dump_basename, "core");
|
||||
FilePath meta_path = GetCrashPath(crash_path, dump_basename, "meta");
|
||||
|
|
@ -469,13 +470,13 @@ UserCollector::ErrorType UserCollector::ConvertAndEnqueueCrash(
|
|||
minidump_path.value());
|
||||
|
||||
if (!IsDeveloperImage()) {
|
||||
file_util::Delete(core_path, false);
|
||||
base::DeleteFile(core_path, false);
|
||||
} else {
|
||||
LOG(INFO) << "Leaving core file at " << core_path.value()
|
||||
<< " due to developer image";
|
||||
}
|
||||
|
||||
file_util::Delete(container_dir, true);
|
||||
base::DeleteFile(container_dir, true);
|
||||
return kErrorNone;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/file_path.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "crash-reporter/crash_collector.h"
|
||||
#include "gtest/gtest_prod.h" // for FRIEND_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "base/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/string_split.h"
|
||||
#include "base/strings/string_split.h"
|
||||
#include "chromeos/syslog_logging.h"
|
||||
#include "chromeos/test_helpers.h"
|
||||
#include "crash-reporter/user_collector.h"
|
||||
|
|
@ -42,7 +42,7 @@ class UserCollectorTest : public ::testing::Test {
|
|||
kFilePath,
|
||||
IsMetrics,
|
||||
false);
|
||||
file_util::Delete(FilePath("test"), true);
|
||||
base::DeleteFile(FilePath("test"), true);
|
||||
mkdir("test", 0777);
|
||||
collector_.set_core_pattern_file("test/core_pattern");
|
||||
collector_.set_core_pipe_limit_file("test/core_pipe_limit");
|
||||
|
|
@ -54,7 +54,7 @@ class UserCollectorTest : public ::testing::Test {
|
|||
void ExpectFileEquals(const char *golden,
|
||||
const char *file_path) {
|
||||
std::string contents;
|
||||
EXPECT_TRUE(file_util::ReadFileToString(FilePath(file_path),
|
||||
EXPECT_TRUE(base::ReadFileToString(FilePath(file_path),
|
||||
&contents));
|
||||
EXPECT_EQ(golden, contents);
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ TEST_F(UserCollectorTest, EnableNoPipeLimitFileAccess) {
|
|||
ASSERT_EQ(s_crashes, 0);
|
||||
// Core pattern should not be written if we cannot access the pipe limit
|
||||
// or otherwise we may set a pattern that results in infinite recursion.
|
||||
ASSERT_FALSE(file_util::PathExists(FilePath("test/core_pattern")));
|
||||
ASSERT_FALSE(base::PathExists(FilePath("test/core_pattern")));
|
||||
EXPECT_TRUE(FindLog("Enabling user crash handling"));
|
||||
EXPECT_TRUE(FindLog("Unable to write /does_not_exist"));
|
||||
}
|
||||
|
|
@ -463,7 +463,7 @@ TEST_F(UserCollectorTest, CopyOffProcFilesOK) {
|
|||
};
|
||||
for (unsigned i = 0; i < sizeof(expectations)/sizeof(expectations[0]); ++i) {
|
||||
EXPECT_EQ(expectations[i].exists,
|
||||
file_util::PathExists(
|
||||
base::PathExists(
|
||||
container_path.Append(expectations[i].name)));
|
||||
}
|
||||
}
|
||||
|
|
@ -479,13 +479,13 @@ TEST_F(UserCollectorTest, ValidateProcFiles) {
|
|||
// maps file is empty
|
||||
FilePath maps_file = container_dir.Append("maps");
|
||||
ASSERT_EQ(0, file_util::WriteFile(maps_file, NULL, 0));
|
||||
ASSERT_TRUE(file_util::PathExists(maps_file));
|
||||
ASSERT_TRUE(base::PathExists(maps_file));
|
||||
EXPECT_FALSE(collector_.ValidateProcFiles(container_dir));
|
||||
|
||||
// maps file is not empty
|
||||
const char data[] = "test data";
|
||||
ASSERT_EQ(sizeof(data), file_util::WriteFile(maps_file, data, sizeof(data)));
|
||||
ASSERT_TRUE(file_util::PathExists(maps_file));
|
||||
ASSERT_TRUE(base::PathExists(maps_file));
|
||||
EXPECT_TRUE(collector_.ValidateProcFiles(container_dir));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue