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(&param, 0, sizeof(param));
2473ef730c57f88ac24b0d6b021e43fc344d602fe36Mark Salyzyn        if (sched_setscheduler((pid_t) 0, SCHED_BATCH, &param) < 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