logcat.cpp revision 80b221cb22f37446e76829d2dd0e8953a32f3bda
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; 6950844525a31fa41d7d432efb3c0355b38adb2f5fMathias Agopian queue = NULL; 706fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato next = NULL; 716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printed = false; 726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 746fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato void enqueue(queued_entry_t* entry) { 756fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (this->queue == NULL) { 766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato this->queue = entry; 776fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 786fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato queued_entry_t** e = &this->queue; 796fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (*e && cmp(entry, *e) >= 0) { 806fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato e = &((*e)->next); 816fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 826fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato entry->next = *e; 836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato *e = entry; 846fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 856fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 866fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato}; 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Global Variables */ 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char * g_outputFileName = NULL; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_logRotateSizeKBytes = 0; // 0 means "no log rotation" 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded" 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_outFD = -1; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic off_t g_outByteCount = 0; 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int g_printBinary = 0; 986fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic int g_devCount = 0; 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventTagMap* g_eventTagMap = NULL; 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int openLogFile (const char *pathname) 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 10480b221cb22f37446e76829d2dd0e8953a32f3bdaEdwin Vane return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void rotateLogs() 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Can't rotate logs if we're not outputting to a file 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(g_outFD); 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = g_maxRotatedLogs ; i > 0 ; i--) { 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *file0, *file1; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file1, "%s.%d", g_outputFileName, i); 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (i - 1 == 0) { 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file0, "%s", g_outputFileName); 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project asprintf(&file0, "%s.%d", g_outputFileName, i - 1); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = rename (file0, file1); 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0 && errno != ENOENT) { 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror("while rotating log files"); 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file1); 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(file0); 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = openLogFile (g_outputFileName); 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror ("couldn't open output file"); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount = 0; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid printBinary(struct logger_entry *buf) 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project size_t size = sizeof(logger_entry) + buf->len; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project do { 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = write(g_outFD, buf, size); 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } while (ret < 0 && errno == EINTR); 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void processBuffer(log_device_t* dev, struct logger_entry *buf) 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 16250844525a31fa41d7d432efb3c0355b38adb2f5fMathias Agopian int bytesWritten = 0; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project AndroidLogEntry entry; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char binaryMsgBuf[1024]; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->binary) { 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_processBinaryLogBuffer(buf, &entry, g_eventTagMap, 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project binaryMsgBuf, sizeof(binaryMsgBuf)); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //printf(">>> pri=%d len=%d msg='%s'\n", 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // entry.priority, entry.messageLen, entry.message); 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_processLogBuffer(buf, &entry); 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 175e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (err < 0) { 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto error; 177e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 178e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato 179e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) { 180e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (false && g_devCount > 1) { 181e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato binaryMsgBuf[0] = dev->label; 182e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato binaryMsgBuf[1] = ' '; 183e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato bytesWritten = write(g_outFD, binaryMsgBuf, 2); 184e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (bytesWritten < 0) { 185e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato perror("output error"); 186e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato exit(-1); 187e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 188e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 190e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry); 191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 192e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (bytesWritten < 0) { 193e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato perror("output error"); 194e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato exit(-1); 195e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount += bytesWritten; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_logRotateSizeKBytes > 0 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && (g_outByteCount / 1024) >= g_logRotateSizeKBytes 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ) { 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rotateLogs(); 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecterror: 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //fprintf (stderr, "Error processing record\n"); 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void chooseFirst(log_device_t* dev, log_device_t** firstdev) { 212d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor for (*firstdev = NULL; dev != NULL; dev = dev->next) { 213d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (dev->queue != NULL && (*firstdev == NULL || cmp(dev->queue, (*firstdev)->queue) < 0)) { 214d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor *firstdev = dev; 2156fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2166fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2176fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2186fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 219d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void maybePrintStart(log_device_t* dev) { 220d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (!dev->printed) { 221d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor dev->printed = true; 222d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_devCount > 1 && !g_printBinary) { 223d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor char buf[1024]; 224d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor snprintf(buf, sizeof(buf), "--------- beginning of %s\n", dev->device); 225d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (write(g_outFD, buf, strlen(buf)) < 0) { 226d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor perror("output error"); 227d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor exit(-1); 228d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 229d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 2306fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 233d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void skipNextEntry(log_device_t* dev) { 234d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor maybePrintStart(dev); 235d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor queued_entry_t* entry = dev->queue; 2366fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->queue = entry->next; 2376fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2386fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato} 2396fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 240d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnorstatic void printNextEntry(log_device_t* dev) { 241d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor maybePrintStart(dev); 242d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_printBinary) { 243d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor printBinary(&dev->queue->entry); 244d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } else { 245d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor processBuffer(dev, &dev->queue->entry); 246d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 247d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor skipNextEntry(dev); 248d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor} 249d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor 2506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratostatic void readLogLines(log_device_t* devices) 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* dev; 2536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int max = 0; 2546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int ret; 255d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor int queued_lines = 0; 256274c31ab6b646b52dfe0f69a9e30077795065d0aNick Kralevich bool sleep = false; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int result; 2596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fd_set readset; 2606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2616fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->fd > max) { 2636fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato max = dev->fd; 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 2656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (1) { 2686fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato do { 2696fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato timeval timeout = { 0, 5000 /* 5ms */ }; // If we oversleep it's ok, i.e. ignore EINTR. 2706fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato FD_ZERO(&readset); 2716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato FD_SET(dev->fd, &readset); 2736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2746fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato result = select(max + 1, &readset, NULL, NULL, sleep ? NULL : &timeout); 2756fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } while (result == -1 && errno == EINTR); 2766fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 2776fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (result >= 0) { 2786fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato for (dev=devices; dev; dev = dev->next) { 2796fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (FD_ISSET(dev->fd, &readset)) { 28050844525a31fa41d7d432efb3c0355b38adb2f5fMathias Agopian queued_entry_t* entry = new queued_entry_t(); 2816fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato /* NOTE: driver guarantees we read exactly one full entry */ 2826fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN); 2836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (ret < 0) { 2846fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (errno == EINTR) { 2856fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2866fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato goto next; 2876fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2886fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (errno == EAGAIN) { 2896fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato delete entry; 2906fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 2916fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2926fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("logcat read"); 2936fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 2946fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 2956fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato else if (!ret) { 2966fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fprintf(stderr, "read: Unexpected EOF!\n"); 2976fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 2986fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 29946070505e771fb539748936dd6ac68aa77b9f422Nick Kralevich else if (entry->entry.len != ret - sizeof(struct logger_entry)) { 30046070505e771fb539748936dd6ac68aa77b9f422Nick Kralevich fprintf(stderr, "read: unexpected length. Expected %d, got %d\n", 30146070505e771fb539748936dd6ac68aa77b9f422Nick Kralevich entry->entry.len, ret - sizeof(struct logger_entry)); 30246070505e771fb539748936dd6ac68aa77b9f422Nick Kralevich exit(EXIT_FAILURE); 30346070505e771fb539748936dd6ac68aa77b9f422Nick Kralevich } 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3056fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato entry->entry.msg[entry->entry.len] = '\0'; 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 3076fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->enqueue(entry); 308d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor ++queued_lines; 3096fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3106fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3116fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 3126fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (result == 0) { 3136fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato // we did our short timeout trick and there's nothing new 314d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor // print everything we have and wait for more data 3156fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato sleep = true; 3166fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (true) { 317d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor chooseFirst(devices, &dev); 318d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (dev == NULL) { 3196fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 3206fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 321d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_tail_lines == 0 || queued_lines <= g_tail_lines) { 322d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor printNextEntry(dev); 323d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } else { 324d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor skipNextEntry(dev); 325d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 326d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor --queued_lines; 3276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 328d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor 329d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor // the caller requested to just dump the log and exit 330e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (g_nonblock) { 3314bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root return; 332e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 3336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 3346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato // print all that aren't the last in their list 335d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor sleep = false; 336d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor while (g_tail_lines == 0 || queued_lines > g_tail_lines) { 337d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor chooseFirst(devices, &dev); 338d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (dev == NULL || dev->queue->next == NULL) { 3396fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato break; 3406fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 341d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor if (g_tail_lines == 0) { 342d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor printNextEntry(dev); 343d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } else { 344d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor skipNextEntry(dev); 345d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor } 346d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor --queued_lines; 3476fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 3486fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 3506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratonext: 3516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ; 352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int clearLog(int logfd) 356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_FLUSH_LOG); 358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* returns the total size of the log's ring buffer */ 361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getLogSize(int logfd) 362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_GET_LOG_BUF_SIZE); 364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* returns the readable size of the log's ring buffer (that is, amount of the log consumed) */ 367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getLogReadableSize(int logfd) 368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ioctl(logfd, LOGGER_GET_LOG_LEN); 370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void setupOutput() 373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outputFileName == NULL) { 376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = STDOUT_FILENO; 377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat statbuf; 380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outFD = openLogFile (g_outputFileName); 382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (g_outFD < 0) { 384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror ("couldn't open output file"); 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fstat(g_outFD, &statbuf); 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_outByteCount = statbuf.st_size; 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void show_help(const char *cmd) 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd); 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "options include:\n" 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -s Set default filter to silent.\n" 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " Like specifying filterspec '*:s'\n" 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -f <filename> Log to file. Default to stdout\n" 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n" 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -n <count> Sets max number of rotated logs to <count>, default 4\n" 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -v <format> Sets the log print format, where <format> is one of:\n\n" 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " brief process tag thread raw time threadtime long\n\n" 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -c clear (flush) the entire log and exit\n" 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -d dump the log and then exit (don't block)\n" 408d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor " -t <count> print only the most recent <count> lines (implies -d)\n" 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -g get the size of the log's ring buffer and exit\n" 410ba9608ff633724ded86aab7a9a401c87c7faafa1Wink Saville " -b <buffer> Request alternate ring buffer, 'main', 'system', 'radio'\n" 411ba9608ff633724ded86aab7a9a401c87c7faafa1Wink Saville " or 'events'. Multiple -b parameters are allowed and the\n" 412ba9608ff633724ded86aab7a9a401c87c7faafa1Wink Saville " results are interleaved. The default is -b main -b system.\n" 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " -B output the log in binary"); 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"\nfilterspecs are a series of \n" 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " <tag>[:priority]\n\n" 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "where <tag> is a log component tag (or * for all) and priority is:\n" 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " V Verbose\n" 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " D Debug\n" 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " I Info\n" 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " W Warn\n" 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " E Error\n" 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " F Fatal\n" 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " S Silent (supress all output)\n" 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\n'*' means '*:d' and <tag> by itself means <tag>:v\n" 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\nIf not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.\n" 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "If no filterspec is found, filter defaults to '*:I'\n" 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "\nIf not specified with -v, format is set from ANDROID_PRINTF_LOG\n" 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project "or defaults to \"brief\"\n\n"); 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} /* namespace android */ 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int setLogFormat(const char * formatString) 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static AndroidLogPrintFormat format; 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project format = android_log_formatFromString(formatString); 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (format == FORMAT_OFF) { 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // FORMAT_OFF means invalid string 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_log_setPrintFormat(g_logformat, format); 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern "C" void logprint_run_tests(void); 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 4576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onoratoint main(int argc, char **argv) 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int hasSetLogFormat = 0; 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int clearLog = 0; 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int getLogSize = 0; 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int mode = O_RDONLY; 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *forceFilters = NULL; 4656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* devices = NULL; 4666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato log_device_t* dev; 4676fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool needBinary = false; 468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project g_logformat = android_log_format_new(); 470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 2 && 0 == strcmp(argv[1], "--test")) { 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logprint_run_tests(); 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (argc == 2 && 0 == strcmp(argv[1], "--help")) { 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (;;) { 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret; 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 484d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B"); 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret < 0) { 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(ret) { 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 's': 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // default to all silent 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_log_addFilterRule(g_logformat, "*:s"); 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'c': 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project clearLog = 1; 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode = O_WRONLY; 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'd': 502e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato g_nonblock = true; 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 505d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor case 't': 506d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor g_nonblock = true; 507d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor g_tail_lines = atoi(optarg); 508d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor break; 509d1d3b6dbedd720349aef3e93c4f61a43ffe5ada3Dan Egnor 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'g': 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project getLogSize = 1; 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5146fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato case 'b': { 5156fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato char* buf = (char*) malloc(strlen(LOG_FILE_DIR) + strlen(optarg) + 1); 5166fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato strcpy(buf, LOG_FILE_DIR); 5176fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato strcat(buf, optarg); 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 5196fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato bool binary = strcmp(optarg, "events") == 0; 5206fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (binary) { 5216fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato needBinary = true; 5226fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5236fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 5246fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (devices) { 5256fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = devices; 5266fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (dev->next) { 5276fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = dev->next; 5286fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5296fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->next = new log_device_t(buf, binary, optarg[0]); 5306fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } else { 5316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato devices = new log_device_t(buf, binary, optarg[0]); 5326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 5336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::g_devCount++; 5346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'B': 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_printBinary = 1; 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'f': 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // redirect output to a file 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_outputFileName = optarg; 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'r': 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (optarg == NULL) { 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_logRotateSizeKBytes 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project = DEFAULT_LOG_ROTATE_SIZE_KBYTES; 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project long logRotateSize; 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *lastDigit; 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isdigit(optarg[0])) { 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -r\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 android::g_logRotateSizeKBytes = atoi(optarg); 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'n': 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!isdigit(optarg[0])) { 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -r\n"); 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_maxRotatedLogs = atoi(optarg); 573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'v': 576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat (optarg); 577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Invalid parameter to -v\n"); 579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hasSetLogFormat = 1; 584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case 'Q': 587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* this is a *hidden* option used to start a version of logcat */ 588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* in an emulated device only. it basically looks for androidboot.logcat= */ 589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* on the kernel command line. If something is found, it extracts a log filter */ 590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* and uses it to run the program. If nothing is found, the program should */ 591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* quit immediately */ 592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define KERNEL_OPTION "androidboot.logcat=" 593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define CONSOLE_OPTION "androidboot.console=" 594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project { 595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* logcat; 597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* console; 598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int force_exit = 1; 599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static char cmdline[1024]; 600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open("/proc/cmdline", O_RDONLY); 602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int n = read(fd, cmdline, sizeof(cmdline)-1 ); 604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (n < 0) n = 0; 605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[n] = 0; 606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project cmdline[0] = 0; 609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logcat = strstr( cmdline, KERNEL_OPTION ); 612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project console = strstr( cmdline, CONSOLE_OPTION ); 613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logcat != NULL) { 614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = logcat + sizeof(KERNEL_OPTION)-1;; 615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" );; 616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) 618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *q = 0; 619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project forceFilters = p; 621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project force_exit = 0; 622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* if nothing found or invalid filters, exit quietly */ 624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (force_exit) 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* redirect our output to the emulator console */ 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (console) { 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* p = console + sizeof(CONSOLE_OPTION)-1; 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* q = strpbrk( p, " \t\n\r" ); 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char devname[64]; 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (q != NULL) { 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = q - p; 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = strlen(p); 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = snprintf( devname, sizeof(devname), "/dev/%.*s", len, p ); 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "logcat using %s (%d)\n", devname, len); 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (len < (int)sizeof(devname)) { 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = open( devname, O_WRONLY ); 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (fd >= 0) { 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 1); 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(fd, 2); 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"Unrecognized Option\n"); 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 6616fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (!devices) { 662e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato devices = new log_device_t(strdup("/dev/"LOGGER_LOG_MAIN), false, 'm'); 6636fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::g_devCount = 1; 664e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato int accessmode = 665e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato (mode & O_RDONLY) ? R_OK : 0 666e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato | (mode & O_WRONLY) ? W_OK : 0; 667e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato // only add this if it's available 668e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) { 669e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato devices->next = new log_device_t(strdup("/dev/"LOGGER_LOG_SYSTEM), false, 's'); 670e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato android::g_devCount++; 671e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 6726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 6736fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (android::g_logRotateSizeKBytes != 0 675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project && android::g_outputFileName == NULL 676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ) { 677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr,"-r requires -f as well\n"); 678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::setupOutput(); 683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (hasSetLogFormat == 0) { 685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char* logFormat = getenv("ANDROID_PRINTF_LOG"); 686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (logFormat != NULL) { 688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = setLogFormat(logFormat); 689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "invalid format in ANDROID_PRINTF_LOG '%s'\n", 692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project logFormat); 693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (forceFilters) { 698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, forceFilters); 699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf (stderr, "Invalid filter expression in -logcat option\n"); 701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(0); 702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (argc == optind) { 704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from environment variable 705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *env_tags_orig = getenv("ANDROID_LOG_TAGS"); 706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (env_tags_orig != NULL) { 708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, env_tags_orig); 709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "Invalid filter expression in" 712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project " ANDROID_LOG_TAGS\n"); 713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // Add from commandline 719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (int i = optind ; i < argc ; i++) { 720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = android_log_addFilterString(g_logformat, argv[i]); 721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]); 724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::show_help(argv[0]); 725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(-1); 726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7306fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = devices; 7316fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato while (dev) { 7326fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->fd = open(dev->device, mode); 7336fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (dev->fd < 0) { 7346fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato fprintf(stderr, "Unable to open log device '%s': %s\n", 7356fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev->device, strerror(errno)); 736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project exit(EXIT_FAILURE); 737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7396fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (clearLog) { 7406fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int ret; 7416fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato ret = android::clearLog(dev->fd); 7426fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (ret) { 7436fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7446fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7456fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7486fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 7496fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato int size, readable; 7506fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7516fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato size = android::getLogSize(dev->fd); 7526fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (size < 0) { 7536fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7546fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7556fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7566fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7576fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato readable = android::getLogReadableSize(dev->fd); 7586fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (readable < 0) { 7596fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato perror("ioctl"); 7606fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato exit(EXIT_FAILURE); 7616fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7626fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7636fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato printf("%s: ring buffer is %dKb (%dKb consumed), " 7646fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato "max entry is %db, max payload is %db\n", dev->device, 7656fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato size / 1024, readable / 1024, 7666fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD); 767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7696fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato dev = dev->next; 7706fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato } 7716fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato 7726fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (getLogSize) { 7734bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root exit(0); 774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 775e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato if (clearLog) { 7764bf3c02e026077d14a4512c7c2f71937da3c2d50Kenny Root exit(0); 777e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato } 778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_INT(10, 12345); 780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_LONG(11, 0x1122334455667788LL); 781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project //LOG_EVENT_STRING(0, "whassup, doc?"); 782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7836fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato if (needBinary) 784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android::g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE); 785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 7866fa09a066d6b6898a394a3ccf6c32111665cdbcbJoe Onorato android::readLogLines(devices); 787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 790