17b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn// Copyright 2006-2015 The Android Open Source Project 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <arpa/inet.h> 465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <assert.h> 565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <ctype.h> 6f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn#include <dirent.h> 765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <errno.h> 865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <fcntl.h> 9562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen#include <getopt.h> 10eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou#include <math.h> 113ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <sched.h> 123ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <signal.h> 133ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <stdarg.h> 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 175976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau#include <sys/cdefs.h> 18aede9897df492e7dd550f581e49d9151b36fcea8Riley Andrews#include <sys/resource.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 21f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn#include <sys/types.h> 223ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <time.h> 233ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <unistd.h> 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn#include <memory> 26f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn#include <string> 27f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn 284f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/file.h> 294f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/strings.h> 303ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <cutils/sched_policy.h> 3165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <cutils/sockets.h> 323ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <log/event_tag_map.h> 3365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <log/log.h> 34fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <log/log_read.h> 3565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <log/logd.h> 363ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn#include <log/logger.h> 3765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <log/logprint.h> 38aede9897df492e7dd550f581e49d9151b36fcea8Riley Andrews#include <utils/threads.h> 3965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn 400f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin#include <pcrecpp.h> 410f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DEFAULT_MAX_ROTATED_LOGS 4 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic AndroidLogFormat * g_logformat; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* logd prefixes records with a length field */ 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define RECORD_LENGTH_FIELD_SIZE_BYTES sizeof(uint32_t) 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostruct log_device_t { 5095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn const char* device; 516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool binary; 5295132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn struct logger *logger; 5395132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn struct logger_list *logger_list; 546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool printed; 556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 566fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* next; 576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 585f6738af4897f11d5a6674cffefdfcd2b46c5890Mark Salyzyn log_device_t(const char* d, bool b) { 596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato device = d; 606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato binary = b; 616fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato next = NULL; 626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printed = false; 635976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logger = NULL; 645976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logger_list = NULL; 656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato}; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Global Variables */ 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 729cc9cf0280bfd90c8ccaafb250ccd4a4621b1cbcMark Salyzynstatic const char * g_outputFileName; 735976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau// 0 means "no log rotation" 749cc9cf0280bfd90c8ccaafb250ccd4a4621b1cbcMark Salyzynstatic size_t g_logRotateSizeKBytes; 755976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau// 0 means "unbounded" 765976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiaustatic size_t g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_outFD = -1; 789cc9cf0280bfd90c8ccaafb250ccd4a4621b1cbcMark Salyzynstatic size_t g_outByteCount; 799cc9cf0280bfd90c8ccaafb250ccd4a4621b1cbcMark Salyzynstatic int g_printBinary; 809cc9cf0280bfd90c8ccaafb250ccd4a4621b1cbcMark Salyzynstatic int g_devCount; // >1 means multiple 810f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlinstatic pcrecpp::RE* g_regex; 821164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin// 0 means "infinite" 839cc9cf0280bfd90c8ccaafb250ccd4a4621b1cbcMark Salyzynstatic size_t g_maxCount; 849cc9cf0280bfd90c8ccaafb250ccd4a4621b1cbcMark Salyzynstatic size_t g_printCount; 853bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzynstatic bool g_printItAnyways; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 87df42ce4cf33faf800e6cef6d203bd9448a436dbdMark Salyzyn// if showHelp is set, newline required in fmt statement to transition to usage 885976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau__noreturn static void logcat_panic(bool showHelp, const char *fmt, ...) __printflike(2,3); 895976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int openLogFile (const char *pathname) 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 9280b221cb22f37446e76829d2dd0e8953a32f3bdaEdwin Vane return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void rotateLogs() 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Can't rotate logs if we're not outputting to a file 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(g_outFD); 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 106eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou // Compute the maximum number of digits needed to count up to g_maxRotatedLogs in decimal. 107eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou // eg: g_maxRotatedLogs == 30 -> log10(30) == 1.477 -> maxRotationCountDigits == 2 108eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou int maxRotationCountDigits = 109eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou (g_maxRotatedLogs > 0) ? (int) (floor(log10(g_maxRotatedLogs) + 1)) : 0; 110eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = g_maxRotatedLogs ; i > 0 ; i--) { 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *file0, *file1; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 114eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou asprintf(&file1, "%s.%.*d", g_outputFileName, maxRotationCountDigits, i); 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i - 1 == 0) { 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file0, "%s", g_outputFileName); 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 119eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou asprintf(&file0, "%s.%.*d", g_outputFileName, maxRotationCountDigits, i - 1); 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1225976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (!file0 || !file1) { 1235976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau perror("while rotating log files"); 1245976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau break; 1255976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 1265976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 1275976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau err = rename(file0, file1); 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0 && errno != ENOENT) { 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("while rotating log files"); 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file1); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file0); 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1375976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau g_outFD = openLogFile(g_outputFileName); 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 1405976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "couldn't open output file"); 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount = 0; 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 14795132e97e57b055c5103619ce2487d07f30e63dbMark Salyzynvoid printBinary(struct log_msg *buf) 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 14995132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn size_t size = buf->len(); 15095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn 15195132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn TEMP_FAILURE_RETRY(write(g_outFD, buf, size)); 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 154df42ce4cf33faf800e6cef6d203bd9448a436dbdMark Salyzynstatic bool regexOk(const AndroidLogEntry& entry) 1550f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin{ 156df42ce4cf33faf800e6cef6d203bd9448a436dbdMark Salyzyn if (!g_regex) { 1570f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin return true; 1580f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin } 1590f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin 1600f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin std::string messageString(entry.message, entry.messageLen); 1610f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin 1620f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin return g_regex->PartialMatch(messageString); 1630f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin} 1640f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin 16595132e97e57b055c5103619ce2487d07f30e63dbMark Salyzynstatic void processBuffer(log_device_t* dev, struct log_msg *buf) 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 16750844525a31fa41d7d432efb3c0355b38adb2f5fMathias Agopian int bytesWritten = 0; 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AndroidLogEntry entry; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char binaryMsgBuf[1024]; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->binary) { 1739421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn static bool hasOpenedEventTagMap = false; 1749421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn static EventTagMap *eventTagMap = NULL; 1759421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn 1769421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn if (!eventTagMap && !hasOpenedEventTagMap) { 1779421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE); 1789421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn hasOpenedEventTagMap = true; 1799421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn } 18095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn err = android_log_processBinaryLogBuffer(&buf->entry_v1, &entry, 1819421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn eventTagMap, 18295132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn binaryMsgBuf, 18395132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn sizeof(binaryMsgBuf)); 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //printf(">>> pri=%d len=%d msg='%s'\n", 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // entry.priority, entry.messageLen, entry.message); 186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 18795132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn err = android_log_processLogBuffer(&buf->entry_v1, &entry); 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 189e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (err < 0) { 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 191e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 192e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato 1933bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) { 1943bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn bool match = regexOk(entry); 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1963bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn g_printCount += match; 1973bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn if (match || g_printItAnyways) { 1983bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry); 1991164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin 2003bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn if (bytesWritten < 0) { 2013bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn logcat_panic(false, "output error"); 2023bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn } 203e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount += bytesWritten; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 20895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (g_logRotateSizeKBytes > 0 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && (g_outByteCount / 1024) >= g_logRotateSizeKBytes 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ) { 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rotateLogs(); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecterror: 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //fprintf (stderr, "Error processing record\n"); 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2197b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzynstatic void maybePrintStart(log_device_t* dev, bool printDividers) { 2207b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn if (!dev->printed || printDividers) { 221d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_devCount > 1 && !g_printBinary) { 222d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor char buf[1024]; 2237b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn snprintf(buf, sizeof(buf), "--------- %s %s\n", 2247b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn dev->printed ? "switch to" : "beginning of", 22595132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn dev->device); 226d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (write(g_outFD, buf, strlen(buf)) < 0) { 2275976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "output error"); 228d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 229d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 2307b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn dev->printed = true; 2316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void setupOutput() 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = STDOUT_FILENO; 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 2413ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn if (set_sched_policy(0, SP_BACKGROUND) < 0) { 2423ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn fprintf(stderr, "failed to set background scheduling policy\n"); 2433ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn } 2443ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn 2453ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn struct sched_param param; 2463ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn memset(¶m, 0, sizeof(param)); 2473ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn if (sched_setscheduler((pid_t) 0, SCHED_BATCH, ¶m) < 0) { 2483ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn fprintf(stderr, "failed to set to batch scheduler\n"); 2493ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn } 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 251aede9897df492e7dd550f581e49d9151b36fcea8Riley Andrews if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { 252aede9897df492e7dd550f581e49d9151b36fcea8Riley Andrews fprintf(stderr, "failed set to priority\n"); 253aede9897df492e7dd550f581e49d9151b36fcea8Riley Andrews } 254aede9897df492e7dd550f581e49d9151b36fcea8Riley Andrews 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = openLogFile (g_outputFileName); 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 2585976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "couldn't open output file"); 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2613ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn struct stat statbuf; 2625976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (fstat(g_outFD, &statbuf) == -1) { 2635976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau close(g_outFD); 2645976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "couldn't get output file stat\n"); 2655976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 2665976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 2675976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if ((size_t) statbuf.st_size > SIZE_MAX || statbuf.st_size < 0) { 2685976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau close(g_outFD); 2695976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "invalid output file stat\n"); 2705976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount = statbuf.st_size; 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void show_help(const char *cmd) 277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd); 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "options include:\n" 2813f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -s Set default filter to silent. Equivalent to filterspec '*:S'\n" 2823f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -f <file>, --file=<file> Log to file. Default is stdout\n" 2833f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -r <kbytes>, --rotate-kbytes=<kbytes>\n" 2843f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " Rotate log every kbytes. Requires -f option\n" 2853f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -n <count>, --rotate-count=<count>\n" 2863f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " Sets max number of rotated logs to <count>, default 4\n" 2873f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -v <format>, --format=<format>\n" 2883f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " Sets the log print format, where <format> is:\n" 2893f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " brief color epoch long monotonic printable process raw\n" 2903f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " tag thread threadtime time uid usec UTC year zone\n" 2913f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -D, --dividers Print dividers between each log buffer\n" 2923f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -c, --clear Clear (flush) the entire log and exit\n" 293c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn " if Log to File specified, clear fileset instead\n" 2943f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -d Dump the log and then exit (don't block)\n" 2953f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -e <expr>, --regex=<expr>\n" 2963f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " Only print lines where the log message matches <expr>\n" 2973f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " where <expr> is a regular expression\n" 2983f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn // Leave --head undocumented as alias for -m 2993f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -m <count>, --max-count=<count>\n" 3003f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " Quit after printing <count> lines. This is meant to be\n" 3013f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " paired with --regex, but will work on its own.\n" 3023f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " --print Paired with --regex and --max-count to let content bypass\n" 3033bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn " regex filter but still stop at number of matches.\n" 3043f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn // Leave --tail undocumented as alias for -t 3053f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -t <count> Print only the most recent <count> lines (implies -d)\n" 3063f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -t '<time>' Print most recent lines since specified time (implies -d)\n" 3073f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -T <count> Print only the most recent <count> lines (does not imply -d)\n" 3083f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -T '<time>' Print most recent lines since specified time (not imply -d)\n" 309f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn " count is pure numerical, time is 'MM-DD hh:mm:ss.mmm...'\n" 3104cbed02e440dc400668fbdfb8ce4a710e5caebe5Mark Salyzyn " 'YYYY-MM-DD hh:mm:ss.mmm...' or 'sssss.mmm...' format\n" 3113f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -g, --buffer-size Get the size of the ring buffer.\n" 3123f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -G <size>, --buffer-size=<size>\n" 3133f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " Set size of log ring buffer, may suffix with K or M.\n" 3143f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -L, -last Dump logs from prior to last reboot\n" 315083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn // Leave security (Device Owner only installations) and 316083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn // kernel (userdebug and eng) buffers undocumented. 3173f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -b <buffer>, --buffer=<buffer> Request alternate ring buffer, 'main',\n" 3183f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " 'system', 'radio', 'events', 'crash', 'default' or 'all'.\n" 3197545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn " Multiple -b parameters or comma separated list of buffers are\n" 3207545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn " allowed. Buffers interleaved. Default -b main,system,crash.\n" 3213f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -B, --binary Output the log in binary.\n" 3223f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -S, --statistics Output statistics.\n" 3233f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -p, --prune Print prune white and ~black list. Service is specified as\n" 3243f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " UID, UID/PID or /PID. Weighed for quicker pruning if prefix\n" 325bbbe14f758d7b9f147daf82a59b317b087631c01Mark Salyzyn " with ~, otherwise weighed for longevity if unadorned. All\n" 326bbbe14f758d7b9f147daf82a59b317b087631c01Mark Salyzyn " other pruning activity is oldest first. Special case ~!\n" 327bbbe14f758d7b9f147daf82a59b317b087631c01Mark Salyzyn " represents an automatic quicker pruning for the noisiest\n" 328bbbe14f758d7b9f147daf82a59b317b087631c01Mark Salyzyn " UID as determined by the current statistics.\n" 3293f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " -P '<list> ...', --prune='<list> ...'\n" 3303f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " Set prune white and ~black list, using same format as\n" 3313f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn " listed above. Must be quoted.\n" 33241ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn " --pid=<pid> Only prints logs from the given pid.\n" 3333f6777a3dd848eeaffcae8c9f2a4c4da193967e3Mark Salyzyn // Check ANDROID_LOG_WRAP_DEFAULT_TIMEOUT value for match to 2 hours 33441ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn " --wrap Sleep for 2 hours or when buffer about to wrap whichever\n" 33541ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn " comes first. Improves efficiency of polling by providing\n" 33641ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn " an about-to-wrap wakeup.\n"); 337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"\nfilterspecs are a series of \n" 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " <tag>[:priority]\n\n" 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "where <tag> is a log component tag (or * for all) and priority is:\n" 341bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn " V Verbose (default for <tag>)\n" 342bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn " D Debug (default for '*')\n" 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " I Info\n" 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " W Warn\n" 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " E Error\n" 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " F Fatal\n" 347bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn " S Silent (suppress all output)\n" 348bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn "\n'*' by itself means '*:D' and <tag> by itself means <tag>:V.\n" 349bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn "If no '*' filterspec or -s on command line, all filter defaults to '*:V'.\n" 350bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn "eg: '*:S <tag>' prints only <tag>, '<tag>:S' suppresses all <tag> log messages.\n" 351bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn "\nIf not specified on the command line, filterspec is set from ANDROID_LOG_TAGS.\n" 352bba894af3f4260dcabfee902d4e3836a606da9b8Mark Salyzyn "\nIf not specified with -v on command line, format is set from ANDROID_PRINTF_LOG\n" 353649fc605f8094c06a38251466ccb15a722e8a91fMark Salyzyn "or defaults to \"threadtime\"\n\n"); 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int setLogFormat(const char * formatString) 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static AndroidLogPrintFormat format; 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project format = android_log_formatFromString(formatString); 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (format == FORMAT_OFF) { 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // FORMAT_OFF means invalid string 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367e1f2004ecc05ce2d5d4313d16c7791594643f2efMark Salyzyn return android_log_setPrintFormat(g_logformat, format); 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 370671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzynstatic const char multipliers[][2] = { 371671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn { "" }, 372671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn { "K" }, 373671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn { "M" }, 374671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn { "G" } 375671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn}; 376671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn 377671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzynstatic unsigned long value_of_size(unsigned long value) 378671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn{ 379671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn for (unsigned i = 0; 380671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn (i < sizeof(multipliers)/sizeof(multipliers[0])) && (value >= 1024); 381671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn value /= 1024, ++i) ; 382671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn return value; 383671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn} 384671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn 385671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzynstatic const char *multiplier_of_size(unsigned long value) 386671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn{ 387671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn unsigned i; 388671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn for (i = 0; 389671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn (i < sizeof(multipliers)/sizeof(multipliers[0])) && (value >= 1024); 390671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn value /= 1024, ++i) ; 391671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn return multipliers[i]; 392671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn} 393671e343c7d9c832eca093325c0b8b934c47a83b4Mark Salyzyn 3945976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau/*String to unsigned int, returns -1 if it fails*/ 3955976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiaustatic bool getSizeTArg(char *ptr, size_t *val, size_t min = 0, 3965976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau size_t max = SIZE_MAX) 3975976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau{ 398562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen if (!ptr) { 399562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen return false; 400562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen } 401562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen 4025976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau char *endp; 4035976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau errno = 0; 404562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen size_t ret = (size_t)strtoll(ptr, &endp, 0); 4055976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 406562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen if (endp[0] || errno) { 4075976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return false; 4085976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 4095976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 410562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen if ((ret > max) || (ret < min)) { 4115976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return false; 4125976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 4135976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 4145976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau *val = ret; 4155976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return true; 4165976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau} 4175976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 4185976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiaustatic void logcat_panic(bool showHelp, const char *fmt, ...) 4195976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau{ 42077d7e81c1c06fe47b07c3252cb21de86dbaedcd5Mark Salyzyn va_list args; 42177d7e81c1c06fe47b07c3252cb21de86dbaedcd5Mark Salyzyn va_start(args, fmt); 42277d7e81c1c06fe47b07c3252cb21de86dbaedcd5Mark Salyzyn vfprintf(stderr, fmt, args); 42377d7e81c1c06fe47b07c3252cb21de86dbaedcd5Mark Salyzyn va_end(args); 4245976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 4255976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (showHelp) { 4265976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau show_help(getprogname()); 4275976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 4285976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 4295976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau exit(EXIT_FAILURE); 4305976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau} 4315976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 432f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzynstatic char *parseTime(log_time &t, const char *cp) { 433f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn 434f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn char *ep = t.strptime(cp, "%m-%d %H:%M:%S.%q"); 435f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn if (ep) { 436f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn return ep; 437f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn } 4384cbed02e440dc400668fbdfb8ce4a710e5caebe5Mark Salyzyn ep = t.strptime(cp, "%Y-%m-%d %H:%M:%S.%q"); 4394cbed02e440dc400668fbdfb8ce4a710e5caebe5Mark Salyzyn if (ep) { 4404cbed02e440dc400668fbdfb8ce4a710e5caebe5Mark Salyzyn return ep; 4414cbed02e440dc400668fbdfb8ce4a710e5caebe5Mark Salyzyn } 4424cbed02e440dc400668fbdfb8ce4a710e5caebe5Mark Salyzyn return t.strptime(cp, "%s.%q"); 443f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn} 444f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn 445f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn// Find last logged line in gestalt of all matching existing output files 446f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzynstatic log_time lastLogTime(char *outputFileName) { 447f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn log_time retval(log_time::EPOCH); 448f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if (!outputFileName) { 449f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn return retval; 450f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 451f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn 452f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn std::string directory; 453f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn char *file = strrchr(outputFileName, '/'); 454f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if (!file) { 455f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn directory = "."; 456f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn file = outputFileName; 457f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } else { 458f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn *file = '\0'; 459f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn directory = outputFileName; 460f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn *file = '/'; 461f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn ++file; 462f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 4631ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn 4641ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn std::unique_ptr<DIR, int(*)(DIR*)> 4651ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn dir(opendir(directory.c_str()), closedir); 4661ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn if (!dir.get()) { 4671ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn return retval; 4681ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn } 4691ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn 4701ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn clockid_t clock_type = android_log_clockid(); 4711ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn log_time now(clock_type); 4721ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn bool monotonic = clock_type == CLOCK_MONOTONIC; 4731ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn 474f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn size_t len = strlen(file); 475f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn log_time modulo(0, NS_PER_SEC); 476f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn struct dirent *dp; 4771ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn 478f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn while ((dp = readdir(dir.get())) != NULL) { 479f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if ((dp->d_type != DT_REG) 480b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn // If we are using realtime, check all files that match the 481b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn // basename for latest time. If we are using monotonic time 482b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn // then only check the main file because time cycles on 483b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn // every reboot. 484b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn || strncmp(dp->d_name, file, len + monotonic) 485f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn || (dp->d_name[len] 486f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn && ((dp->d_name[len] != '.') 487f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn || !isdigit(dp->d_name[len+1])))) { 488f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn continue; 489f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 490f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn 491f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn std::string file_name = directory; 492f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn file_name += "/"; 493f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn file_name += dp->d_name; 494f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn std::string file; 495f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if (!android::base::ReadFileToString(file_name, &file)) { 496f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn continue; 497f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 498f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn 499f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn bool found = false; 500f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn for (const auto& line : android::base::Split(file, "\n")) { 501f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn log_time t(log_time::EPOCH); 502f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn char *ep = parseTime(t, line.c_str()); 503f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if (!ep || (*ep != ' ')) { 504f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn continue; 505f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 506f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // determine the time precision of the logs (eg: msec or usec) 507f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn for (unsigned long mod = 1UL; mod < modulo.tv_nsec; mod *= 10) { 508f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if (t.tv_nsec % (mod * 10)) { 509f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn modulo.tv_nsec = mod; 510f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn break; 511f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 512f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 513f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // We filter any times later than current as we may not have the 514f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // year stored with each log entry. Also, since it is possible for 515f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // entries to be recorded out of order (very rare) we select the 516f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // maximum we find just in case. 517f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if ((t < now) && (t > retval)) { 518f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn retval = t; 519f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn found = true; 520f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 521f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 522f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // We count on the basename file to be the definitive end, so stop here. 523f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if (!dp->d_name[len] && found) { 524f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn break; 525f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 526f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 527f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn if (retval == log_time::EPOCH) { 528f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn return retval; 529f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 530f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // tail_time prints matching or higher, round up by the modulo to prevent 531f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn // a replay of the last entry we have just checked. 532f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn retval += modulo; 533f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn return retval; 534f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn} 535f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn 5365976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau} /* namespace android */ 5375976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 5385976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 5396fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratoint main(int argc, char **argv) 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 5415976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau using namespace android; 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int hasSetLogFormat = 0; 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int clearLog = 0; 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int getLogSize = 0; 546dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn unsigned long setLogSize = 0; 547dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn int getPruneList = 0; 548dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn char *setPruneList = NULL; 54934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn int printStatistics = 0; 5502d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn int mode = ANDROID_LOG_RDONLY; 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *forceFilters = NULL; 5526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* devices = NULL; 5536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* dev; 5547b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn bool printDividers = false; 55595132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn struct logger_list *logger_list; 5565976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau size_t tail_lines = 0; 557fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn log_time tail_time(log_time::EPOCH); 558562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen size_t pid = 0; 5591164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin bool got_t = false; 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn signal(SIGPIPE, exit); 56265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_logformat = android_log_format_new(); 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 2 && 0 == strcmp(argv[1], "--help")) { 5665976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau show_help(argv[0]); 5675976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_SUCCESS; 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 573562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen int option_index = 0; 5743bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn // list of long-argument only strings for later comparison 575562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen static const char pid_str[] = "pid"; 57641ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn static const char wrap_str[] = "wrap"; 5773bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn static const char print_str[] = "print"; 578562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen static const struct option long_options[] = { 579f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "binary", no_argument, NULL, 'B' }, 580f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "buffer", required_argument, NULL, 'b' }, 5817ec59405ce1de7777e177654cf2f0fa4dc71656cMark Salyzyn { "buffer-size", optional_argument, NULL, 'g' }, 582f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "clear", no_argument, NULL, 'c' }, 583f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "dividers", no_argument, NULL, 'D' }, 584f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "file", required_argument, NULL, 'f' }, 585f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "format", required_argument, NULL, 'v' }, 5861ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn // hidden and undocumented reserved alias for --regex 5871ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn { "grep", required_argument, NULL, 'e' }, 5887ec59405ce1de7777e177654cf2f0fa4dc71656cMark Salyzyn // hidden and undocumented reserved alias for --max-count 5897ec59405ce1de7777e177654cf2f0fa4dc71656cMark Salyzyn { "head", required_argument, NULL, 'm' }, 590f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "last", no_argument, NULL, 'L' }, 5911164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin { "max-count", required_argument, NULL, 'm' }, 5921ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn { pid_str, required_argument, NULL, 0 }, 5933bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn { print_str, no_argument, NULL, 0 }, 594f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "prune", optional_argument, NULL, 'p' }, 5950f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin { "regex", required_argument, NULL, 'e' }, 5967ec59405ce1de7777e177654cf2f0fa4dc71656cMark Salyzyn { "rotate-count", required_argument, NULL, 'n' }, 5977ec59405ce1de7777e177654cf2f0fa4dc71656cMark Salyzyn { "rotate-kbytes", required_argument, NULL, 'r' }, 598f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn { "statistics", no_argument, NULL, 'S' }, 5997ec59405ce1de7777e177654cf2f0fa4dc71656cMark Salyzyn // hidden and undocumented reserved alias for -t 6007ec59405ce1de7777e177654cf2f0fa4dc71656cMark Salyzyn { "tail", required_argument, NULL, 't' }, 60141ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn // support, but ignore and do not document, the optional argument 60241ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn { wrap_str, optional_argument, NULL, 0 }, 603562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen { NULL, 0, NULL, 0 } 604562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen }; 605562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen 6061164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin ret = getopt_long(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:m:e:", 607562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen long_options, &option_index); 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < 0) { 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 613562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen switch (ret) { 614562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen case 0: 615562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen // One of the long options 616562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen if (long_options[option_index].name == pid_str) { 617562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen // ToDo: determine runtime PID_MAX? 618562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen if (!getSizeTArg(optarg, &pid, 1)) { 619562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen logcat_panic(true, "%s %s out of range\n", 620562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen long_options[option_index].name, optarg); 621562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen } 622562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen break; 623562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen } 62441ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn if (long_options[option_index].name == wrap_str) { 62541ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn mode |= ANDROID_LOG_WRAP | 62641ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn ANDROID_LOG_RDONLY | 62741ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn ANDROID_LOG_NONBLOCK; 62841ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn // ToDo: implement API that supports setting a wrap timeout 62941ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn size_t dummy = ANDROID_LOG_WRAP_DEFAULT_TIMEOUT; 63041ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn if (optarg && !getSizeTArg(optarg, &dummy, 1)) { 63141ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn logcat_panic(true, "%s %s out of range\n", 63241ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn long_options[option_index].name, optarg); 63341ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn } 63441ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn if (dummy != ANDROID_LOG_WRAP_DEFAULT_TIMEOUT) { 63541ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn fprintf(stderr, 63641ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn "WARNING: %s %u seconds, ignoring %zu\n", 63741ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn long_options[option_index].name, 63841ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn ANDROID_LOG_WRAP_DEFAULT_TIMEOUT, dummy); 63941ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn } 64041ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn break; 64141ba25f864380d5fe9e0f9a8c51dce17263807faMark Salyzyn } 6423bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn if (long_options[option_index].name == print_str) { 6433bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn g_printItAnyways = true; 6443bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn break; 6453bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn } 646562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen break; 647562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen 64895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn case 's': 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // default to all silent 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_log_addFilterRule(g_logformat, "*:s"); 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'c': 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clearLog = 1; 6552d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn mode |= ANDROID_LOG_WRONLY; 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6587c975ac3a471d4c7f6a7246558e5e9295118a97dMark Salyzyn case 'L': 6597c975ac3a471d4c7f6a7246558e5e9295118a97dMark Salyzyn mode |= ANDROID_LOG_PSTORE; 6607c975ac3a471d4c7f6a7246558e5e9295118a97dMark Salyzyn break; 6617c975ac3a471d4c7f6a7246558e5e9295118a97dMark Salyzyn 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'd': 6632d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn mode |= ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK; 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 666d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor case 't': 6671164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin got_t = true; 6682d3f38a6b8e724749b59d201a01b35fa0951141eMark Salyzyn mode |= ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK; 6695d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn /* FALLTHRU */ 6705d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn case 'T': 671fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn if (strspn(optarg, "0123456789") != strlen(optarg)) { 672f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn char *cp = parseTime(tail_time, optarg); 673fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn if (!cp) { 674f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn logcat_panic(false, "-%c \"%s\" not in time format\n", 675f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn ret, optarg); 676fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 677fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn if (*cp) { 678fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn char c = *cp; 679fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn *cp = '\0'; 680fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn fprintf(stderr, 681fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn "WARNING: -%c \"%s\"\"%c%s\" time truncated\n", 682fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn ret, optarg, c, cp + 1); 683fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn *cp = c; 684fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 685fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } else { 6865976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (!getSizeTArg(optarg, &tail_lines, 1)) { 687fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn fprintf(stderr, 688fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn "WARNING: -%c %s invalid, setting to 1\n", 689fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn ret, optarg); 690fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn tail_lines = 1; 691fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 692fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 693d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor break; 694d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor 6957b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn case 'D': 6967b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn printDividers = true; 6977b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn break; 6987b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn 6990f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin case 'e': 7000f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin g_regex = new pcrecpp::RE(optarg); 7010f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin break; 7020f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin 7031164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin case 'm': { 7041164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin char *end = NULL; 7051164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin if (!getSizeTArg(optarg, &g_maxCount)) { 7061164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin logcat_panic(false, "-%c \"%s\" isn't an " 7071164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin "integer greater than zero\n", ret, optarg); 7081164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin } 7091164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin } 7101164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin break; 7111164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'g': 713f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn if (!optarg) { 714f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn getLogSize = 1; 715f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn break; 716f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn } 717f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn // FALLTHRU 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 719dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'G': { 7205976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau char *cp; 7215976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (strtoll(optarg, &cp, 0) > 0) { 7225976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau setLogSize = strtoll(optarg, &cp, 0); 7235976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } else { 7245976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau setLogSize = 0; 725dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 726dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 727dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn switch(*cp) { 728dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'g': 729dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'G': 730dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn setLogSize *= 1024; 731dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn /* FALLTHRU */ 732dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'm': 733dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'M': 734dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn setLogSize *= 1024; 735dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn /* FALLTHRU */ 736dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'k': 737dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'K': 738dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn setLogSize *= 1024; 739dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn /* FALLTHRU */ 740dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case '\0': 741dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn break; 742dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 743dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn default: 744dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn setLogSize = 0; 745dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 746dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 747dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn if (!setLogSize) { 748dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn fprintf(stderr, "ERROR: -G <num><multiplier>\n"); 7495976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_FAILURE; 750dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 751dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 752dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn break; 753dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 754dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'p': 755f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn if (!optarg) { 756f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn getPruneList = 1; 757f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn break; 758f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn } 759f8bff87c65eeaa0a97ba904e8d815b07cc03c91eMark Salyzyn // FALLTHRU 760dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 761dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn case 'P': 762dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn setPruneList = optarg; 763dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn break; 764dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 7656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato case 'b': { 7667545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn unsigned idMask = 0; 7677545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn while ((optarg = strtok(optarg, ",:; \t\n\r\f")) != NULL) { 7687545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn if (strcmp(optarg, "default") == 0) { 7697545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn idMask |= (1 << LOG_ID_MAIN) | 7707545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn (1 << LOG_ID_SYSTEM) | 7717545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn (1 << LOG_ID_CRASH); 7727545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn } else if (strcmp(optarg, "all") == 0) { 7737545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn idMask = (unsigned)-1; 7747545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn } else { 7757545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn log_id_t log_id = android_name_to_log_id(optarg); 7767545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn const char *name = android_log_id_to_name(log_id); 7777545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn 7787545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn if (strcmp(name, optarg) != 0) { 7797545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn logcat_panic(true, "unknown buffer %s\n", optarg); 780083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 7817545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn idMask |= (1 << log_id); 78234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 7837545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn optarg = NULL; 784083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 78534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 7867545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { 7877545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn const char *name = android_log_id_to_name((log_id_t)i); 7887545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn log_id_t log_id = android_name_to_log_id(name); 789d0bd1b1b58a31c193889eef1b427e9fd3f77b782Mark Salyzyn 7907545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn if (log_id != (log_id_t)i) { 7917545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn continue; 7927545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn } 7937545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn if ((idMask & (1 << i)) == 0) { 7947545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn continue; 7957545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn } 796d0bd1b1b58a31c193889eef1b427e9fd3f77b782Mark Salyzyn 7977545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn bool found = false; 7987545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn for (dev = devices; dev; dev = dev->next) { 7997545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn if (!strcmp(name, dev->device)) { 8007545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn found = true; 801083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn break; 802083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 8037545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn if (!dev->next) { 8047545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn break; 80534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 80634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 8077545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn if (found) { 8087545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn continue; 8097545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn } 81034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 8117545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn bool binary = !strcmp(name, "events") || 8127545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn !strcmp(name, "security"); 8137545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn log_device_t* d = new log_device_t(name, binary); 8146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 815083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn if (dev) { 8167545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn dev->next = d; 8177545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn dev = d; 8187545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn } else { 8197545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn devices = dev = d; 820083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn } 8217545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn g_devCount++; 8226fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 8236fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'B': 8275976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau g_printBinary = 1; 828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'f': 8319812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn if ((tail_time == log_time::EPOCH) && (tail_lines == 0)) { 832f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn tail_time = lastLogTime(optarg); 833f3555d9427425c2cba9600ceffb49305c440aa4aMark Salyzyn } 834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // redirect output to a file 8355976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau g_outputFileName = optarg; 836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'r': 8395976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (!getSizeTArg(optarg, &g_logRotateSizeKBytes, 1)) { 8405976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, "Invalid parameter %s to -r\n", optarg); 841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'n': 8455976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (!getSizeTArg(optarg, &g_maxRotatedLogs, 1)) { 8465976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, "Invalid parameter %s to -n\n", optarg); 847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'v': 851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat (optarg); 852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 8535976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, "Invalid parameter %s to -v\n", optarg); 854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 855e1f2004ecc05ce2d5d4313d16c7791594643f2efMark Salyzyn hasSetLogFormat |= err; 856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'Q': 859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this is a *hidden* option used to start a version of logcat */ 860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* in an emulated device only. it basically looks for androidboot.logcat= */ 861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* on the kernel command line. If something is found, it extracts a log filter */ 862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* and uses it to run the program. If nothing is found, the program should */ 863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* quit immediately */ 864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define KERNEL_OPTION "androidboot.logcat=" 865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CONSOLE_OPTION "androidboot.console=" 866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* logcat; 869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* console; 870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int force_exit = 1; 871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static char cmdline[1024]; 872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n = read(fd, cmdline, sizeof(cmdline)-1 ); 876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n < 0) n = 0; 877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[n] = 0; 878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[0] = 0; 881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logcat = strstr( cmdline, KERNEL_OPTION ); 884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project console = strstr( cmdline, CONSOLE_OPTION ); 885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logcat != NULL) { 886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = logcat + sizeof(KERNEL_OPTION)-1;; 887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" );; 888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) 890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *q = 0; 891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project forceFilters = p; 893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project force_exit = 0; 894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if nothing found or invalid filters, exit quietly */ 8965976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (force_exit) { 8975976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_SUCCESS; 8985976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* redirect our output to the emulator console */ 901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (console) { 902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = console + sizeof(CONSOLE_OPTION)-1; 903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" ); 904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char devname[64]; 905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) { 908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = q - p; 909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(p); 911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = snprintf( devname, sizeof(devname), "/dev/%.*s", len, p ); 913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "logcat using %s (%d)\n", devname, len); 914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len < (int)sizeof(devname)) { 915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open( devname, O_WRONLY ); 916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 1); 918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 2); 919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 92634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn case 'S': 92734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn printStatistics = 1; 92834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn break; 92934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 9305976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau case ':': 9315976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, "Option -%c needs an argument\n", optopt); 9325976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau break; 9335976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau 934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 9355976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, "Unrecognized Option %c\n", optopt); 9365976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau break; 937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9401164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin if (g_maxCount && got_t) { 941df42ce4cf33faf800e6cef6d203bd9448a436dbdMark Salyzyn logcat_panic(true, "Cannot use -m (--max-count) and -t together\n"); 9421164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin } 9433bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn if (g_printItAnyways && (!g_regex || !g_maxCount)) { 9443bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn // One day it would be nice if --print -v color and --regex <expr> 9453bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn // could play with each other and show regex highlighted content. 9463bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn fprintf(stderr, "WARNING: " 9473bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn "--print ignored, to be used in combination with\n" 9483bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn " " 9493bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn "--regex <expr> and --max-count <N>\n"); 9503bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn g_printItAnyways = false; 9513bef8973aa12ad0cd1584d528191d1c2d47e2b3aMark Salyzyn } 9521164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin 9536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (!devices) { 9545f6738af4897f11d5a6674cffefdfcd2b46c5890Mark Salyzyn dev = devices = new log_device_t("main", false); 9555976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau g_devCount = 1; 95695132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (android_name_to_log_id("system") == LOG_ID_SYSTEM) { 9575f6738af4897f11d5a6674cffefdfcd2b46c5890Mark Salyzyn dev = dev->next = new log_device_t("system", false); 9585976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau g_devCount++; 959e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 96099f47a9e7c4374f2bbfc18e4a97aa7848245ea33Mark Salyzyn if (android_name_to_log_id("crash") == LOG_ID_CRASH) { 9615f6738af4897f11d5a6674cffefdfcd2b46c5890Mark Salyzyn dev = dev->next = new log_device_t("crash", false); 9625976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau g_devCount++; 963989980c55d9a11766b8698a97ce5eef3d8cfa286Mark Salyzyn } 9646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 9656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 9665976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (g_logRotateSizeKBytes != 0 && g_outputFileName == NULL) { 9675976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, "-r requires -f as well\n"); 968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9705976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau setupOutput(); 971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hasSetLogFormat == 0) { 973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* logFormat = getenv("ANDROID_PRINTF_LOG"); 974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logFormat != NULL) { 976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat(logFormat); 977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 97895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn fprintf(stderr, "invalid format in ANDROID_PRINTF_LOG '%s'\n", 979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logFormat); 980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 981649fc605f8094c06a38251466ccb15a722e8a91fMark Salyzyn } else { 982649fc605f8094c06a38251466ccb15a722e8a91fMark Salyzyn setLogFormat("threadtime"); 983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (forceFilters) { 987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, forceFilters); 988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 9895976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "Invalid filter expression in logcat args\n"); 990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (argc == optind) { 992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from environment variable 993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *env_tags_orig = getenv("ANDROID_LOG_TAGS"); 994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (env_tags_orig != NULL) { 996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, env_tags_orig); 997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (err < 0) { 9995976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, 10005976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau "Invalid filter expression in ANDROID_LOG_TAGS\n"); 1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from commandline 1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = optind ; i < argc ; i++) { 1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, argv[i]); 1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 100895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (err < 0) { 10095976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(true, "Invalid filter expression '%s'\n", argv[i]); 1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = devices; 1015fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn if (tail_time != log_time::EPOCH) { 1016562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen logger_list = android_logger_list_alloc_time(mode, tail_time, pid); 1017fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } else { 1018562e513d4b3860d3ec831a66817fa141ce17b77fKristian Monsen logger_list = android_logger_list_alloc(mode, tail_lines, pid); 1019fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 1020603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn const char *openDeviceFail = NULL; 1021603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn const char *clearFail = NULL; 1022603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn const char *setSizeFail = NULL; 1023603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn const char *getSizeFail = NULL; 1024603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn // We have three orthogonal actions below to clear, set log size and 1025603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn // get log size. All sharing the same iteration loop. 10266fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (dev) { 102795132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn dev->logger_list = logger_list; 102895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn dev->logger = android_logger_open(logger_list, 102995132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn android_name_to_log_id(dev->device)); 103095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (!dev->logger) { 1031603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn openDeviceFail = openDeviceFail ?: dev->device; 1032603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn dev = dev->next; 1033603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn continue; 1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (clearLog) { 1037c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn if (g_outputFileName) { 1038c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn int maxRotationCountDigits = 1039c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn (g_maxRotatedLogs > 0) ? (int) (floor(log10(g_maxRotatedLogs) + 1)) : 0; 1040c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn 1041c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn for (int i = g_maxRotatedLogs ; i >= 0 ; --i) { 1042c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn char *file; 1043c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn 1044c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn if (i == 0) { 1045c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn asprintf(&file, "%s", g_outputFileName); 1046c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn } else { 1047c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn asprintf(&file, "%s.%.*d", g_outputFileName, maxRotationCountDigits, i); 1048c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn } 1049c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn 1050c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn if (!file) { 1051c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn perror("while clearing log files"); 1052c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn clearFail = clearFail ?: dev->device; 1053c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn break; 1054c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn } 1055c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn 1056c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn err = unlink(file); 1057c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn 1058c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn if (err < 0 && errno != ENOENT && clearFail == NULL) { 1059c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn perror("while clearing log files"); 1060c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn clearFail = dev->device; 1061c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn } 1062c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn 1063c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn free(file); 1064c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn } 1065c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn } else if (android_logger_clear(dev->logger)) { 1066603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn clearFail = clearFail ?: dev->device; 10676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1070603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn if (setLogSize) { 1071603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn if (android_logger_set_log_size(dev->logger, setLogSize)) { 1072603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn setSizeFail = setSizeFail ?: dev->device; 1073603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn } 1074dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 1075dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 10766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 1077603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn long size = android_logger_get_log_size(dev->logger); 1078603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn long readable = android_logger_get_log_readable_size(dev->logger); 1079603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn 1080603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn if ((size < 0) || (readable < 0)) { 1081603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn getSizeFail = getSizeFail ?: dev->device; 1082603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn } else { 1083603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn printf("%s: ring buffer is %ld%sb (%ld%sb consumed), " 1084603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn "max entry is %db, max payload is %db\n", dev->device, 1085603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn value_of_size(size), multiplier_of_size(size), 1086603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn value_of_size(readable), multiplier_of_size(readable), 1087603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn (int) LOGGER_ENTRY_MAX_LEN, 1088603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn (int) LOGGER_ENTRY_MAX_PAYLOAD); 10896fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 10926fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = dev->next; 10936fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1094603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn // report any errors in the above loop and exit 1095603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn if (openDeviceFail) { 1096603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn logcat_panic(false, "Unable to open log device '%s'\n", openDeviceFail); 1097603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn } 1098603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn if (clearFail) { 1099603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn logcat_panic(false, "failed to clear the '%s' log\n", clearFail); 1100603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn } 1101603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn if (setSizeFail) { 1102603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn logcat_panic(false, "failed to set the '%s' log size\n", setSizeFail); 1103603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn } 1104603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn if (getSizeFail) { 1105603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn logcat_panic(false, "failed to get the readable '%s' log size", 1106603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn getSizeFail); 1107603b8e50c8e542b4c0e51ed742a714cb14e8dd9bMark Salyzyn } 11086fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 1109dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn if (setPruneList) { 11105976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau size_t len = strlen(setPruneList); 11115976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau /*extra 32 bytes are needed by android_logger_set_prune_list */ 11125976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau size_t bLen = len + 32; 11135976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau char *buf = NULL; 11145976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (asprintf(&buf, "%-*s", (int)(bLen - 1), setPruneList) > 0) { 11155976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau buf[len] = '\0'; 11165976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (android_logger_set_prune_list(logger_list, buf, bLen)) { 11175976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "failed to set the prune list"); 11185976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } 11195976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau free(buf); 11205976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau } else { 11215976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "failed to set the prune list (alloc)"); 1122dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 1123dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 1124dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn 11251c950479393d42d18829d4009dbdb3a7f03acbb7Mark Salyzyn if (printStatistics || getPruneList) { 112634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn size_t len = 8192; 112734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn char *buf; 112834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 1129083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn for (int retry = 32; 113034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn (retry >= 0) && ((buf = new char [len])); 11315976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau delete [] buf, buf = NULL, --retry) { 1132dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn if (getPruneList) { 1133dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn android_logger_get_prune_list(logger_list, buf, len); 1134dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } else { 1135dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn android_logger_get_statistics(logger_list, buf, len); 1136dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 113734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn buf[len-1] = '\0'; 11385976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (atol(buf) < 3) { 113934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn delete [] buf; 114034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn buf = NULL; 114134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn break; 114234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 11435976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau size_t ret = atol(buf) + 1; 11445976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (ret <= len) { 11455976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau len = ret; 114634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn break; 114734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 11485976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau len = ret; 114934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 115034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 115134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (!buf) { 11525976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "failed to read data"); 115334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 115434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 115534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn // remove trailing FF 115634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn char *cp = buf + len - 1; 115734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *cp = '\0'; 115834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn bool truncated = *--cp != '\f'; 115934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (!truncated) { 116034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *cp = '\0'; 116134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 116234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 116334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn // squash out the byte count 116434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn cp = buf; 116534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn if (!truncated) { 116622e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn while (isdigit(*cp)) { 116722e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn ++cp; 116822e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn } 116922e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn if (*cp == '\n') { 117034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn ++cp; 117134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 117234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 117334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 117434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn printf("%s", cp); 117534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn delete [] buf; 11765976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_SUCCESS; 117734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn } 117834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 117934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn 11806fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 11815976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_SUCCESS; 1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 1183dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn if (setLogSize || setPruneList) { 11845976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_SUCCESS; 1185dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7Mark Salyzyn } 1186e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (clearLog) { 11875976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_SUCCESS; 1188e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_INT(10, 12345); 1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_LONG(11, 0x1122334455667788LL); 1192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_STRING(0, "whassup, doc?"); 1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 11947b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn dev = NULL; 11955f6738af4897f11d5a6674cffefdfcd2b46c5890Mark Salyzyn log_device_t unexpected("unexpected", false); 11961164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin 1197df42ce4cf33faf800e6cef6d203bd9448a436dbdMark Salyzyn while (!g_maxCount || (g_printCount < g_maxCount)) { 119895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn struct log_msg log_msg; 11997b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn log_device_t* d; 120095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn int ret = android_logger_list_read(logger_list, &log_msg); 120195132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn 120295132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (ret == 0) { 12035976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "read: unexpected EOF!\n"); 120495132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 120595132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn 120695132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (ret < 0) { 120795132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (ret == -EAGAIN) { 120895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn break; 120995132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 121095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn 121195132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (ret == -EIO) { 12125976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "read: unexpected EOF!\n"); 121395132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 121495132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn if (ret == -EINVAL) { 12155976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "read: unexpected length.\n"); 121695132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 12175976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau logcat_panic(false, "logcat read failure"); 121895132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 121995132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn 1220083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn for (d = devices; d; d = d->next) { 12217b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn if (android_name_to_log_id(d->device) == log_msg.id()) { 122295132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn break; 122395132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 122495132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 12257b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn if (!d) { 12265976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau g_devCount = 2; // set to Multiple 12279421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn d = &unexpected; 12289421b0c0600030f84c81b05e708e2d7b1a3f9b1cMark Salyzyn d->binary = log_msg.id() == LOG_ID_EVENTS; 122995132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 123095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn 12317b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn if (dev != d) { 12327b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn dev = d; 12335976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau maybePrintStart(dev, printDividers); 12347b30ff8d8768241af0e036e4d9296d07b2dde66aMark Salyzyn } 12355976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau if (g_printBinary) { 12365976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau printBinary(&log_msg); 123795132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } else { 12385976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau processBuffer(dev, &log_msg); 123995132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 124095132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn } 124195132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn 124295132e97e57b055c5103619ce2487d07f30e63dbMark Salyzyn android_logger_list_free(logger_list); 1243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 12445976303aa6e55a9e81eadb35d50f458052e3fa24Traian Schiau return EXIT_SUCCESS; 1245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 1246