logcat.cpp revision d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3
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; 27e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onoratostatic bool g_nonblock = false; 28d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic int g_tail_lines = 0; 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* logd prefixes records with a length field */ 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define RECORD_LENGTH_FIELD_SIZE_BYTES sizeof(uint32_t) 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_FILE_DIR "/dev/log/" 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 356fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostruct queued_entry_t { 366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato union { 376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4))); 386fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato struct logger_entry entry __attribute__((aligned(4))); 396fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato }; 406fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t* next; 416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t() { 436fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato next = NULL; 446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 456fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato}; 466fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 476fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic int cmp(queued_entry_t* a, queued_entry_t* b) { 486fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int n = a->entry.sec - b->entry.sec; 496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (n != 0) { 506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato return n; 516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato return a->entry.nsec - b->entry.nsec; 536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostruct log_device_t { 566fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato char* device; 576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool binary; 586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int fd; 596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool printed; 606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato char label; 616fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t* queue; 636fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* next; 646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t(char* d, bool b, char l) { 666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato device = d; 676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato binary = b; 686fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato label = l; 696fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato next = NULL; 706fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printed = false; 716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato void enqueue(queued_entry_t* entry) { 746fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (this->queue == NULL) { 756fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato this->queue = entry; 766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 776fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t** e = &this->queue; 786fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (*e && cmp(entry, *e) >= 0) { 796fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato e = &((*e)->next); 806fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 816fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato entry->next = *e; 826fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato *e = entry; 836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 846fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 856fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato}; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Global Variables */ 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char * g_outputFileName = NULL; 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_logRotateSizeKBytes = 0; // 0 means "no log rotation" 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded" 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_outFD = -1; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic off_t g_outByteCount = 0; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_printBinary = 0; 976fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic int g_devCount = 0; 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventTagMap* g_eventTagMap = NULL; 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int openLogFile (const char *pathname) 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return open(g_outputFileName, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void rotateLogs() 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Can't rotate logs if we're not outputting to a file 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(g_outFD); 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = g_maxRotatedLogs ; i > 0 ; i--) { 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *file0, *file1; 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file1, "%s.%d", g_outputFileName, i); 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i - 1 == 0) { 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file0, "%s", g_outputFileName); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file0, "%s.%d", g_outputFileName, i - 1); 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = rename (file0, file1); 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0 && errno != ENOENT) { 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("while rotating log files"); 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file1); 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file0); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = openLogFile (g_outputFileName); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror ("couldn't open output file"); 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount = 0; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid printBinary(struct logger_entry *buf) 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t size = sizeof(logger_entry) + buf->len; 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = write(g_outFD, buf, size); 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (ret < 0 && errno == EINTR); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void processBuffer(log_device_t* dev, struct logger_entry *buf) 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int bytesWritten; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AndroidLogEntry entry; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char binaryMsgBuf[1024]; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->binary) { 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_processBinaryLogBuffer(buf, &entry, g_eventTagMap, 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project binaryMsgBuf, sizeof(binaryMsgBuf)); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //printf(">>> pri=%d len=%d msg='%s'\n", 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // entry.priority, entry.messageLen, entry.message); 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_processLogBuffer(buf, &entry); 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 174e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (err < 0) { 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 176e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 177e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato 178e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) { 179e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (false && g_devCount > 1) { 180e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato binaryMsgBuf[0] = dev->label; 181e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato binaryMsgBuf[1] = ' '; 182e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato bytesWritten = write(g_outFD, binaryMsgBuf, 2); 183e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (bytesWritten < 0) { 184e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato perror("output error"); 185e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato exit(-1); 186e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 187e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 189e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry); 190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 191e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (bytesWritten < 0) { 192e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato perror("output error"); 193e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato exit(-1); 194e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount += bytesWritten; 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_logRotateSizeKBytes > 0 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && (g_outByteCount / 1024) >= g_logRotateSizeKBytes 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ) { 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rotateLogs(); 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecterror: 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //fprintf (stderr, "Error processing record\n"); 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 210d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void chooseFirst(log_device_t* dev, log_device_t** firstdev) { 211d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor for (*firstdev = NULL; dev != NULL; dev = dev->next) { 212d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (dev->queue != NULL && (*firstdev == NULL || cmp(dev->queue, (*firstdev)->queue) < 0)) { 213d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor *firstdev = dev; 2146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2156fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2166fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2176fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 218d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void maybePrintStart(log_device_t* dev) { 219d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (!dev->printed) { 220d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor dev->printed = true; 221d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_devCount > 1 && !g_printBinary) { 222d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor char buf[1024]; 223d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor snprintf(buf, sizeof(buf), "--------- beginning of %s\n", dev->device); 224d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (write(g_outFD, buf, strlen(buf)) < 0) { 225d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor perror("output error"); 226d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor exit(-1); 227d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 228d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 2296fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2306fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 232d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void skipNextEntry(log_device_t* dev) { 233d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor maybePrintStart(dev); 234d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor queued_entry_t* entry = dev->queue; 2356fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->queue = entry->next; 2366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2386fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 239d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void printNextEntry(log_device_t* dev) { 240d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor maybePrintStart(dev); 241d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_printBinary) { 242d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor printBinary(&dev->queue->entry); 243d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } else { 244d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor processBuffer(dev, &dev->queue->entry); 245d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 246d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor skipNextEntry(dev); 247d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor} 248d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor 2496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void readLogLines(log_device_t* devices) 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* dev; 2526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int max = 0; 2536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int ret; 254d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor int queued_lines = 0; 2556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool sleep = true; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int result; 2586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fd_set readset; 2596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2616fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->fd > max) { 2626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato max = dev->fd; 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (1) { 2676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato do { 2686fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato timeval timeout = { 0, 5000 /* 5ms */ }; // If we oversleep it's ok, i.e. ignore EINTR. 2696fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato FD_ZERO(&readset); 2706fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato FD_SET(dev->fd, &readset); 2726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato result = select(max + 1, &readset, NULL, NULL, sleep ? NULL : &timeout); 2746fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } while (result == -1 && errno == EINTR); 2756fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (result >= 0) { 2776fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2786fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (FD_ISSET(dev->fd, &readset)) { 279d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor queued_entry_t* entry = new queued_entry_t; 2806fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato /* NOTE: driver guarantees we read exactly one full entry */ 2816fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN); 2826fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (ret < 0) { 2836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (errno == EINTR) { 2846fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2856fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato goto next; 2866fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2876fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (errno == EAGAIN) { 2886fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2896fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 2906fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2916fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("logcat read"); 2926fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 2936fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2946fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato else if (!ret) { 2956fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fprintf(stderr, "read: Unexpected EOF!\n"); 2966fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 2976fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2996fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato entry->entry.msg[entry->entry.len] = '\0'; 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3016fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->enqueue(entry); 302d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor ++queued_lines; 3036fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3046fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3056fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 3066fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (result == 0) { 3076fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato // we did our short timeout trick and there's nothing new 308d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor // print everything we have and wait for more data 3096fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato sleep = true; 3106fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (true) { 311d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor chooseFirst(devices, &dev); 312d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (dev == NULL) { 3136fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 3146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 315d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_tail_lines == 0 || queued_lines <= g_tail_lines) { 316d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor printNextEntry(dev); 317d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } else { 318d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor skipNextEntry(dev); 319d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 320d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor --queued_lines; 3216fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 322d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor 323d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor // the caller requested to just dump the log and exit 324e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (g_nonblock) { 325e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato exit(0); 326e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 3276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 3286fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato // print all that aren't the last in their list 329d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor sleep = false; 330d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor while (g_tail_lines == 0 || queued_lines > g_tail_lines) { 331d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor chooseFirst(devices, &dev); 332d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (dev == NULL || dev->queue->next == NULL) { 3336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 3346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 335d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_tail_lines == 0) { 336d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor printNextEntry(dev); 337d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } else { 338d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor skipNextEntry(dev); 339d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 340d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor --queued_lines; 3416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratonext: 3456fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ; 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int clearLog(int logfd) 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_FLUSH_LOG); 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* returns the total size of the log's ring buffer */ 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getLogSize(int logfd) 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_GET_LOG_BUF_SIZE); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* returns the readable size of the log's ring buffer (that is, amount of the log consumed) */ 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getLogReadableSize(int logfd) 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_GET_LOG_LEN); 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void setupOutput() 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = STDOUT_FILENO; 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat statbuf; 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = openLogFile (g_outputFileName); 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror ("couldn't open output file"); 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fstat(g_outFD, &statbuf); 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount = statbuf.st_size; 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void show_help(const char *cmd) 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd); 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "options include:\n" 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -s Set default filter to silent.\n" 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " Like specifying filterspec '*:s'\n" 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -f <filename> Log to file. Default to stdout\n" 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n" 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -n <count> Sets max number of rotated logs to <count>, default 4\n" 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -v <format> Sets the log print format, where <format> is one of:\n\n" 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " brief process tag thread raw time threadtime long\n\n" 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -c clear (flush) the entire log and exit\n" 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -d dump the log and then exit (don't block)\n" 402d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor " -t <count> print only the most recent <count> lines (implies -d)\n" 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -g get the size of the log's ring buffer and exit\n" 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -b <buffer> request alternate ring buffer\n" 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " ('main' (default), 'radio', 'events')\n" 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -B output the log in binary"); 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"\nfilterspecs are a series of \n" 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " <tag>[:priority]\n\n" 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "where <tag> is a log component tag (or * for all) and priority is:\n" 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " V Verbose\n" 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " D Debug\n" 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " I Info\n" 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " W Warn\n" 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " E Error\n" 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " F Fatal\n" 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " S Silent (supress all output)\n" 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n'*' means '*:d' and <tag> by itself means <tag>:v\n" 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\nIf not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.\n" 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "If no filterspec is found, filter defaults to '*:I'\n" 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\nIf not specified with -v, format is set from ANDROID_PRINTF_LOG\n" 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "or defaults to \"brief\"\n\n"); 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} /* namespace android */ 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int setLogFormat(const char * formatString) 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static AndroidLogPrintFormat format; 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project format = android_log_formatFromString(formatString); 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (format == FORMAT_OFF) { 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // FORMAT_OFF means invalid string 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_log_setPrintFormat(g_logformat, format); 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern "C" void logprint_run_tests(void); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratoint main(int argc, char **argv) 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int hasSetLogFormat = 0; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int clearLog = 0; 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int getLogSize = 0; 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int mode = O_RDONLY; 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *forceFilters = NULL; 4586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* devices = NULL; 4596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* dev; 4606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool needBinary = false; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_logformat = android_log_format_new(); 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 2 && 0 == strcmp(argv[1], "--test")) { 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logprint_run_tests(); 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 2 && 0 == strcmp(argv[1], "--help")) { 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 477d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B"); 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < 0) { 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(ret) { 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 's': 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // default to all silent 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_log_addFilterRule(g_logformat, "*:s"); 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'c': 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clearLog = 1; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = O_WRONLY; 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'd': 495e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato g_nonblock = true; 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 498d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor case 't': 499d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor g_nonblock = true; 500d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor g_tail_lines = atoi(optarg); 501d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor break; 502d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'g': 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getLogSize = 1; 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5076fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato case 'b': { 5086fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato char* buf = (char*) malloc(strlen(LOG_FILE_DIR) + strlen(optarg) + 1); 5096fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato strcpy(buf, LOG_FILE_DIR); 5106fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato strcat(buf, optarg); 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5126fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool binary = strcmp(optarg, "events") == 0; 5136fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (binary) { 5146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato needBinary = true; 5156fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5166fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 5176fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (devices) { 5186fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = devices; 5196fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (dev->next) { 5206fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = dev->next; 5216fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5226fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->next = new log_device_t(buf, binary, optarg[0]); 5236fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 5246fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato devices = new log_device_t(buf, binary, optarg[0]); 5256fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5266fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::g_devCount++; 5276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'B': 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_printBinary = 1; 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'f': 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // redirect output to a file 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_outputFileName = optarg; 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'r': 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (optarg == NULL) { 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_logRotateSizeKBytes 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project = DEFAULT_LOG_ROTATE_SIZE_KBYTES; 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project long logRotateSize; 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *lastDigit; 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isdigit(optarg[0])) { 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -r\n"); 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_logRotateSizeKBytes = atoi(optarg); 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'n': 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isdigit(optarg[0])) { 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -r\n"); 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_maxRotatedLogs = atoi(optarg); 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'v': 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat (optarg); 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -v\n"); 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hasSetLogFormat = 1; 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'Q': 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this is a *hidden* option used to start a version of logcat */ 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* in an emulated device only. it basically looks for androidboot.logcat= */ 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* on the kernel command line. If something is found, it extracts a log filter */ 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* and uses it to run the program. If nothing is found, the program should */ 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* quit immediately */ 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define KERNEL_OPTION "androidboot.logcat=" 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CONSOLE_OPTION "androidboot.console=" 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* logcat; 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* console; 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int force_exit = 1; 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static char cmdline[1024]; 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n = read(fd, cmdline, sizeof(cmdline)-1 ); 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n < 0) n = 0; 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[n] = 0; 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[0] = 0; 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logcat = strstr( cmdline, KERNEL_OPTION ); 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project console = strstr( cmdline, CONSOLE_OPTION ); 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logcat != NULL) { 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = logcat + sizeof(KERNEL_OPTION)-1;; 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" );; 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *q = 0; 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project forceFilters = p; 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project force_exit = 0; 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if nothing found or invalid filters, exit quietly */ 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (force_exit) 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* redirect our output to the emulator console */ 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (console) { 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = console + sizeof(CONSOLE_OPTION)-1; 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" ); 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char devname[64]; 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) { 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = q - p; 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(p); 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = snprintf( devname, sizeof(devname), "/dev/%.*s", len, p ); 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "logcat using %s (%d)\n", devname, len); 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len < (int)sizeof(devname)) { 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open( devname, O_WRONLY ); 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 1); 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 2); 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Unrecognized Option\n"); 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (!devices) { 655e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato devices = new log_device_t(strdup("/dev/"LOGGER_LOG_MAIN), false, 'm'); 6566fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::g_devCount = 1; 657e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato int accessmode = 658e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato (mode & O_RDONLY) ? R_OK : 0 659e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato | (mode & O_WRONLY) ? W_OK : 0; 660e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato // only add this if it's available 661e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) { 662e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato devices->next = new log_device_t(strdup("/dev/"LOGGER_LOG_SYSTEM), false, 's'); 663e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato android::g_devCount++; 664e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 6656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 6666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (android::g_logRotateSizeKBytes != 0 668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && android::g_outputFileName == NULL 669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ) { 670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"-r requires -f as well\n"); 671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::setupOutput(); 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hasSetLogFormat == 0) { 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* logFormat = getenv("ANDROID_PRINTF_LOG"); 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logFormat != NULL) { 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat(logFormat); 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "invalid format in ANDROID_PRINTF_LOG '%s'\n", 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logFormat); 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (forceFilters) { 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, forceFilters); 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf (stderr, "Invalid filter expression in -logcat option\n"); 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (argc == optind) { 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from environment variable 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *env_tags_orig = getenv("ANDROID_LOG_TAGS"); 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (env_tags_orig != NULL) { 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, env_tags_orig); 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "Invalid filter expression in" 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " ANDROID_LOG_TAGS\n"); 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from commandline 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = optind ; i < argc ; i++) { 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, argv[i]); 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]); 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7236fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = devices; 7246fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (dev) { 7256fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->fd = open(dev->device, mode); 7266fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->fd < 0) { 7276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fprintf(stderr, "Unable to open log device '%s': %s\n", 7286fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->device, strerror(errno)); 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(EXIT_FAILURE); 730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (clearLog) { 7336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int ret; 7346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ret = android::clearLog(dev->fd); 7356fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (ret) { 7366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7386fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 7426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int size, readable; 7436fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato size = android::getLogSize(dev->fd); 7456fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (size < 0) { 7466fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7476fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7486fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato readable = android::getLogReadableSize(dev->fd); 7516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (readable < 0) { 7526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7566fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printf("%s: ring buffer is %dKb (%dKb consumed), " 7576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato "max entry is %db, max payload is %db\n", dev->device, 7586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato size / 1024, readable / 1024, 7596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD); 760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = dev->next; 7636fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 768e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (clearLog) { 769e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato return 0; 770e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_INT(10, 12345); 773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_LONG(11, 0x1122334455667788LL); 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_STRING(0, "whassup, doc?"); 775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (needBinary) 777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE); 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7796fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::readLogLines(devices); 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 783