logcat: allow comma-separate list of buffers
- Add parsing to support comma+ separated list of buffers.
- Move get_size test into a standalone get_groups function
- add some additional tests for this feature, leveraging
get_groups to confirm buffer selection.
Bug: 28120456
Change-Id: I0b42736c08cf4b2a435cb74cda540dc163a26bd1
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 04b096f..fe5da19 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -315,8 +315,8 @@
// kernel (userdebug and eng) buffers undocumented.
" -b <buffer>, --buffer=<buffer> Request alternate ring buffer, 'main',\n"
" 'system', 'radio', 'events', 'crash', 'default' or 'all'.\n"
- " Multiple -b parameters are allowed. Buffers interleaved.\n"
- " Default -b main -b system -b crash.\n"
+ " Multiple -b parameters or comma separated list of buffers are\n"
+ " allowed. Buffers interleaved. Default -b main,system,crash.\n"
" -B, --binary Output the log in binary.\n"
" -S, --statistics Output statistics.\n"
" -p, --prune Print prune white and ~black list. Service is specified as\n"
@@ -762,111 +762,63 @@
break;
case 'b': {
- if (strcmp(optarg, "default") == 0) {
- for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
- switch (i) {
- case LOG_ID_SECURITY:
- case LOG_ID_EVENTS:
- continue;
- case LOG_ID_MAIN:
- case LOG_ID_SYSTEM:
- case LOG_ID_CRASH:
- break;
- default:
- continue;
- }
+ unsigned idMask = 0;
+ while ((optarg = strtok(optarg, ",:; \t\n\r\f")) != NULL) {
+ if (strcmp(optarg, "default") == 0) {
+ idMask |= (1 << LOG_ID_MAIN) |
+ (1 << LOG_ID_SYSTEM) |
+ (1 << LOG_ID_CRASH);
+ } else if (strcmp(optarg, "all") == 0) {
+ idMask = (unsigned)-1;
+ } else {
+ log_id_t log_id = android_name_to_log_id(optarg);
+ const char *name = android_log_id_to_name(log_id);
- const char *name = android_log_id_to_name((log_id_t)i);
- log_id_t log_id = android_name_to_log_id(name);
-
- if (log_id != (log_id_t)i) {
- continue;
+ if (strcmp(name, optarg) != 0) {
+ logcat_panic(true, "unknown buffer %s\n", optarg);
}
-
- bool found = false;
- for (dev = devices; dev; dev = dev->next) {
- if (!strcmp(optarg, dev->device)) {
- found = true;
- break;
- }
- if (!dev->next) {
- break;
- }
- }
- if (found) {
- break;
- }
-
- log_device_t* d = new log_device_t(name, false);
-
- if (dev) {
- dev->next = d;
- dev = d;
- } else {
- devices = dev = d;
- }
- g_devCount++;
+ idMask |= (1 << log_id);
}
- break;
+ optarg = NULL;
}
- if (strcmp(optarg, "all") == 0) {
- for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
- const char *name = android_log_id_to_name((log_id_t)i);
- log_id_t log_id = android_name_to_log_id(name);
+ for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
+ const char *name = android_log_id_to_name((log_id_t)i);
+ log_id_t log_id = android_name_to_log_id(name);
- if (log_id != (log_id_t)i) {
- continue;
- }
+ if (log_id != (log_id_t)i) {
+ continue;
+ }
+ if ((idMask & (1 << i)) == 0) {
+ continue;
+ }
- bool found = false;
- for (dev = devices; dev; dev = dev->next) {
- if (!strcmp(optarg, dev->device)) {
- found = true;
- break;
- }
- if (!dev->next) {
- break;
- }
- }
- if (found) {
+ bool found = false;
+ for (dev = devices; dev; dev = dev->next) {
+ if (!strcmp(name, dev->device)) {
+ found = true;
break;
}
-
- bool binary = !strcmp(name, "events") ||
- !strcmp(name, "security");
- log_device_t* d = new log_device_t(name, binary);
-
- if (dev) {
- dev->next = d;
- dev = d;
- } else {
- devices = dev = d;
- }
- g_devCount++;
- }
- break;
- }
-
- bool binary = !(strcmp(optarg, "events") &&
- strcmp(optarg, "security"));
-
- if (devices) {
- dev = devices;
- while (dev->next) {
- if (!strcmp(optarg, dev->device)) {
- dev = NULL;
+ if (!dev->next) {
break;
}
- dev = dev->next;
}
+ if (found) {
+ continue;
+ }
+
+ bool binary = !strcmp(name, "events") ||
+ !strcmp(name, "security");
+ log_device_t* d = new log_device_t(name, binary);
+
if (dev) {
- dev->next = new log_device_t(optarg, binary);
+ dev->next = d;
+ dev = d;
+ } else {
+ devices = dev = d;
}
- } else {
- devices = new log_device_t(optarg, binary);
+ g_devCount++;
}
- g_devCount++;
}
break;
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index a606b6f..2c3579d 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -30,6 +30,8 @@
#include <log/logger.h>
#include <log/log_read.h>
+#define BIG_BUFFER (5 * 1024)
+
// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
// non-syscall libs. Since we are only using this in the emergency of
// a signal to stuff a terminating code into the logs, we will spin rather
@@ -54,7 +56,7 @@
"logcat -b radio -b events -b system -b main -d 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int ids = 0;
int count = 0;
@@ -102,7 +104,7 @@
"logcat -v long -v year -b all -t 3 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -165,7 +167,7 @@
"logcat -v long -v America/Los_Angeles -b all -t 3 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
count = 0;
@@ -189,7 +191,7 @@
"logcat -v long -v America/Los_Angeles -v zone -b all -t 3 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -209,7 +211,7 @@
int count;
do {
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer),
"logcat -v long -b radio -b events -b system -b main -t %d 2>/dev/null",
@@ -252,7 +254,7 @@
ASSERT_TRUE(NULL != (fp = popen("logcat -v long -b all -t 10 2>&1", "r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
char *last_timestamp = NULL;
char *first_timestamp = NULL;
int count = 0;
@@ -315,7 +317,7 @@
"logcat -v brief -b events -t 100 2>/dev/null",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -339,15 +341,17 @@
ASSERT_EQ(1, count);
}
-TEST(logcat, get_size) {
+int get_groups(const char *cmd) {
FILE *fp;
// NB: crash log only available in user space
- ASSERT_TRUE(NULL != (fp = popen(
- "logcat -v brief -b radio -b events -b system -b main -g 2>/dev/null",
- "r")));
+ EXPECT_TRUE(NULL != (fp = popen(cmd, "r")));
- char buffer[5120];
+ if (fp == NULL) {
+ return 0;
+ }
+
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -407,7 +411,23 @@
pclose(fp);
- ASSERT_EQ(4, count);
+ return count;
+}
+
+TEST(logcat, get_size) {
+ ASSERT_EQ(4, get_groups(
+ "logcat -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"));
+}
+
+TEST(logcat, bad_buffer) {
+ ASSERT_EQ(0, get_groups(
+ "logcat -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
}
static void caught_blocking(int /*signum*/)
@@ -436,7 +456,7 @@
" logcat -v brief -b events 2>&1",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -505,7 +525,7 @@
" logcat -v brief -b events -T 5 2>&1",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -568,7 +588,7 @@
FILE *fp;
EXPECT_TRUE(NULL != (fp = popen(command, "r")));
if (fp) {
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
while (fgets(buffer, sizeof(buffer), fp)) {
@@ -611,7 +631,7 @@
FILE *fp;
EXPECT_TRUE(NULL != (fp = popen(command, "r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int log_file_count = 0;
while (fgets(buffer, sizeof(buffer), fp)) {
@@ -784,7 +804,7 @@
" logcat -v brief -b events 2>&1",
"r")));
- char buffer[5120];
+ char buffer[BIG_BUFFER];
int count = 0;
@@ -845,7 +865,7 @@
return false;
}
- char buffer[5120];
+ char buffer[BIG_BUFFER];
while (fgets(buffer, sizeof(buffer), fp)) {
char *hold = *list;
@@ -874,7 +894,7 @@
static bool set_white_black(const char *list) {
FILE *fp;
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list ? list : "");
fp = popen(buffer, "r");
@@ -936,7 +956,7 @@
FILE *fp;
int count = 0;
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer), "logcat --pid %d -d -e logcat_test_a+b", getpid());
@@ -969,7 +989,7 @@
FILE *fp;
int count = 0;
- char buffer[5120];
+ char buffer[BIG_BUFFER];
snprintf(buffer, sizeof(buffer), "logcat --pid %d -d --max-count 3", getpid());