logcat.cpp revision 6fa09a066d6b6898a394a3ccf6c32111665cdbcb
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// Copyright 2006 The Android Open Source Project 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/logger.h> 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/logd.h> 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/sockets.h> 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/logprint.h> 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/event_tag_map.h> 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdarg.h> 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h> 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <time.h> 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/socket.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <arpa/inet.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define DEFAULT_MAX_ROTATED_LOGS 4 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic AndroidLogFormat * g_logformat; 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* logd prefixes records with a length field */ 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define RECORD_LENGTH_FIELD_SIZE_BYTES sizeof(uint32_t) 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_FILE_DIR "/dev/log/" 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostruct queued_entry_t { 346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato union { 356fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4))); 366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato struct logger_entry entry __attribute__((aligned(4))); 376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato }; 386fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t* next; 396fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 406fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t() { 416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato next = NULL; 426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 436fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato}; 446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 456fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic int cmp(queued_entry_t* a, queued_entry_t* b) { 466fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int n = a->entry.sec - b->entry.sec; 476fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (n != 0) { 486fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato return n; 496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato return a->entry.nsec - b->entry.nsec; 516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostruct log_device_t { 546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato char* device; 556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool binary; 566fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int fd; 576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool printed; 586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato char label; 596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t* queue; 616fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* next; 626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 636fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t(char* d, bool b, char l) { 646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato device = d; 656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato binary = b; 666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato label = l; 676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato next = NULL; 686fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printed = false; 696fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 706fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato void enqueue(queued_entry_t* entry) { 726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (this->queue == NULL) { 736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato this->queue = entry; 746fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 756fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t** e = &this->queue; 766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (*e && cmp(entry, *e) >= 0) { 776fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato e = &((*e)->next); 786fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 796fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato entry->next = *e; 806fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato *e = entry; 816fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 826fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato}; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Global Variables */ 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char * g_outputFileName = NULL; 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_logRotateSizeKBytes = 0; // 0 means "no log rotation" 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded" 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_outFD = -1; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic off_t g_outByteCount = 0; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_printBinary = 0; 956fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic int g_devCount = 0; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventTagMap* g_eventTagMap = NULL; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int openLogFile (const char *pathname) 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return open(g_outputFileName, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void rotateLogs() 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Can't rotate logs if we're not outputting to a file 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(g_outFD); 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = g_maxRotatedLogs ; i > 0 ; i--) { 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *file0, *file1; 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file1, "%s.%d", g_outputFileName, i); 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i - 1 == 0) { 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file0, "%s", g_outputFileName); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file0, "%s.%d", g_outputFileName, i - 1); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = rename (file0, file1); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0 && errno != ENOENT) { 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("while rotating log files"); 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file1); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file0); 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = openLogFile (g_outputFileName); 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror ("couldn't open output file"); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 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 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid printBinary(struct logger_entry *buf) 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t size = sizeof(logger_entry) + buf->len; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = write(g_outFD, buf, size); 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (ret < 0 && errno == EINTR); 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void processBuffer(log_device_t* dev, struct logger_entry *buf) 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int bytesWritten; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AndroidLogEntry entry; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char binaryMsgBuf[1024]; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (!dev->printed) { 1656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->printed = true; 1666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (g_devCount > 1) { 1676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato snprintf(binaryMsgBuf, sizeof(binaryMsgBuf), "--------- beginning of %s\n", 1686fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->device); 1696fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bytesWritten = write(g_outFD, binaryMsgBuf, strlen(binaryMsgBuf)); 1706fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (bytesWritten < 0) { 1716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("output error"); 1726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(-1); 1736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1746fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1756fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 1776fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (g_devCount > 1) { 1786fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato binaryMsgBuf[0] = dev->label; 1796fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato binaryMsgBuf[1] = ' '; 1806fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bytesWritten = write(g_outFD, binaryMsgBuf, 2); 1816fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (bytesWritten < 0) { 1826fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("output error"); 1836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(-1); 1846fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1856fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 1866fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 1876fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->binary) { 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_processBinaryLogBuffer(buf, &entry, g_eventTagMap, 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project binaryMsgBuf, sizeof(binaryMsgBuf)); 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //printf(">>> pri=%d len=%d msg='%s'\n", 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // entry.priority, entry.messageLen, entry.message); 192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_processLogBuffer(buf, &entry); 194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project bytesWritten = android_log_filterAndPrintLogLine( 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_logformat, g_outFD, &entry); 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (bytesWritten < 0) { 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("output error"); 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount += bytesWritten; 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 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 2196fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void chooseFirst(log_device_t* dev, log_device_t** firstdev, queued_entry_t** firstentry) { 2206fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato *firstdev = NULL; 2216fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato *firstentry = NULL; 2226fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int i=0; 2236fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (; dev; dev=dev->next) { 2246fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato i++; 2256fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->queue) { 2266fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if ((*firstentry) == NULL || cmp(dev->queue, *firstentry) < 0) { 2276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato (*firstentry) = dev->queue; 2286fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato *firstdev = dev; 2296fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2306fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void printEntry(log_device_t* dev, queued_entry_t* entry) { 2356fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (g_printBinary) { 2366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printBinary(&entry->entry); 2376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 2386fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato processBuffer(dev, &entry->entry); 2396fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2406fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void eatEntry(log_device_t* dev, queued_entry_t* entry) { 2436fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->queue != entry) { 2446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("assertion failed: entry isn't first in queue"); 2456fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(1); 2466fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2476fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printEntry(dev, entry); 2486fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->queue = entry->next; 2496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void readLogLines(log_device_t* devices) 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* dev; 2556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int max = 0; 2566fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t* entry; 2576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t* old; 2586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int ret; 2596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool somethingForEveryone; 2606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool sleep = true; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int result; 2636fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fd_set readset; 2646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->fd > max) { 2676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato max = dev->fd; 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2696fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (1) { 2726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato do { 2736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato timeval timeout = { 0, 5000 /* 5ms */ }; // If we oversleep it's ok, i.e. ignore EINTR. 2746fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato FD_ZERO(&readset); 2756fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato FD_SET(dev->fd, &readset); 2776fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2786fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato result = select(max + 1, &readset, NULL, NULL, sleep ? NULL : &timeout); 2796fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } while (result == -1 && errno == EINTR); 2806fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2816fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (result >= 0) { 2826fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (FD_ISSET(dev->fd, &readset)) { 2846fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato entry = new queued_entry_t; 2856fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato /* NOTE: driver guarantees we read exactly one full entry */ 2866fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN); 2876fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (ret < 0) { 2886fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (errno == EINTR) { 2896fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2906fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato goto next; 2916fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2926fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (errno == EAGAIN) { 2936fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2946fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 2956fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2966fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("logcat read"); 2976fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 2986fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2996fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato else if (!ret) { 3006fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fprintf(stderr, "read: Unexpected EOF!\n"); 3016fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 3026fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3046fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato entry->entry.msg[entry->entry.len] = '\0'; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3066fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->enqueue(entry); 3076fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3086fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3096fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 3106fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (result == 0) { 3116fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato // we did our short timeout trick and there's nothing new 3126fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato // print all that aren't the last in their list 3136fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato sleep = true; 3146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (true) { 3156fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato chooseFirst(devices, &dev, &entry); 3166fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (!entry) { 3176fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 3186fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3196fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato eatEntry(dev, entry); 3206fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3216fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 3226fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato // print all that aren't the last in their list 3236fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (true) { 3246fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato chooseFirst(devices, &dev, &entry); 3256fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (!entry) { 3266fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato sleep = false; 3276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 3286fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else if (entry->next == NULL) { 3296fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato sleep = false; 3306fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 3316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato eatEntry(dev, entry); 3336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratonext: 3376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ; 338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int clearLog(int logfd) 342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_FLUSH_LOG); 344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* returns the total size of the log's ring buffer */ 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getLogSize(int logfd) 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_GET_LOG_BUF_SIZE); 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* returns the readable size of the log's ring buffer (that is, amount of the log consumed) */ 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getLogReadableSize(int logfd) 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_GET_LOG_LEN); 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void setupOutput() 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = STDOUT_FILENO; 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat statbuf; 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = openLogFile (g_outputFileName); 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror ("couldn't open output file"); 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fstat(g_outFD, &statbuf); 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount = statbuf.st_size; 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void show_help(const char *cmd) 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd); 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "options include:\n" 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -s Set default filter to silent.\n" 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " Like specifying filterspec '*:s'\n" 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -f <filename> Log to file. Default to stdout\n" 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n" 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -n <count> Sets max number of rotated logs to <count>, default 4\n" 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -v <format> Sets the log print format, where <format> is one of:\n\n" 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " brief process tag thread raw time threadtime long\n\n" 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -c clear (flush) the entire log and exit\n" 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -d dump the log and then exit (don't block)\n" 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -g get the size of the log's ring buffer and exit\n" 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -b <buffer> request alternate ring buffer\n" 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " ('main' (default), 'radio', 'events')\n" 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -B output the log in binary"); 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"\nfilterspecs are a series of \n" 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " <tag>[:priority]\n\n" 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "where <tag> is a log component tag (or * for all) and priority is:\n" 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " V Verbose\n" 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " D Debug\n" 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " I Info\n" 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " W Warn\n" 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " E Error\n" 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " F Fatal\n" 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " S Silent (supress all output)\n" 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n'*' means '*:d' and <tag> by itself means <tag>:v\n" 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\nIf not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.\n" 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "If no filterspec is found, filter defaults to '*:I'\n" 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\nIf not specified with -v, format is set from ANDROID_PRINTF_LOG\n" 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "or defaults to \"brief\"\n\n"); 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} /* namespace android */ 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int setLogFormat(const char * formatString) 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static AndroidLogPrintFormat format; 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project format = android_log_formatFromString(formatString); 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (format == FORMAT_OFF) { 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // FORMAT_OFF means invalid string 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_log_setPrintFormat(g_logformat, format); 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern "C" void logprint_run_tests(void); 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratoint main(int argc, char **argv) 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int hasSetLogFormat = 0; 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int clearLog = 0; 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int getLogSize = 0; 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int mode = O_RDONLY; 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *forceFilters = NULL; 4496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* devices = NULL; 4506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* dev; 4516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool needBinary = false; 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_logformat = android_log_format_new(); 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 2 && 0 == strcmp(argv[1], "--test")) { 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logprint_run_tests(); 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 2 && 0 == strcmp(argv[1], "--help")) { 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = getopt(argc, argv, "cdgsQf:r::n:v:b:B"); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < 0) { 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(ret) { 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 's': 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // default to all silent 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_log_addFilterRule(g_logformat, "*:s"); 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'c': 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clearLog = 1; 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = O_WRONLY; 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'd': 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode |= O_NONBLOCK; 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'g': 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getLogSize = 1; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4936fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato case 'b': { 4946fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato char* buf = (char*) malloc(strlen(LOG_FILE_DIR) + strlen(optarg) + 1); 4956fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato strcpy(buf, LOG_FILE_DIR); 4966fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato strcat(buf, optarg); 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4986fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool binary = strcmp(optarg, "events") == 0; 4996fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (binary) { 5006fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato needBinary = true; 5016fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5026fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 5036fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (devices) { 5046fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = devices; 5056fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (dev->next) { 5066fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = dev->next; 5076fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5086fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->next = new log_device_t(buf, binary, optarg[0]); 5096fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 5106fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato devices = new log_device_t(buf, binary, optarg[0]); 5116fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5126fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::g_devCount++; 5136fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'B': 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_printBinary = 1; 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'f': 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // redirect output to a file 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_outputFileName = optarg; 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'r': 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (optarg == NULL) { 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_logRotateSizeKBytes 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project = DEFAULT_LOG_ROTATE_SIZE_KBYTES; 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project long logRotateSize; 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *lastDigit; 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isdigit(optarg[0])) { 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -r\n"); 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_logRotateSizeKBytes = atoi(optarg); 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'n': 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isdigit(optarg[0])) { 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -r\n"); 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_maxRotatedLogs = atoi(optarg); 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'v': 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat (optarg); 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -v\n"); 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hasSetLogFormat = 1; 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'Q': 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this is a *hidden* option used to start a version of logcat */ 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* in an emulated device only. it basically looks for androidboot.logcat= */ 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* on the kernel command line. If something is found, it extracts a log filter */ 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* and uses it to run the program. If nothing is found, the program should */ 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* quit immediately */ 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define KERNEL_OPTION "androidboot.logcat=" 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CONSOLE_OPTION "androidboot.console=" 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* logcat; 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* console; 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int force_exit = 1; 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static char cmdline[1024]; 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n = read(fd, cmdline, sizeof(cmdline)-1 ); 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n < 0) n = 0; 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[n] = 0; 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[0] = 0; 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logcat = strstr( cmdline, KERNEL_OPTION ); 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project console = strstr( cmdline, CONSOLE_OPTION ); 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logcat != NULL) { 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = logcat + sizeof(KERNEL_OPTION)-1;; 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" );; 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *q = 0; 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project forceFilters = p; 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project force_exit = 0; 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if nothing found or invalid filters, exit quietly */ 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (force_exit) 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* redirect our output to the emulator console */ 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (console) { 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = console + sizeof(CONSOLE_OPTION)-1; 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" ); 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char devname[64]; 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) { 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = q - p; 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(p); 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = snprintf( devname, sizeof(devname), "/dev/%.*s", len, p ); 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "logcat using %s (%d)\n", devname, len); 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len < (int)sizeof(devname)) { 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open( devname, O_WRONLY ); 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 1); 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 2); 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Unrecognized Option\n"); 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6406fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (!devices) { 6416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato devices = new log_device_t(strdup("/dev/"LOGGER_LOG_MAIN), false, LOGGER_LOG_MAIN[0]); 6426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::g_devCount = 1; 6436fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 6446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (android::g_logRotateSizeKBytes != 0 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && android::g_outputFileName == NULL 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ) { 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"-r requires -f as well\n"); 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::setupOutput(); 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hasSetLogFormat == 0) { 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* logFormat = getenv("ANDROID_PRINTF_LOG"); 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logFormat != NULL) { 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat(logFormat); 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "invalid format in ANDROID_PRINTF_LOG '%s'\n", 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logFormat); 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (forceFilters) { 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, forceFilters); 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf (stderr, "Invalid filter expression in -logcat option\n"); 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (argc == optind) { 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from environment variable 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *env_tags_orig = getenv("ANDROID_LOG_TAGS"); 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (env_tags_orig != NULL) { 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, env_tags_orig); 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "Invalid filter expression in" 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " ANDROID_LOG_TAGS\n"); 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from commandline 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = optind ; i < argc ; i++) { 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, argv[i]); 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]); 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7016fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = devices; 7026fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (dev) { 7036fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->fd = open(dev->device, mode); 7046fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->fd < 0) { 7056fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fprintf(stderr, "Unable to open log device '%s': %s\n", 7066fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->device, strerror(errno)); 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(EXIT_FAILURE); 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7106fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (clearLog) { 7116fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int ret; 7126fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ret = android::clearLog(dev->fd); 7136fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (ret) { 7146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7156fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7166fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7176fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato return 0; 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7206fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 7216fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int size, readable; 7226fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7236fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato size = android::getLogSize(dev->fd); 7246fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (size < 0) { 7256fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7266fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7286fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7296fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato readable = android::getLogReadableSize(dev->fd); 7306fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (readable < 0) { 7316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7356fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printf("%s: ring buffer is %dKb (%dKb consumed), " 7366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato "max entry is %db, max payload is %db\n", dev->device, 7376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato size / 1024, readable / 1024, 7386fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD); 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = dev->next; 7426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7436fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_INT(10, 12345); 749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_LONG(11, 0x1122334455667788LL); 750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_STRING(0, "whassup, doc?"); 751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (needBinary) 753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE); 754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::readLogLines(devices); 756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 759