logcat: clear when specifying file output
If -c and -f are both specified, clear the files rather than notifying the logger to clear its data. The -f then acts like a switch between clearing the in-memory log data, or the on-disk logrotate data. Bug: 28936216 Change-Id: Ib1d1fb46ea09f81a2fd9bebb6c8f0f9f2355f6e8
This commit is contained in:
parent
95428817d6
commit
b7d059bb2f
|
@ -290,6 +290,7 @@ static void show_help(const char *cmd)
|
|||
" tag thread threadtime time uid usec UTC year zone\n"
|
||||
" -D, --dividers Print dividers between each log buffer\n"
|
||||
" -c, --clear Clear (flush) the entire log and exit\n"
|
||||
" if Log to File specified, clear fileset instead\n"
|
||||
" -d Dump the log and then exit (don't block)\n"
|
||||
" -e <expr>, --regex=<expr>\n"
|
||||
" Only print lines where the log message matches <expr>\n"
|
||||
|
@ -1033,7 +1034,35 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (clearLog) {
|
||||
if (android_logger_clear(dev->logger)) {
|
||||
if (g_outputFileName) {
|
||||
int maxRotationCountDigits =
|
||||
(g_maxRotatedLogs > 0) ? (int) (floor(log10(g_maxRotatedLogs) + 1)) : 0;
|
||||
|
||||
for (int i = g_maxRotatedLogs ; i >= 0 ; --i) {
|
||||
char *file;
|
||||
|
||||
if (i == 0) {
|
||||
asprintf(&file, "%s", g_outputFileName);
|
||||
} else {
|
||||
asprintf(&file, "%s.%.*d", g_outputFileName, maxRotationCountDigits, i);
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
perror("while clearing log files");
|
||||
clearFail = clearFail ?: dev->device;
|
||||
break;
|
||||
}
|
||||
|
||||
err = unlink(file);
|
||||
|
||||
if (err < 0 && errno != ENOENT && clearFail == NULL) {
|
||||
perror("while clearing log files");
|
||||
clearFail = dev->device;
|
||||
}
|
||||
|
||||
free(file);
|
||||
}
|
||||
} else if (android_logger_clear(dev->logger)) {
|
||||
clearFail = clearFail ?: dev->device;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -772,6 +772,82 @@ TEST(logcat, logrotate_continue) {
|
|||
EXPECT_FALSE(system(command));
|
||||
}
|
||||
|
||||
TEST(logcat, logrotate_clear) {
|
||||
static const char tmp_out_dir_form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
|
||||
char tmp_out_dir[sizeof(tmp_out_dir_form)];
|
||||
ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
|
||||
|
||||
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 clear_cmd[] = " -c";
|
||||
static const char cleanup_cmd[] = "rm -rf %s";
|
||||
char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) + sizeof(log_filename) + sizeof(clear_cmd) + 32];
|
||||
|
||||
// Run command with all data
|
||||
{
|
||||
snprintf(command, sizeof(command) - sizeof(clear_cmd),
|
||||
logcat_cmd, tmp_out_dir, log_filename, num_val);
|
||||
|
||||
int ret;
|
||||
EXPECT_FALSE((ret = system(command)));
|
||||
if (ret) {
|
||||
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
|
||||
EXPECT_FALSE(system(command));
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
|
||||
EXPECT_NE(nullptr, dir);
|
||||
if (!dir) {
|
||||
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
|
||||
EXPECT_FALSE(system(command));
|
||||
return;
|
||||
}
|
||||
struct dirent *entry;
|
||||
unsigned count = 0;
|
||||
while ((entry = readdir(dir.get()))) {
|
||||
if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
|
||||
continue;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
EXPECT_EQ(count, num_val + 1);
|
||||
}
|
||||
|
||||
{
|
||||
// Now with -c option tacked onto the end
|
||||
strcat(command, clear_cmd);
|
||||
|
||||
int ret;
|
||||
EXPECT_FALSE((ret = system(command)));
|
||||
if (ret) {
|
||||
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
|
||||
EXPECT_FALSE(system(command));
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
|
||||
EXPECT_NE(nullptr, dir);
|
||||
if (!dir) {
|
||||
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
|
||||
EXPECT_FALSE(system(command));
|
||||
return;
|
||||
}
|
||||
struct dirent *entry;
|
||||
unsigned count = 0;
|
||||
while ((entry = readdir(dir.get()))) {
|
||||
if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "Found %s/%s!!!\n", tmp_out_dir, entry->d_name);
|
||||
++count;
|
||||
}
|
||||
EXPECT_EQ(count, 0U);
|
||||
}
|
||||
|
||||
snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
|
||||
EXPECT_FALSE(system(command));
|
||||
}
|
||||
|
||||
TEST(logcat, logrotate_nodir) {
|
||||
// expect logcat to error out on writing content and exit(1) for nodir
|
||||
EXPECT_EQ(W_EXITCODE(1, 0),
|
||||
|
|
Loading…
Reference in New Issue