Merge "Move early_hal start to late-fs trigger action" into oc-dev
diff --git a/include/ziparchive/zip_writer.h b/include/ziparchive/zip_writer.h
index 41ca2e1..08ead48 100644
--- a/include/ziparchive/zip_writer.h
+++ b/include/ziparchive/zip_writer.h
@@ -75,7 +75,8 @@
uint32_t uncompressed_size;
uint16_t last_mod_time;
uint16_t last_mod_date;
- uint32_t local_file_header_offset;
+ uint32_t padding_length;
+ off64_t local_file_header_offset;
};
static const char* ErrorCodeString(int32_t error_code);
@@ -172,6 +173,7 @@
};
FILE* file_;
+ bool seekable_;
off64_t current_offset_;
State state_;
std::vector<FileEntry> files_;
diff --git a/init/init.cpp b/init/init.cpp
index 7e61767..94bf37a 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -714,14 +714,18 @@
return false;
}
std::string actual_plat_id;
- if (!read_first_line("/system/etc/selinux/plat_sepolicy.cil.sha256", &actual_plat_id)) {
- PLOG(INFO) << "Failed to read /system/etc/selinux/plat_sepolicy.cil.sha256";
+ if (!read_first_line("/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256",
+ &actual_plat_id)) {
+ PLOG(INFO) << "Failed to read "
+ "/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256";
return false;
}
std::string precompiled_plat_id;
- if (!read_first_line("/vendor/etc/selinux/precompiled_sepolicy.plat.sha256",
+ if (!read_first_line("/vendor/etc/selinux/precompiled_sepolicy.plat_and_mapping.sha256",
&precompiled_plat_id)) {
- PLOG(INFO) << "Failed to read /vendor/etc/selinux/precompiled_sepolicy.plat.sha256";
+ PLOG(INFO) << "Failed to read "
+ "/vendor/etc/selinux/"
+ "precompiled_sepolicy.plat_and_mapping.sha256";
return false;
}
if ((actual_plat_id.empty()) || (actual_plat_id != precompiled_plat_id)) {
@@ -793,7 +797,7 @@
"-M", "true",
// Target the highest policy language version supported by the kernel
"-c", std::to_string(max_policy_version).c_str(),
- "/vendor/etc/selinux/mapping_sepolicy.cil",
+ "/system/etc/selinux/mapping_sepolicy.cil",
"/vendor/etc/selinux/nonplat_sepolicy.cil",
"-o", compiled_sepolicy,
// We don't care about file_contexts output by the compiler
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index 7600528..2edf224 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -18,6 +18,7 @@
#include <cstdio>
#include <sys/param.h>
+#include <sys/stat.h>
#include <zlib.h>
#define DEF_MEM_LEVEL 8 // normally in zutil.h?
@@ -84,11 +85,19 @@
delete stream;
}
-ZipWriter::ZipWriter(FILE* f) : file_(f), current_offset_(0), state_(State::kWritingZip),
- z_stream_(nullptr, DeleteZStream), buffer_(kBufSize) {
+ZipWriter::ZipWriter(FILE* f) : file_(f), seekable_(false), current_offset_(0),
+ state_(State::kWritingZip), z_stream_(nullptr, DeleteZStream),
+ buffer_(kBufSize) {
+ // Check if the file is seekable (regular file). If fstat fails, that's fine, subsequent calls
+ // will fail as well.
+ struct stat file_stats;
+ if (fstat(fileno(f), &file_stats) == 0) {
+ seekable_ = S_ISREG(file_stats.st_mode);
+ }
}
ZipWriter::ZipWriter(ZipWriter&& writer) : file_(writer.file_),
+ seekable_(writer.seekable_),
current_offset_(writer.current_offset_),
state_(writer.state_),
files_(std::move(writer.files_)),
@@ -100,6 +109,7 @@
ZipWriter& ZipWriter::operator=(ZipWriter&& writer) {
file_ = writer.file_;
+ seekable_ = writer.seekable_;
current_offset_ = writer.current_offset_;
state_ = writer.state_;
files_ = std::move(writer.files_);
@@ -159,6 +169,30 @@
*out_time = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
}
+static void CopyFromFileEntry(const ZipWriter::FileEntry& src, bool use_data_descriptor,
+ LocalFileHeader* dst) {
+ dst->lfh_signature = LocalFileHeader::kSignature;
+ if (use_data_descriptor) {
+ // Set this flag to denote that a DataDescriptor struct will appear after the data,
+ // containing the crc and size fields.
+ dst->gpb_flags |= kGPBDDFlagMask;
+
+ // The size and crc fields must be 0.
+ dst->compressed_size = 0u;
+ dst->uncompressed_size = 0u;
+ dst->crc32 = 0u;
+ } else {
+ dst->compressed_size = src.compressed_size;
+ dst->uncompressed_size = src.uncompressed_size;
+ dst->crc32 = src.crc32;
+ }
+ dst->compression_method = src.compression_method;
+ dst->last_mod_time = src.last_mod_time;
+ dst->last_mod_date = src.last_mod_date;
+ dst->file_name_length = src.path.size();
+ dst->extra_field_length = src.padding_length;
+}
+
int32_t ZipWriter::StartAlignedEntryWithTime(const char* path, size_t flags,
time_t time, uint32_t alignment) {
if (state_ != State::kWritingZip) {
@@ -173,66 +207,58 @@
return kInvalidAlignment;
}
- current_file_entry_ = {};
- current_file_entry_.path = path;
- current_file_entry_.local_file_header_offset = current_offset_;
+ FileEntry file_entry = {};
+ file_entry.local_file_header_offset = current_offset_;
+ file_entry.path = path;
- if (!IsValidEntryName(reinterpret_cast<const uint8_t*>(current_file_entry_.path.data()),
- current_file_entry_.path.size())) {
+ if (!IsValidEntryName(reinterpret_cast<const uint8_t*>(file_entry.path.data()),
+ file_entry.path.size())) {
return kInvalidEntryName;
}
- LocalFileHeader header = {};
- header.lfh_signature = LocalFileHeader::kSignature;
-
- // Set this flag to denote that a DataDescriptor struct will appear after the data,
- // containing the crc and size fields.
- header.gpb_flags |= kGPBDDFlagMask;
-
if (flags & ZipWriter::kCompress) {
- current_file_entry_.compression_method = kCompressDeflated;
+ file_entry.compression_method = kCompressDeflated;
int32_t result = PrepareDeflate();
if (result != kNoError) {
return result;
}
} else {
- current_file_entry_.compression_method = kCompressStored;
+ file_entry.compression_method = kCompressStored;
}
- header.compression_method = current_file_entry_.compression_method;
- ExtractTimeAndDate(time, ¤t_file_entry_.last_mod_time, ¤t_file_entry_.last_mod_date);
- header.last_mod_time = current_file_entry_.last_mod_time;
- header.last_mod_date = current_file_entry_.last_mod_date;
+ ExtractTimeAndDate(time, &file_entry.last_mod_time, &file_entry.last_mod_date);
- header.file_name_length = current_file_entry_.path.size();
-
- off64_t offset = current_offset_ + sizeof(header) + current_file_entry_.path.size();
+ off_t offset = current_offset_ + sizeof(LocalFileHeader) + file_entry.path.size();
std::vector<char> zero_padding;
if (alignment != 0 && (offset & (alignment - 1))) {
// Pad the extra field so the data will be aligned.
uint16_t padding = alignment - (offset % alignment);
- header.extra_field_length = padding;
+ file_entry.padding_length = padding;
offset += padding;
- zero_padding.resize(padding);
- memset(zero_padding.data(), 0, zero_padding.size());
+ zero_padding.resize(padding, 0);
}
+ LocalFileHeader header = {};
+ // Always start expecting a data descriptor. When the data has finished being written,
+ // if it is possible to seek back, the GPB flag will reset and the sizes written.
+ CopyFromFileEntry(file_entry, true /*use_data_descriptor*/, &header);
+
if (fwrite(&header, sizeof(header), 1, file_) != 1) {
return HandleError(kIoError);
}
- if (fwrite(path, sizeof(*path), current_file_entry_.path.size(), file_)
- != current_file_entry_.path.size()) {
+ if (fwrite(path, sizeof(*path), file_entry.path.size(), file_) != file_entry.path.size()) {
return HandleError(kIoError);
}
- if (header.extra_field_length != 0 &&
- fwrite(zero_padding.data(), 1, header.extra_field_length, file_)
- != header.extra_field_length) {
+ if (file_entry.padding_length != 0 &&
+ fwrite(zero_padding.data(), 1, file_entry.padding_length, file_)
+ != file_entry.padding_length) {
return HandleError(kIoError);
}
+ current_file_entry_ = std::move(file_entry);
current_offset_ = offset;
state_ = State::kWritingEntry;
return kNoError;
@@ -405,23 +431,41 @@
}
}
- const uint32_t sig = DataDescriptor::kOptSignature;
- if (fwrite(&sig, sizeof(sig), 1, file_) != 1) {
- state_ = State::kError;
- return kIoError;
- }
+ if ((current_file_entry_.compression_method & kCompressDeflated) || !seekable_) {
+ // Some versions of ZIP don't allow STORED data to have a trailing DataDescriptor.
+ // If this file is not seekable, or if the data is compressed, write a DataDescriptor.
+ const uint32_t sig = DataDescriptor::kOptSignature;
+ if (fwrite(&sig, sizeof(sig), 1, file_) != 1) {
+ return HandleError(kIoError);
+ }
- DataDescriptor dd = {};
- dd.crc32 = current_file_entry_.crc32;
- dd.compressed_size = current_file_entry_.compressed_size;
- dd.uncompressed_size = current_file_entry_.uncompressed_size;
- if (fwrite(&dd, sizeof(dd), 1, file_) != 1) {
- return HandleError(kIoError);
+ DataDescriptor dd = {};
+ dd.crc32 = current_file_entry_.crc32;
+ dd.compressed_size = current_file_entry_.compressed_size;
+ dd.uncompressed_size = current_file_entry_.uncompressed_size;
+ if (fwrite(&dd, sizeof(dd), 1, file_) != 1) {
+ return HandleError(kIoError);
+ }
+ current_offset_ += sizeof(DataDescriptor::kOptSignature) + sizeof(dd);
+ } else {
+ // Seek back to the header and rewrite to include the size.
+ if (fseeko(file_, current_file_entry_.local_file_header_offset, SEEK_SET) != 0) {
+ return HandleError(kIoError);
+ }
+
+ LocalFileHeader header = {};
+ CopyFromFileEntry(current_file_entry_, false /*use_data_descriptor*/, &header);
+
+ if (fwrite(&header, sizeof(header), 1, file_) != 1) {
+ return HandleError(kIoError);
+ }
+
+ if (fseeko(file_, current_offset_, SEEK_SET) != 0) {
+ return HandleError(kIoError);
+ }
}
files_.emplace_back(std::move(current_file_entry_));
-
- current_offset_ += sizeof(DataDescriptor::kOptSignature) + sizeof(dd);
state_ = State::kWritingZip;
return kNoError;
}
@@ -431,7 +475,7 @@
return kInvalidState;
}
- off64_t startOfCdr = current_offset_;
+ off_t startOfCdr = current_offset_;
for (FileEntry& file : files_) {
CentralDirectoryRecord cdr = {};
cdr.record_signature = CentralDirectoryRecord::kSignature;
@@ -443,7 +487,7 @@
cdr.compressed_size = file.compressed_size;
cdr.uncompressed_size = file.uncompressed_size;
cdr.file_name_length = file.path.size();
- cdr.local_file_header_offset = file.local_file_header_offset;
+ cdr.local_file_header_offset = static_cast<uint32_t>(file.local_file_header_offset);
if (fwrite(&cdr, sizeof(cdr), 1, file_) != 1) {
return HandleError(kIoError);
}
@@ -473,7 +517,7 @@
// Since we can BackUp() and potentially finish writing at an offset less than one we had
// already written at, we must truncate the file.
- if (ftruncate64(fileno(file_), current_offset_) != 0) {
+ if (ftruncate(fileno(file_), current_offset_) != 0) {
return HandleError(kIoError);
}
diff --git a/libziparchive/zip_writer_test.cc b/libziparchive/zip_writer_test.cc
index 30f4950..5b526a4 100644
--- a/libziparchive/zip_writer_test.cc
+++ b/libziparchive/zip_writer_test.cc
@@ -64,6 +64,7 @@
ZipEntry data;
ASSERT_EQ(0, FindEntry(handle, ZipString("file.txt"), &data));
EXPECT_EQ(kCompressStored, data.method);
+ EXPECT_EQ(0u, data.has_data_descriptor);
EXPECT_EQ(strlen(expected), data.compressed_length);
ASSERT_EQ(strlen(expected), data.uncompressed_length);
ASSERT_TRUE(AssertFileEntryContentsEq(expected, handle, &data));
diff --git a/logcat/Android.mk b/logcat/Android.mk
index f564f0f..4e11ca9 100644
--- a/logcat/Android.mk
+++ b/logcat/Android.mk
@@ -15,6 +15,16 @@
include $(CLEAR_VARS)
+LOCAL_MODULE := logcatd
+LOCAL_MODULE_TAGS := debug
+LOCAL_SRC_FILES := logcatd_main.cpp event.logtags
+LOCAL_SHARED_LIBRARIES := liblogcat $(logcatLibs)
+LOCAL_CFLAGS := -Werror
+
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
LOCAL_MODULE := liblogcat
LOCAL_SRC_FILES := logcat.cpp getopt_long.cpp logcat_system.cpp
LOCAL_SHARED_LIBRARIES := $(logcatLibs)
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 8134936..64d1d2f 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -882,6 +882,7 @@
{ "grep", required_argument, nullptr, 'e' },
// hidden and undocumented reserved alias for --max-count
{ "head", required_argument, nullptr, 'm' },
+ { "help", no_argument, nullptr, 'h' },
{ id_str, required_argument, nullptr, 0 },
{ "last", no_argument, nullptr, 'L' },
{ "max-count", required_argument, nullptr, 'm' },
@@ -900,9 +901,8 @@
};
// clang-format on
- ret = getopt_long_r(argc, argv,
- ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:m:e:", long_options,
- &option_index, &optctx);
+ ret = getopt_long_r(argc, argv, ":cdDhLt:T:gG:sQf:r:n:v:b:BSpP:m:e:",
+ long_options, &option_index, &optctx);
if (ret < 0) break;
switch (ret) {
@@ -1304,6 +1304,11 @@
"Option -%c needs an argument\n", optctx.optopt);
goto exit;
+ case 'h':
+ show_help(context);
+ show_format_help(context);
+ goto exit;
+
default:
logcat_panic(context, HELP_TRUE, "Unrecognized Option %c\n",
optctx.optopt);
diff --git a/logcat/logcatd.rc b/logcat/logcatd.rc
index b082a64..06cc90d 100644
--- a/logcat/logcatd.rc
+++ b/logcat/logcatd.rc
@@ -34,9 +34,6 @@
on property:logd.logpersistd.enable=true && property:logd.logpersistd=logcatd
# all exec/services are called with umask(077), so no gain beyond 0700
mkdir /data/misc/logd 0700 logd log
- # logd for write to /data/misc/logd, log group for read from pstore (-L)
- # b/28788401 b/30041146 b/30612424
- # exec - logd log -- /system/bin/logcat -L -b ${logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n ${logd.logpersistd.size:-256} --id=${ro.build.id}
start logcatd
# stop logcatd service and clear data
@@ -57,7 +54,7 @@
stop logcatd
# logcatd service
-service logcatd /system/bin/logcat -b ${logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n ${logd.logpersistd.size:-256} --id=${ro.build.id}
+service logcatd /system/bin/logcatd -L -b ${logd.logpersistd.buffer:-all} -v threadtime -v usec -v printable -D -f /data/misc/logd/logcat -r 1024 -n ${logd.logpersistd.size:-256} --id=${ro.build.id}
class late_start
disabled
# logd for write to /data/misc/logd, log group for read from log daemon
diff --git a/logcat/logcatd_main.cpp b/logcat/logcatd_main.cpp
new file mode 100644
index 0000000..9109eb1
--- /dev/null
+++ b/logcat/logcatd_main.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <string>
+#include <vector>
+
+#include <log/logcat.h>
+
+int main(int argc, char** argv, char** envp) {
+ android_logcat_context ctx = create_android_logcat();
+ if (!ctx) return -1;
+
+ signal(SIGPIPE, exit);
+
+ // Save and detect presence of -L or --last flag
+ std::vector<std::string> args;
+ bool last = false;
+ for (int i = 0; i < argc; ++i) {
+ if (!argv[i]) continue;
+ args.push_back(std::string(argv[i]));
+ if (!strcmp(argv[i], "-L") || !strcmp(argv[i], "--last")) last = true;
+ }
+
+ // Generate argv from saved content
+ std::vector<const char*> argv_hold;
+ for (auto& str : args) argv_hold.push_back(str.c_str());
+ argv_hold.push_back(nullptr);
+
+ int ret = 0;
+ if (last) {
+ // Run logcat command with -L flag
+ ret = android_logcat_run_command(ctx, -1, -1, argv_hold.size() - 1,
+ (char* const*)&argv_hold[0], envp);
+ // Remove -L and --last flags from argument list
+ for (std::vector<const char*>::iterator it = argv_hold.begin();
+ it != argv_hold.end();) {
+ if (!*it || (strcmp(*it, "-L") && strcmp(*it, "--last"))) {
+ ++it;
+ } else {
+ it = argv_hold.erase(it);
+ }
+ }
+ // fall through to re-run the command regardless of the arguments
+ // passed in. For instance, we expect -h to report help stutter.
+ }
+
+ // Run logcat command without -L flag
+ int retval = android_logcat_run_command(ctx, -1, -1, argv_hold.size() - 1,
+ (char* const*)&argv_hold[0], envp);
+ if (!ret) ret = retval;
+ retval = android_logcat_destroy(&ctx);
+ if (!ret) ret = retval;
+ return ret;
+}
diff --git a/logcat/tests/Android.mk b/logcat/tests/Android.mk
index 22aca17..defd3c4 100644
--- a/logcat/tests/Android.mk
+++ b/logcat/tests/Android.mk
@@ -50,6 +50,7 @@
test_src_files := \
logcat_test.cpp \
+ logcatd_test.cpp \
liblogcat_test.cpp \
# Build tests for the device (with .so). Run with:
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index a3a0176..21868f2 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/cdefs.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
@@ -39,6 +40,10 @@
#define logcat_pclose(context, fp) pclose(fp)
#define logcat_system(command) system(command)
#endif
+#ifndef logcat_executable
+#define USING_LOGCAT_EXECUTABLE_DEFAULT
+#define logcat_executable "logcat"
+#endif
#define BIG_BUFFER (5 * 1024)
@@ -64,14 +69,13 @@
#undef LOG_TAG
#define LOG_TAG "inject"
- RLOGE("logcat.buckets");
+ RLOGE(logcat_executable ".buckets");
sleep(1);
- ASSERT_TRUE(
- NULL !=
- (fp = logcat_popen(
- ctx,
- "logcat -b radio -b events -b system -b main -d 2>/dev/null")));
+ ASSERT_TRUE(NULL !=
+ (fp = logcat_popen(
+ ctx, logcat_executable
+ " -b radio -b events -b system -b main -d 2>/dev/null")));
char buffer[BIG_BUFFER];
@@ -101,8 +105,8 @@
logcat_define(ctx);
ASSERT_TRUE(NULL !=
- (fp = logcat_popen(ctx,
- "logcat -b events -d -s auditd "
+ (fp = logcat_popen(ctx, logcat_executable
+ " -b events -d -s auditd "
"am_proc_start am_pss am_proc_bound "
"dvm_lock_sample am_wtf 2>/dev/null")));
@@ -170,10 +174,9 @@
#endif
strftime(needle, sizeof(needle), "[ %Y-", ptm);
- ASSERT_TRUE(
- NULL !=
- (fp = logcat_popen(
- ctx, "logcat -v long -v year -b all -t 3 2>/dev/null")));
+ ASSERT_TRUE(NULL != (fp = logcat_popen(
+ ctx, logcat_executable
+ " -v long -v year -b all -t 3 2>/dev/null")));
char buffer[BIG_BUFFER];
@@ -237,8 +240,8 @@
logcat_define(ctx);
ASSERT_TRUE(NULL !=
- (fp = logcat_popen(ctx,
- "logcat -v long -v America/Los_Angeles "
+ (fp = logcat_popen(ctx, logcat_executable
+ " -v long -v America/Los_Angeles "
"-b all -t 3 2>/dev/null")));
char buffer[BIG_BUFFER];
@@ -264,10 +267,9 @@
FILE* fp;
logcat_define(ctx);
- ASSERT_TRUE(NULL !=
- (fp = logcat_popen(ctx,
- "logcat -v long -v America/Los_Angeles -v "
- "zone -b all -t 3 2>/dev/null")));
+ ASSERT_TRUE(NULL != (fp = logcat_popen(ctx, logcat_executable
+ " -v long -v America/Los_Angeles -v "
+ "zone -b all -t 3 2>/dev/null")));
char buffer[BIG_BUFFER];
@@ -435,11 +437,11 @@
}
TEST(logcat, tail_time) {
- do_tail_time("logcat -v long -v nsec -b all");
+ do_tail_time(logcat_executable " -v long -v nsec -b all");
}
TEST(logcat, tail_time_epoch) {
- do_tail_time("logcat -v long -v nsec -v epoch -b all");
+ do_tail_time(logcat_executable " -v long -v nsec -v epoch -b all");
}
TEST(logcat, End_to_End) {
@@ -452,8 +454,8 @@
FILE* fp;
logcat_define(ctx);
ASSERT_TRUE(NULL !=
- (fp = logcat_popen(
- ctx, "logcat -v brief -b events -t 100 2>/dev/null")));
+ (fp = logcat_popen(ctx, logcat_executable
+ " -v brief -b events -t 100 2>/dev/null")));
char buffer[BIG_BUFFER];
@@ -492,8 +494,8 @@
size_t num = 0;
do {
EXPECT_TRUE(NULL !=
- (fp[num] = logcat_popen(
- ctx[num], "logcat -v brief -b events -t 100")));
+ (fp[num] = logcat_popen(ctx[num], logcat_executable
+ " -v brief -b events -t 100")));
if (!fp[num]) {
fprintf(stderr,
"WARNING: limiting to %zu simultaneous logcat operations\n",
@@ -604,22 +606,23 @@
}
TEST(logcat, get_size) {
- ASSERT_EQ(4, get_groups("logcat -v brief -b radio -b events -b system -b "
+ ASSERT_EQ(4, get_groups(logcat_executable
+ " -v brief -b radio -b events -b system -b "
"main -g 2>/dev/null"));
}
// duplicate test for get_size, but use comma-separated list of buffers
TEST(logcat, multiple_buffer) {
ASSERT_EQ(
- 4, get_groups(
- "logcat -v brief -b radio,events,system,main -g 2>/dev/null"));
+ 4, get_groups(logcat_executable
+ " -v brief -b radio,events,system,main -g 2>/dev/null"));
}
TEST(logcat, bad_buffer) {
- ASSERT_EQ(
- 0,
- get_groups(
- "logcat -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
+ ASSERT_EQ(0,
+ get_groups(
+ logcat_executable
+ " -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
}
#ifndef logcat
@@ -774,8 +777,8 @@
char buf[sizeof(form)];
ASSERT_TRUE(NULL != mkdtemp(strcpy(buf, form)));
- static const char comm[] =
- "logcat -b radio -b events -b system -b main"
+ static const char comm[] = logcat_executable
+ " -b radio -b events -b system -b main"
" -d -f %s/log.txt -n 7 -r 1";
char command[sizeof(buf) + sizeof(comm)];
snprintf(command, sizeof(command), comm, buf);
@@ -820,8 +823,8 @@
char tmp_out_dir[sizeof(tmp_out_dir_form)];
ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
- static const char logcat_cmd[] =
- "logcat -b radio -b events -b system -b main"
+ static const char logcat_cmd[] = logcat_executable
+ " -b radio -b events -b system -b main"
" -d -f %s/log.txt -n 10 -r 1";
char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd)];
snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir);
@@ -880,7 +883,7 @@
static const char log_filename[] = "log.txt";
static const char logcat_cmd[] =
- "logcat -b all -v nsec -d -f %s/%s -n 256 -r 1024";
+ logcat_executable " -b all -v nsec -d -f %s/%s -n 256 -r 1024";
static const char cleanup_cmd[] = "rm -rf %s";
char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) + sizeof(log_filename)];
snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
@@ -1005,7 +1008,8 @@
static const char log_filename[] = "log.txt";
static const unsigned num_val = 32;
- static const char logcat_cmd[] = "logcat -b all -d -f %s/%s -n %d -r 1";
+ static const char logcat_cmd[] =
+ logcat_executable " -b all -d -f %s/%s -n %d -r 1";
static const char clear_cmd[] = " -c";
static const char cleanup_cmd[] = "rm -rf %s";
char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) +
@@ -1109,9 +1113,9 @@
TEST(logcat, logrotate_id) {
static const char logcat_cmd[] =
- "logcat -b all -d -f %s/%s -n 32 -r 1 --id=test";
+ logcat_executable " -b all -d -f %s/%s -n 32 -r 1 --id=test";
static const char logcat_short_cmd[] =
- "logcat -b all -t 10 -f %s/%s -n 32 -r 1 --id=test";
+ logcat_executable " -b all -t 10 -f %s/%s -n 32 -r 1 --id=test";
static const char tmp_out_dir_form[] =
"/data/local/tmp/logcat.logrotate.XXXXXX";
static const char log_filename[] = "log.txt";
@@ -1155,8 +1159,8 @@
TEST(logcat, logrotate_nodir) {
// expect logcat to error out on writing content and not exit(0) for nodir
- static const char command[] =
- "logcat -b all -d"
+ static const char command[] = logcat_executable
+ " -b all -d"
" -f /das/nein/gerfingerpoken/logcat/log.txt"
" -n 256 -r 1024";
EXPECT_FALSE(IsFalse(0 == logcat_system(command), command));
@@ -1292,7 +1296,7 @@
FILE* fp;
logcat_define(ctx);
- fp = logcat_popen(ctx, "logcat -p 2>/dev/null");
+ fp = logcat_popen(ctx, logcat_executable " -p 2>/dev/null");
if (fp == NULL) {
fprintf(stderr, "ERROR: logcat -p 2>/dev/null\n");
return false;
@@ -1330,7 +1334,8 @@
char buffer[BIG_BUFFER];
- snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list ? list : "");
+ snprintf(buffer, sizeof(buffer), logcat_executable " -P '%s' 2>&1",
+ list ? list : "");
fp = logcat_popen(ctx, buffer);
if (fp == NULL) {
fprintf(stderr, "ERROR: %s\n", buffer);
@@ -1392,15 +1397,11 @@
int count = 0;
char buffer[BIG_BUFFER];
-// Have to make liblogcat data unique from logcat data injection
-#ifdef logcat
-#define logcat_regex_prefix "lolcat_test"
-#else
-#define logcat_regex_prefix "logcat_test"
-#endif
+#define logcat_regex_prefix ___STRING(logcat) "_test"
snprintf(buffer, sizeof(buffer),
- "logcat --pid %d -d -e " logcat_regex_prefix "_a+b", getpid());
+ logcat_executable " --pid %d -d -e " logcat_regex_prefix "_a+b",
+ getpid());
LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, logcat_regex_prefix,
logcat_regex_prefix "_ab"));
@@ -1437,8 +1438,8 @@
char buffer[BIG_BUFFER];
- snprintf(buffer, sizeof(buffer), "logcat --pid %d -d --max-count 3",
- getpid());
+ snprintf(buffer, sizeof(buffer),
+ logcat_executable " --pid %d -d --max-count 3", getpid());
LOG_FAILURE_RETRY(
__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
@@ -1663,8 +1664,34 @@
}
TEST(logcat, security) {
- EXPECT_FALSE(reportedSecurity("logcat -b all -g 2>&1"));
- EXPECT_TRUE(reportedSecurity("logcat -b security -g 2>&1"));
- EXPECT_TRUE(reportedSecurity("logcat -b security -c 2>&1"));
- EXPECT_TRUE(reportedSecurity("logcat -b security -G 256K 2>&1"));
+ EXPECT_FALSE(reportedSecurity(logcat_executable " -b all -g 2>&1"));
+ EXPECT_TRUE(reportedSecurity(logcat_executable " -b security -g 2>&1"));
+ EXPECT_TRUE(reportedSecurity(logcat_executable " -b security -c 2>&1"));
+ EXPECT_TRUE(
+ reportedSecurity(logcat_executable " -b security -G 256K 2>&1"));
+}
+
+static size_t commandOutputSize(const char* command) {
+ logcat_define(ctx);
+ FILE* fp = logcat_popen(ctx, command);
+ if (!fp) return 0;
+
+ std::string ret;
+ if (!android::base::ReadFdToString(fileno(fp), &ret)) return 0;
+ if (logcat_pclose(ctx, fp) != 0) return 0;
+
+ return ret.size();
+}
+
+TEST(logcat, help) {
+ size_t logcatHelpTextSize = commandOutputSize(logcat_executable " -h 2>&1");
+ EXPECT_LT(4096UL, logcatHelpTextSize);
+ size_t logcatLastHelpTextSize =
+ commandOutputSize(logcat_executable " -L -h 2>&1");
+#ifdef USING_LOGCAT_EXECUTABLE_DEFAULT // logcat and liblogcat
+ EXPECT_EQ(logcatHelpTextSize, logcatLastHelpTextSize);
+#else
+ // logcatd -L -h prints the help twice, as designed.
+ EXPECT_EQ(logcatHelpTextSize * 2, logcatLastHelpTextSize);
+#endif
}
diff --git a/logcat/tests/logcatd_test.cpp b/logcat/tests/logcatd_test.cpp
new file mode 100644
index 0000000..bb7534e
--- /dev/null
+++ b/logcat/tests/logcatd_test.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define logcat logcatd
+#define logcat_executable "logcatd"
+
+#include "logcat_test.cpp"