Loading logcat/logcat.cpp +153 −133 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <signal.h> #include <time.h> #include <unistd.h> #include <sys/cdefs.h> #include <sys/socket.h> #include <sys/stat.h> #include <arpa/inet.h> Loading @@ -24,7 +25,6 @@ #include <log/logprint.h> #include <log/event_tag_map.h> #define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16 #define DEFAULT_MAX_ROTATED_LOGS 4 static AndroidLogFormat * g_logformat; Loading @@ -46,6 +46,8 @@ struct log_device_t { binary = b; next = NULL; printed = false; logger = NULL; logger_list = NULL; } }; Loading @@ -54,13 +56,17 @@ namespace android { /* Global Variables */ static const char * g_outputFileName = NULL; static int g_logRotateSizeKBytes = 0; // 0 means "no log rotation" static int g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded" // 0 means "no log rotation" static size_t g_logRotateSizeKBytes = 0; // 0 means "unbounded" static size_t g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; static int g_outFD = -1; static off_t g_outByteCount = 0; static size_t g_outByteCount = 0; static int g_printBinary = 0; static int g_devCount = 0; // >1 means multiple __noreturn static void logcat_panic(bool showHelp, const char *fmt, ...) __printflike(2,3); static int openLogFile (const char *pathname) { return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); Loading Loading @@ -93,6 +99,11 @@ static void rotateLogs() asprintf(&file0, "%s.%.*d", g_outputFileName, maxRotationCountDigits, i - 1); } if (!file0 || !file1) { perror("while rotating log files"); break; } err = rename(file0, file1); if (err < 0 && errno != ENOENT) { Loading @@ -106,8 +117,7 @@ static void rotateLogs() g_outFD = openLogFile(g_outputFileName); if (g_outFD < 0) { perror ("couldn't open output file"); exit(-1); logcat_panic(false, "couldn't open output file"); } g_outByteCount = 0; Loading Loading @@ -153,8 +163,7 @@ static void processBuffer(log_device_t* dev, struct log_msg *buf) bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry); if (bytesWritten < 0) { perror("output error"); exit(-1); logcat_panic(false, "output error"); } } Loading @@ -179,8 +188,7 @@ static void maybePrintStart(log_device_t* dev, bool printDividers) { dev->printed ? "switch to" : "beginning of", dev->device); if (write(g_outFD, buf, strlen(buf)) < 0) { perror("output error"); exit(-1); logcat_panic(false, "output error"); } } dev->printed = true; Loading @@ -199,11 +207,18 @@ static void setupOutput() g_outFD = openLogFile (g_outputFileName); if (g_outFD < 0) { perror ("couldn't open output file"); exit(-1); logcat_panic(false, "couldn't open output file"); } if (fstat(g_outFD, &statbuf) == -1) { close(g_outFD); logcat_panic(false, "couldn't get output file stat\n"); } fstat(g_outFD, &statbuf); if ((size_t) statbuf.st_size > SIZE_MAX || statbuf.st_size < 0) { close(g_outFD); logcat_panic(false, "invalid output file stat\n"); } g_outByteCount = statbuf.st_size; } Loading @@ -217,7 +232,7 @@ static void show_help(const char *cmd) " -s Set default filter to silent.\n" " Like specifying filterspec '*:S'\n" " -f <filename> Log to file. Default to stdout\n" " -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n" " -r <kbytes> Rotate log every kbytes. Requires -f\n" " -n <count> Sets max number of rotated logs to <count>, default 4\n" " -v <format> Sets the log print format, where <format> is:\n\n" " brief color long process raw tag thread threadtime time\n\n" Loading Loading @@ -265,9 +280,6 @@ static void show_help(const char *cmd) "or defaults to \"threadtime\"\n\n"); } } /* namespace android */ static int setLogFormat(const char * formatString) { static AndroidLogPrintFormat format; Loading Loading @@ -308,8 +320,48 @@ static const char *multiplier_of_size(unsigned long value) return multipliers[i]; } /*String to unsigned int, returns -1 if it fails*/ static bool getSizeTArg(char *ptr, size_t *val, size_t min = 0, size_t max = SIZE_MAX) { char *endp; errno = 0; size_t ret = (size_t) strtoll(ptr, &endp, 0); if (endp[0] != '\0' || errno != 0 ) { return false; } if (ret > max || ret < min) { return false; } *val = ret; return true; } static void logcat_panic(bool showHelp, const char *fmt, ...) { if (fmt) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); } if (showHelp) { show_help(getprogname()); } exit(EXIT_FAILURE); } } /* namespace android */ int main(int argc, char **argv) { using namespace android; int err; int hasSetLogFormat = 0; int clearLog = 0; Loading @@ -324,7 +376,7 @@ int main(int argc, char **argv) log_device_t* dev; bool printDividers = false; struct logger_list *logger_list; unsigned int tail_lines = 0; size_t tail_lines = 0; log_time tail_time(log_time::EPOCH); signal(SIGPIPE, exit); Loading @@ -332,14 +384,14 @@ int main(int argc, char **argv) g_logformat = android_log_format_new(); if (argc == 2 && 0 == strcmp(argv[1], "--help")) { android::show_help(argv[0]); exit(0); show_help(argv[0]); return EXIT_SUCCESS; } for (;;) { int ret; ret = getopt(argc, argv, "cdDLt:T:gG:sQf:r:n:v:b:BSpP:"); ret = getopt(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:"); if (ret < 0) { break; Loading Loading @@ -372,10 +424,9 @@ int main(int argc, char **argv) char *cp = tail_time.strptime(optarg, log_time::default_format); if (!cp) { fprintf(stderr, "ERROR: -%c \"%s\" not in \"%s\" time format\n", logcat_panic(false, "-%c \"%s\" not in \"%s\" time format\n", ret, optarg, log_time::default_format); exit(1); } if (*cp) { char c = *cp; Loading @@ -386,8 +437,7 @@ int main(int argc, char **argv) *cp = c; } } else { tail_lines = atoi(optarg); if (!tail_lines) { if (!getSizeTArg(optarg, &tail_lines, 1)) { fprintf(stderr, "WARNING: -%c %s invalid, setting to 1\n", ret, optarg); Loading @@ -405,13 +455,11 @@ int main(int argc, char **argv) break; case 'G': { // would use atol if not for the multiplier char *cp = optarg; char *cp; if (strtoll(optarg, &cp, 0) > 0) { setLogSize = strtoll(optarg, &cp, 0); } else { setLogSize = 0; while (('0' <= *cp) && (*cp <= '9')) { setLogSize *= 10; setLogSize += *cp - '0'; ++cp; } switch(*cp) { Loading @@ -436,7 +484,7 @@ int main(int argc, char **argv) if (!setLogSize) { fprintf(stderr, "ERROR: -G <num><multiplier>\n"); exit(1); return EXIT_FAILURE; } } break; Loading @@ -458,7 +506,7 @@ int main(int argc, char **argv) } devices = dev = NULL; android::g_devCount = 0; g_devCount = 0; for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { const char *name = android_log_id_to_name((log_id_t)i); log_id_t log_id = android_name_to_log_id(name); Loading @@ -476,7 +524,7 @@ int main(int argc, char **argv) } else { devices = dev = d; } android::g_devCount++; g_devCount++; } break; } Loading @@ -492,51 +540,36 @@ int main(int argc, char **argv) } else { devices = new log_device_t(optarg, binary); } android::g_devCount++; g_devCount++; } break; case 'B': android::g_printBinary = 1; g_printBinary = 1; break; case 'f': // redirect output to a file android::g_outputFileName = optarg; g_outputFileName = optarg; break; case 'r': if (optarg == NULL) { android::g_logRotateSizeKBytes = DEFAULT_LOG_ROTATE_SIZE_KBYTES; } else { if (!isdigit(optarg[0])) { fprintf(stderr,"Invalid parameter to -r\n"); android::show_help(argv[0]); exit(-1); } android::g_logRotateSizeKBytes = atoi(optarg); if (!getSizeTArg(optarg, &g_logRotateSizeKBytes, 1)) { logcat_panic(true, "Invalid parameter %s to -r\n", optarg); } break; case 'n': if (!isdigit(optarg[0])) { fprintf(stderr,"Invalid parameter to -r\n"); android::show_help(argv[0]); exit(-1); if (!getSizeTArg(optarg, &g_maxRotatedLogs, 1)) { logcat_panic(true, "Invalid parameter %s to -n\n", optarg); } android::g_maxRotatedLogs = atoi(optarg); break; case 'v': err = setLogFormat (optarg); if (err < 0) { fprintf(stderr,"Invalid parameter to -v\n"); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Invalid parameter %s to -v\n", optarg); } if (strcmp("color", optarg)) { // exception for modifiers Loading Loading @@ -582,8 +615,9 @@ int main(int argc, char **argv) force_exit = 0; } /* if nothing found or invalid filters, exit quietly */ if (force_exit) exit(0); if (force_exit) { return EXIT_SUCCESS; } /* redirect our output to the emulator console */ if (console) { Loading Loading @@ -615,36 +649,34 @@ int main(int argc, char **argv) printStatistics = 1; break; case ':': logcat_panic(true, "Option -%c needs an argument\n", optopt); break; default: fprintf(stderr,"Unrecognized Option\n"); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Unrecognized Option %c\n", optopt); break; } } if (!devices) { dev = devices = new log_device_t("main", false); android::g_devCount = 1; g_devCount = 1; if (android_name_to_log_id("system") == LOG_ID_SYSTEM) { dev = dev->next = new log_device_t("system", false); android::g_devCount++; g_devCount++; } if (android_name_to_log_id("crash") == LOG_ID_CRASH) { dev = dev->next = new log_device_t("crash", false); android::g_devCount++; g_devCount++; } } if (android::g_logRotateSizeKBytes != 0 && android::g_outputFileName == NULL ) { fprintf(stderr,"-r requires -f as well\n"); android::show_help(argv[0]); exit(-1); if (g_logRotateSizeKBytes != 0 && g_outputFileName == NULL) { logcat_panic(true, "-r requires -f as well\n"); } android::setupOutput(); setupOutput(); if (hasSetLogFormat == 0) { const char* logFormat = getenv("ANDROID_PRINTF_LOG"); Loading @@ -663,8 +695,7 @@ int main(int argc, char **argv) if (forceFilters) { err = android_log_addFilterString(g_logformat, forceFilters); if (err < 0) { fprintf (stderr, "Invalid filter expression in -logcat option\n"); exit(0); logcat_panic(false, "Invalid filter expression in logcat args\n"); } } else if (argc == optind) { // Add from environment variable Loading @@ -674,10 +705,8 @@ int main(int argc, char **argv) err = android_log_addFilterString(g_logformat, env_tags_orig); if (err < 0) { fprintf(stderr, "Invalid filter expression in" " ANDROID_LOG_TAGS\n"); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Invalid filter expression in ANDROID_LOG_TAGS\n"); } } } else { Loading @@ -686,9 +715,7 @@ int main(int argc, char **argv) err = android_log_addFilterString(g_logformat, argv[i]); if (err < 0) { fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Invalid filter expression '%s'\n", argv[i]); } } } Loading @@ -704,22 +731,20 @@ int main(int argc, char **argv) dev->logger = android_logger_open(logger_list, android_name_to_log_id(dev->device)); if (!dev->logger) { fprintf(stderr, "Unable to open log device '%s'\n", dev->device); exit(EXIT_FAILURE); logcat_panic(false, "Unable to open log device '%s'\n", dev->device); } if (clearLog) { int ret; ret = android_logger_clear(dev->logger); if (ret) { perror("failed to clear the log"); exit(EXIT_FAILURE); logcat_panic(false, "failed to clear the log"); } } if (setLogSize && android_logger_set_log_size(dev->logger, setLogSize)) { perror("failed to set the log size"); exit(EXIT_FAILURE); logcat_panic(false, "failed to set the log size"); } if (getLogSize) { Loading @@ -727,14 +752,12 @@ int main(int argc, char **argv) size = android_logger_get_log_size(dev->logger); if (size < 0) { perror("failed to get the log size"); exit(EXIT_FAILURE); logcat_panic(false, "failed to get the log size"); } readable = android_logger_get_log_readable_size(dev->logger); if (readable < 0) { perror("failed to get the readable log size"); exit(EXIT_FAILURE); logcat_panic(false, "failed to get the readable log size"); } printf("%s: ring buffer is %ld%sb (%ld%sb consumed), " Loading @@ -748,16 +771,18 @@ int main(int argc, char **argv) } if (setPruneList) { size_t len = strlen(setPruneList) + 32; // margin to allow rc char *buf = (char *) malloc(len); strcpy(buf, setPruneList); int ret = android_logger_set_prune_list(logger_list, buf, len); size_t len = strlen(setPruneList); /*extra 32 bytes are needed by android_logger_set_prune_list */ size_t bLen = len + 32; char *buf = NULL; if (asprintf(&buf, "%-*s", (int)(bLen - 1), setPruneList) > 0) { buf[len] = '\0'; if (android_logger_set_prune_list(logger_list, buf, bLen)) { logcat_panic(false, "failed to set the prune list"); } free(buf); if (ret) { perror("failed to set the prune list"); exit(EXIT_FAILURE); } else { logcat_panic(false, "failed to set the prune list (alloc)"); } } Loading @@ -767,29 +792,28 @@ int main(int argc, char **argv) for(int retry = 32; (retry >= 0) && ((buf = new char [len])); delete [] buf, --retry) { delete [] buf, buf = NULL, --retry) { if (getPruneList) { android_logger_get_prune_list(logger_list, buf, len); } else { android_logger_get_statistics(logger_list, buf, len); } buf[len-1] = '\0'; size_t ret = atol(buf) + 1; if (ret < 4) { if (atol(buf) < 3) { delete [] buf; buf = NULL; break; } bool check = ret <= len; size_t ret = atol(buf) + 1; if (ret <= len) { len = ret; if (check) { break; } len = ret; } if (!buf) { perror("failed to read data"); exit(EXIT_FAILURE); logcat_panic(false, "failed to read data"); } // remove trailing FF Loading @@ -813,18 +837,18 @@ int main(int argc, char **argv) printf("%s", cp); delete [] buf; exit(0); return EXIT_SUCCESS; } if (getLogSize) { exit(0); return EXIT_SUCCESS; } if (setLogSize || setPruneList) { exit(0); return EXIT_SUCCESS; } if (clearLog) { exit(0); return EXIT_SUCCESS; } //LOG_EVENT_INT(10, 12345); Loading @@ -839,8 +863,7 @@ int main(int argc, char **argv) int ret = android_logger_list_read(logger_list, &log_msg); if (ret == 0) { fprintf(stderr, "read: unexpected EOF!\n"); exit(EXIT_FAILURE); logcat_panic(false, "read: unexpected EOF!\n"); } if (ret < 0) { Loading @@ -849,15 +872,12 @@ int main(int argc, char **argv) } if (ret == -EIO) { fprintf(stderr, "read: unexpected EOF!\n"); exit(EXIT_FAILURE); logcat_panic(false, "read: unexpected EOF!\n"); } if (ret == -EINVAL) { fprintf(stderr, "read: unexpected length.\n"); exit(EXIT_FAILURE); logcat_panic(false, "read: unexpected length.\n"); } perror("logcat read failure"); exit(EXIT_FAILURE); logcat_panic(false, "logcat read failure"); } for(d = devices; d; d = d->next) { Loading @@ -866,23 +886,23 @@ int main(int argc, char **argv) } } if (!d) { android::g_devCount = 2; // set to Multiple g_devCount = 2; // set to Multiple d = &unexpected; d->binary = log_msg.id() == LOG_ID_EVENTS; } if (dev != d) { dev = d; android::maybePrintStart(dev, printDividers); maybePrintStart(dev, printDividers); } if (android::g_printBinary) { android::printBinary(&log_msg); if (g_printBinary) { printBinary(&log_msg); } else { android::processBuffer(dev, &log_msg); processBuffer(dev, &log_msg); } } android_logger_list_free(logger_list); return 0; return EXIT_SUCCESS; } Loading
logcat/logcat.cpp +153 −133 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <signal.h> #include <time.h> #include <unistd.h> #include <sys/cdefs.h> #include <sys/socket.h> #include <sys/stat.h> #include <arpa/inet.h> Loading @@ -24,7 +25,6 @@ #include <log/logprint.h> #include <log/event_tag_map.h> #define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16 #define DEFAULT_MAX_ROTATED_LOGS 4 static AndroidLogFormat * g_logformat; Loading @@ -46,6 +46,8 @@ struct log_device_t { binary = b; next = NULL; printed = false; logger = NULL; logger_list = NULL; } }; Loading @@ -54,13 +56,17 @@ namespace android { /* Global Variables */ static const char * g_outputFileName = NULL; static int g_logRotateSizeKBytes = 0; // 0 means "no log rotation" static int g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded" // 0 means "no log rotation" static size_t g_logRotateSizeKBytes = 0; // 0 means "unbounded" static size_t g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; static int g_outFD = -1; static off_t g_outByteCount = 0; static size_t g_outByteCount = 0; static int g_printBinary = 0; static int g_devCount = 0; // >1 means multiple __noreturn static void logcat_panic(bool showHelp, const char *fmt, ...) __printflike(2,3); static int openLogFile (const char *pathname) { return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); Loading Loading @@ -93,6 +99,11 @@ static void rotateLogs() asprintf(&file0, "%s.%.*d", g_outputFileName, maxRotationCountDigits, i - 1); } if (!file0 || !file1) { perror("while rotating log files"); break; } err = rename(file0, file1); if (err < 0 && errno != ENOENT) { Loading @@ -106,8 +117,7 @@ static void rotateLogs() g_outFD = openLogFile(g_outputFileName); if (g_outFD < 0) { perror ("couldn't open output file"); exit(-1); logcat_panic(false, "couldn't open output file"); } g_outByteCount = 0; Loading Loading @@ -153,8 +163,7 @@ static void processBuffer(log_device_t* dev, struct log_msg *buf) bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry); if (bytesWritten < 0) { perror("output error"); exit(-1); logcat_panic(false, "output error"); } } Loading @@ -179,8 +188,7 @@ static void maybePrintStart(log_device_t* dev, bool printDividers) { dev->printed ? "switch to" : "beginning of", dev->device); if (write(g_outFD, buf, strlen(buf)) < 0) { perror("output error"); exit(-1); logcat_panic(false, "output error"); } } dev->printed = true; Loading @@ -199,11 +207,18 @@ static void setupOutput() g_outFD = openLogFile (g_outputFileName); if (g_outFD < 0) { perror ("couldn't open output file"); exit(-1); logcat_panic(false, "couldn't open output file"); } if (fstat(g_outFD, &statbuf) == -1) { close(g_outFD); logcat_panic(false, "couldn't get output file stat\n"); } fstat(g_outFD, &statbuf); if ((size_t) statbuf.st_size > SIZE_MAX || statbuf.st_size < 0) { close(g_outFD); logcat_panic(false, "invalid output file stat\n"); } g_outByteCount = statbuf.st_size; } Loading @@ -217,7 +232,7 @@ static void show_help(const char *cmd) " -s Set default filter to silent.\n" " Like specifying filterspec '*:S'\n" " -f <filename> Log to file. Default to stdout\n" " -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n" " -r <kbytes> Rotate log every kbytes. Requires -f\n" " -n <count> Sets max number of rotated logs to <count>, default 4\n" " -v <format> Sets the log print format, where <format> is:\n\n" " brief color long process raw tag thread threadtime time\n\n" Loading Loading @@ -265,9 +280,6 @@ static void show_help(const char *cmd) "or defaults to \"threadtime\"\n\n"); } } /* namespace android */ static int setLogFormat(const char * formatString) { static AndroidLogPrintFormat format; Loading Loading @@ -308,8 +320,48 @@ static const char *multiplier_of_size(unsigned long value) return multipliers[i]; } /*String to unsigned int, returns -1 if it fails*/ static bool getSizeTArg(char *ptr, size_t *val, size_t min = 0, size_t max = SIZE_MAX) { char *endp; errno = 0; size_t ret = (size_t) strtoll(ptr, &endp, 0); if (endp[0] != '\0' || errno != 0 ) { return false; } if (ret > max || ret < min) { return false; } *val = ret; return true; } static void logcat_panic(bool showHelp, const char *fmt, ...) { if (fmt) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); } if (showHelp) { show_help(getprogname()); } exit(EXIT_FAILURE); } } /* namespace android */ int main(int argc, char **argv) { using namespace android; int err; int hasSetLogFormat = 0; int clearLog = 0; Loading @@ -324,7 +376,7 @@ int main(int argc, char **argv) log_device_t* dev; bool printDividers = false; struct logger_list *logger_list; unsigned int tail_lines = 0; size_t tail_lines = 0; log_time tail_time(log_time::EPOCH); signal(SIGPIPE, exit); Loading @@ -332,14 +384,14 @@ int main(int argc, char **argv) g_logformat = android_log_format_new(); if (argc == 2 && 0 == strcmp(argv[1], "--help")) { android::show_help(argv[0]); exit(0); show_help(argv[0]); return EXIT_SUCCESS; } for (;;) { int ret; ret = getopt(argc, argv, "cdDLt:T:gG:sQf:r:n:v:b:BSpP:"); ret = getopt(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:"); if (ret < 0) { break; Loading Loading @@ -372,10 +424,9 @@ int main(int argc, char **argv) char *cp = tail_time.strptime(optarg, log_time::default_format); if (!cp) { fprintf(stderr, "ERROR: -%c \"%s\" not in \"%s\" time format\n", logcat_panic(false, "-%c \"%s\" not in \"%s\" time format\n", ret, optarg, log_time::default_format); exit(1); } if (*cp) { char c = *cp; Loading @@ -386,8 +437,7 @@ int main(int argc, char **argv) *cp = c; } } else { tail_lines = atoi(optarg); if (!tail_lines) { if (!getSizeTArg(optarg, &tail_lines, 1)) { fprintf(stderr, "WARNING: -%c %s invalid, setting to 1\n", ret, optarg); Loading @@ -405,13 +455,11 @@ int main(int argc, char **argv) break; case 'G': { // would use atol if not for the multiplier char *cp = optarg; char *cp; if (strtoll(optarg, &cp, 0) > 0) { setLogSize = strtoll(optarg, &cp, 0); } else { setLogSize = 0; while (('0' <= *cp) && (*cp <= '9')) { setLogSize *= 10; setLogSize += *cp - '0'; ++cp; } switch(*cp) { Loading @@ -436,7 +484,7 @@ int main(int argc, char **argv) if (!setLogSize) { fprintf(stderr, "ERROR: -G <num><multiplier>\n"); exit(1); return EXIT_FAILURE; } } break; Loading @@ -458,7 +506,7 @@ int main(int argc, char **argv) } devices = dev = NULL; android::g_devCount = 0; g_devCount = 0; for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { const char *name = android_log_id_to_name((log_id_t)i); log_id_t log_id = android_name_to_log_id(name); Loading @@ -476,7 +524,7 @@ int main(int argc, char **argv) } else { devices = dev = d; } android::g_devCount++; g_devCount++; } break; } Loading @@ -492,51 +540,36 @@ int main(int argc, char **argv) } else { devices = new log_device_t(optarg, binary); } android::g_devCount++; g_devCount++; } break; case 'B': android::g_printBinary = 1; g_printBinary = 1; break; case 'f': // redirect output to a file android::g_outputFileName = optarg; g_outputFileName = optarg; break; case 'r': if (optarg == NULL) { android::g_logRotateSizeKBytes = DEFAULT_LOG_ROTATE_SIZE_KBYTES; } else { if (!isdigit(optarg[0])) { fprintf(stderr,"Invalid parameter to -r\n"); android::show_help(argv[0]); exit(-1); } android::g_logRotateSizeKBytes = atoi(optarg); if (!getSizeTArg(optarg, &g_logRotateSizeKBytes, 1)) { logcat_panic(true, "Invalid parameter %s to -r\n", optarg); } break; case 'n': if (!isdigit(optarg[0])) { fprintf(stderr,"Invalid parameter to -r\n"); android::show_help(argv[0]); exit(-1); if (!getSizeTArg(optarg, &g_maxRotatedLogs, 1)) { logcat_panic(true, "Invalid parameter %s to -n\n", optarg); } android::g_maxRotatedLogs = atoi(optarg); break; case 'v': err = setLogFormat (optarg); if (err < 0) { fprintf(stderr,"Invalid parameter to -v\n"); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Invalid parameter %s to -v\n", optarg); } if (strcmp("color", optarg)) { // exception for modifiers Loading Loading @@ -582,8 +615,9 @@ int main(int argc, char **argv) force_exit = 0; } /* if nothing found or invalid filters, exit quietly */ if (force_exit) exit(0); if (force_exit) { return EXIT_SUCCESS; } /* redirect our output to the emulator console */ if (console) { Loading Loading @@ -615,36 +649,34 @@ int main(int argc, char **argv) printStatistics = 1; break; case ':': logcat_panic(true, "Option -%c needs an argument\n", optopt); break; default: fprintf(stderr,"Unrecognized Option\n"); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Unrecognized Option %c\n", optopt); break; } } if (!devices) { dev = devices = new log_device_t("main", false); android::g_devCount = 1; g_devCount = 1; if (android_name_to_log_id("system") == LOG_ID_SYSTEM) { dev = dev->next = new log_device_t("system", false); android::g_devCount++; g_devCount++; } if (android_name_to_log_id("crash") == LOG_ID_CRASH) { dev = dev->next = new log_device_t("crash", false); android::g_devCount++; g_devCount++; } } if (android::g_logRotateSizeKBytes != 0 && android::g_outputFileName == NULL ) { fprintf(stderr,"-r requires -f as well\n"); android::show_help(argv[0]); exit(-1); if (g_logRotateSizeKBytes != 0 && g_outputFileName == NULL) { logcat_panic(true, "-r requires -f as well\n"); } android::setupOutput(); setupOutput(); if (hasSetLogFormat == 0) { const char* logFormat = getenv("ANDROID_PRINTF_LOG"); Loading @@ -663,8 +695,7 @@ int main(int argc, char **argv) if (forceFilters) { err = android_log_addFilterString(g_logformat, forceFilters); if (err < 0) { fprintf (stderr, "Invalid filter expression in -logcat option\n"); exit(0); logcat_panic(false, "Invalid filter expression in logcat args\n"); } } else if (argc == optind) { // Add from environment variable Loading @@ -674,10 +705,8 @@ int main(int argc, char **argv) err = android_log_addFilterString(g_logformat, env_tags_orig); if (err < 0) { fprintf(stderr, "Invalid filter expression in" " ANDROID_LOG_TAGS\n"); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Invalid filter expression in ANDROID_LOG_TAGS\n"); } } } else { Loading @@ -686,9 +715,7 @@ int main(int argc, char **argv) err = android_log_addFilterString(g_logformat, argv[i]); if (err < 0) { fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]); android::show_help(argv[0]); exit(-1); logcat_panic(true, "Invalid filter expression '%s'\n", argv[i]); } } } Loading @@ -704,22 +731,20 @@ int main(int argc, char **argv) dev->logger = android_logger_open(logger_list, android_name_to_log_id(dev->device)); if (!dev->logger) { fprintf(stderr, "Unable to open log device '%s'\n", dev->device); exit(EXIT_FAILURE); logcat_panic(false, "Unable to open log device '%s'\n", dev->device); } if (clearLog) { int ret; ret = android_logger_clear(dev->logger); if (ret) { perror("failed to clear the log"); exit(EXIT_FAILURE); logcat_panic(false, "failed to clear the log"); } } if (setLogSize && android_logger_set_log_size(dev->logger, setLogSize)) { perror("failed to set the log size"); exit(EXIT_FAILURE); logcat_panic(false, "failed to set the log size"); } if (getLogSize) { Loading @@ -727,14 +752,12 @@ int main(int argc, char **argv) size = android_logger_get_log_size(dev->logger); if (size < 0) { perror("failed to get the log size"); exit(EXIT_FAILURE); logcat_panic(false, "failed to get the log size"); } readable = android_logger_get_log_readable_size(dev->logger); if (readable < 0) { perror("failed to get the readable log size"); exit(EXIT_FAILURE); logcat_panic(false, "failed to get the readable log size"); } printf("%s: ring buffer is %ld%sb (%ld%sb consumed), " Loading @@ -748,16 +771,18 @@ int main(int argc, char **argv) } if (setPruneList) { size_t len = strlen(setPruneList) + 32; // margin to allow rc char *buf = (char *) malloc(len); strcpy(buf, setPruneList); int ret = android_logger_set_prune_list(logger_list, buf, len); size_t len = strlen(setPruneList); /*extra 32 bytes are needed by android_logger_set_prune_list */ size_t bLen = len + 32; char *buf = NULL; if (asprintf(&buf, "%-*s", (int)(bLen - 1), setPruneList) > 0) { buf[len] = '\0'; if (android_logger_set_prune_list(logger_list, buf, bLen)) { logcat_panic(false, "failed to set the prune list"); } free(buf); if (ret) { perror("failed to set the prune list"); exit(EXIT_FAILURE); } else { logcat_panic(false, "failed to set the prune list (alloc)"); } } Loading @@ -767,29 +792,28 @@ int main(int argc, char **argv) for(int retry = 32; (retry >= 0) && ((buf = new char [len])); delete [] buf, --retry) { delete [] buf, buf = NULL, --retry) { if (getPruneList) { android_logger_get_prune_list(logger_list, buf, len); } else { android_logger_get_statistics(logger_list, buf, len); } buf[len-1] = '\0'; size_t ret = atol(buf) + 1; if (ret < 4) { if (atol(buf) < 3) { delete [] buf; buf = NULL; break; } bool check = ret <= len; size_t ret = atol(buf) + 1; if (ret <= len) { len = ret; if (check) { break; } len = ret; } if (!buf) { perror("failed to read data"); exit(EXIT_FAILURE); logcat_panic(false, "failed to read data"); } // remove trailing FF Loading @@ -813,18 +837,18 @@ int main(int argc, char **argv) printf("%s", cp); delete [] buf; exit(0); return EXIT_SUCCESS; } if (getLogSize) { exit(0); return EXIT_SUCCESS; } if (setLogSize || setPruneList) { exit(0); return EXIT_SUCCESS; } if (clearLog) { exit(0); return EXIT_SUCCESS; } //LOG_EVENT_INT(10, 12345); Loading @@ -839,8 +863,7 @@ int main(int argc, char **argv) int ret = android_logger_list_read(logger_list, &log_msg); if (ret == 0) { fprintf(stderr, "read: unexpected EOF!\n"); exit(EXIT_FAILURE); logcat_panic(false, "read: unexpected EOF!\n"); } if (ret < 0) { Loading @@ -849,15 +872,12 @@ int main(int argc, char **argv) } if (ret == -EIO) { fprintf(stderr, "read: unexpected EOF!\n"); exit(EXIT_FAILURE); logcat_panic(false, "read: unexpected EOF!\n"); } if (ret == -EINVAL) { fprintf(stderr, "read: unexpected length.\n"); exit(EXIT_FAILURE); logcat_panic(false, "read: unexpected length.\n"); } perror("logcat read failure"); exit(EXIT_FAILURE); logcat_panic(false, "logcat read failure"); } for(d = devices; d; d = d->next) { Loading @@ -866,23 +886,23 @@ int main(int argc, char **argv) } } if (!d) { android::g_devCount = 2; // set to Multiple g_devCount = 2; // set to Multiple d = &unexpected; d->binary = log_msg.id() == LOG_ID_EVENTS; } if (dev != d) { dev = d; android::maybePrintStart(dev, printDividers); maybePrintStart(dev, printDividers); } if (android::g_printBinary) { android::printBinary(&log_msg); if (g_printBinary) { printBinary(&log_msg); } else { android::processBuffer(dev, &log_msg); processBuffer(dev, &log_msg); } } android_logger_list_free(logger_list); return 0; return EXIT_SUCCESS; }