From b7d059bb2f4e480d2787cf41e03ef85b75503910 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 6 Jun 2016 14:56:00 -0700 Subject: [PATCH] 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 --- logcat/logcat.cpp | 31 ++++++++++++++- logcat/tests/logcat_test.cpp | 76 ++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp index b8232cd40..ea698c8da 100644 --- a/logcat/logcat.cpp +++ b/logcat/logcat.cpp @@ -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 , --regex=\n" " Only print lines where the log message matches \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; } } diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp index d46e9ff41..0043d1bc0 100644 --- a/logcat/tests/logcat_test.cpp +++ b/logcat/tests/logcat_test.cpp @@ -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(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(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),