blob: b6ca171370dbb1ab4ec5c46fdcf80ccda70c1f5f [file] [log] [blame]
Mark Salyzyna1062c72013-11-22 10:55:48 -08001// Copyright 2006-2013 The Android Open Source Project
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002
Mark Salyzyna1062c72013-11-22 10:55:48 -08003#include <log/log.h>
Colin Cross9227bd32013-07-23 16:59:20 -07004#include <log/logger.h>
5#include <log/logd.h>
6#include <log/logprint.h>
7#include <log/event_tag_map.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08008#include <cutils/sockets.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08009
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdarg.h>
13#include <string.h>
14#include <unistd.h>
15#include <fcntl.h>
16#include <time.h>
17#include <errno.h>
18#include <assert.h>
19#include <ctype.h>
20#include <sys/socket.h>
21#include <sys/stat.h>
22#include <arpa/inet.h>
23
24#define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16
25#define DEFAULT_MAX_ROTATED_LOGS 4
26
27static AndroidLogFormat * g_logformat;
28
29/* logd prefixes records with a length field */
30#define RECORD_LENGTH_FIELD_SIZE_BYTES sizeof(uint32_t)
31
Joe Onorato6fa09a02010-02-26 10:04:23 -080032struct log_device_t {
Mark Salyzyna1062c72013-11-22 10:55:48 -080033 const char* device;
Joe Onorato6fa09a02010-02-26 10:04:23 -080034 bool binary;
Mark Salyzyna1062c72013-11-22 10:55:48 -080035 struct logger *logger;
36 struct logger_list *logger_list;
Joe Onorato6fa09a02010-02-26 10:04:23 -080037 bool printed;
38 char label;
39
Joe Onorato6fa09a02010-02-26 10:04:23 -080040 log_device_t* next;
41
Mark Salyzyna1062c72013-11-22 10:55:48 -080042 log_device_t(const char* d, bool b, char l) {
Joe Onorato6fa09a02010-02-26 10:04:23 -080043 device = d;
44 binary = b;
45 label = l;
46 next = NULL;
47 printed = false;
48 }
Joe Onorato6fa09a02010-02-26 10:04:23 -080049};
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080050
51namespace android {
52
53/* Global Variables */
54
55static const char * g_outputFileName = NULL;
56static int g_logRotateSizeKBytes = 0; // 0 means "no log rotation"
57static int g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded"
58static int g_outFD = -1;
59static off_t g_outByteCount = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080060static int g_printBinary = 0;
Joe Onorato6fa09a02010-02-26 10:04:23 -080061static int g_devCount = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080062
63static EventTagMap* g_eventTagMap = NULL;
64
65static int openLogFile (const char *pathname)
66{
Edwin Vane80b221c2012-08-13 12:55:07 -040067 return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080068}
69
70static void rotateLogs()
71{
72 int err;
73
74 // Can't rotate logs if we're not outputting to a file
75 if (g_outputFileName == NULL) {
76 return;
77 }
78
79 close(g_outFD);
80
81 for (int i = g_maxRotatedLogs ; i > 0 ; i--) {
82 char *file0, *file1;
83
84 asprintf(&file1, "%s.%d", g_outputFileName, i);
85
86 if (i - 1 == 0) {
87 asprintf(&file0, "%s", g_outputFileName);
88 } else {
89 asprintf(&file0, "%s.%d", g_outputFileName, i - 1);
90 }
91
92 err = rename (file0, file1);
93
94 if (err < 0 && errno != ENOENT) {
95 perror("while rotating log files");
96 }
97
98 free(file1);
99 free(file0);
100 }
101
102 g_outFD = openLogFile (g_outputFileName);
103
104 if (g_outFD < 0) {
105 perror ("couldn't open output file");
106 exit(-1);
107 }
108
109 g_outByteCount = 0;
110
111}
112
Mark Salyzyna1062c72013-11-22 10:55:48 -0800113void printBinary(struct log_msg *buf)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800114{
Mark Salyzyna1062c72013-11-22 10:55:48 -0800115 size_t size = buf->len();
116
117 TEMP_FAILURE_RETRY(write(g_outFD, buf, size));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800118}
119
Mark Salyzyna1062c72013-11-22 10:55:48 -0800120static void processBuffer(log_device_t* dev, struct log_msg *buf)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800121{
Mathias Agopian50844522010-03-17 16:10:26 -0700122 int bytesWritten = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800123 int err;
124 AndroidLogEntry entry;
125 char binaryMsgBuf[1024];
126
Joe Onorato6fa09a02010-02-26 10:04:23 -0800127 if (dev->binary) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800128 err = android_log_processBinaryLogBuffer(&buf->entry_v1, &entry,
129 g_eventTagMap,
130 binaryMsgBuf,
131 sizeof(binaryMsgBuf));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800132 //printf(">>> pri=%d len=%d msg='%s'\n",
133 // entry.priority, entry.messageLen, entry.message);
134 } else {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800135 err = android_log_processLogBuffer(&buf->entry_v1, &entry);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800136 }
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800137 if (err < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800138 goto error;
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800139 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800140
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800141 if (android_log_shouldPrintLine(g_logformat, entry.tag, entry.priority)) {
142 if (false && g_devCount > 1) {
143 binaryMsgBuf[0] = dev->label;
144 binaryMsgBuf[1] = ' ';
145 bytesWritten = write(g_outFD, binaryMsgBuf, 2);
146 if (bytesWritten < 0) {
147 perror("output error");
148 exit(-1);
149 }
150 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800151
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800152 bytesWritten = android_log_printLogLine(g_logformat, g_outFD, &entry);
153
154 if (bytesWritten < 0) {
155 perror("output error");
156 exit(-1);
157 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800158 }
159
160 g_outByteCount += bytesWritten;
161
Mark Salyzyna1062c72013-11-22 10:55:48 -0800162 if (g_logRotateSizeKBytes > 0
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800163 && (g_outByteCount / 1024) >= g_logRotateSizeKBytes
164 ) {
165 rotateLogs();
166 }
167
168error:
169 //fprintf (stderr, "Error processing record\n");
170 return;
171}
172
Dan Egnord1d3b6d2010-03-11 20:32:17 -0800173static void maybePrintStart(log_device_t* dev) {
174 if (!dev->printed) {
175 dev->printed = true;
176 if (g_devCount > 1 && !g_printBinary) {
177 char buf[1024];
Mark Salyzyna1062c72013-11-22 10:55:48 -0800178 snprintf(buf, sizeof(buf), "--------- beginning of %s\n",
179 dev->device);
Dan Egnord1d3b6d2010-03-11 20:32:17 -0800180 if (write(g_outFD, buf, strlen(buf)) < 0) {
181 perror("output error");
182 exit(-1);
Joe Onorato6fa09a02010-02-26 10:04:23 -0800183 }
184 }
185 }
186}
187
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800188static void setupOutput()
189{
190
191 if (g_outputFileName == NULL) {
192 g_outFD = STDOUT_FILENO;
193
194 } else {
195 struct stat statbuf;
196
197 g_outFD = openLogFile (g_outputFileName);
198
199 if (g_outFD < 0) {
200 perror ("couldn't open output file");
201 exit(-1);
202 }
203
204 fstat(g_outFD, &statbuf);
205
206 g_outByteCount = statbuf.st_size;
207 }
208}
209
210static void show_help(const char *cmd)
211{
212 fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd);
213
214 fprintf(stderr, "options include:\n"
215 " -s Set default filter to silent.\n"
216 " Like specifying filterspec '*:s'\n"
217 " -f <filename> Log to file. Default to stdout\n"
218 " -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n"
219 " -n <count> Sets max number of rotated logs to <count>, default 4\n"
220 " -v <format> Sets the log print format, where <format> is one of:\n\n"
221 " brief process tag thread raw time threadtime long\n\n"
222 " -c clear (flush) the entire log and exit\n"
223 " -d dump the log and then exit (don't block)\n"
Dan Egnord1d3b6d2010-03-11 20:32:17 -0800224 " -t <count> print only the most recent <count> lines (implies -d)\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800225 " -g get the size of the log's ring buffer and exit\n"
Wink Savilleba9608f2010-06-18 10:15:08 -0700226 " -b <buffer> Request alternate ring buffer, 'main', 'system', 'radio'\n"
227 " or 'events'. Multiple -b parameters are allowed and the\n"
228 " results are interleaved. The default is -b main -b system.\n"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800229 " -B output the log in binary");
230
231
232 fprintf(stderr,"\nfilterspecs are a series of \n"
233 " <tag>[:priority]\n\n"
234 "where <tag> is a log component tag (or * for all) and priority is:\n"
235 " V Verbose\n"
236 " D Debug\n"
237 " I Info\n"
238 " W Warn\n"
239 " E Error\n"
240 " F Fatal\n"
241 " S Silent (supress all output)\n"
242 "\n'*' means '*:d' and <tag> by itself means <tag>:v\n"
243 "\nIf not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.\n"
244 "If no filterspec is found, filter defaults to '*:I'\n"
245 "\nIf not specified with -v, format is set from ANDROID_PRINTF_LOG\n"
246 "or defaults to \"brief\"\n\n");
247
248
249
250}
251
252
253} /* namespace android */
254
255static int setLogFormat(const char * formatString)
256{
257 static AndroidLogPrintFormat format;
258
259 format = android_log_formatFromString(formatString);
260
261 if (format == FORMAT_OFF) {
262 // FORMAT_OFF means invalid string
263 return -1;
264 }
265
266 android_log_setPrintFormat(g_logformat, format);
267
268 return 0;
269}
270
271extern "C" void logprint_run_tests(void);
272
Joe Onorato6fa09a02010-02-26 10:04:23 -0800273int main(int argc, char **argv)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800274{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800275 int err;
276 int hasSetLogFormat = 0;
277 int clearLog = 0;
278 int getLogSize = 0;
279 int mode = O_RDONLY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800280 const char *forceFilters = NULL;
Joe Onorato6fa09a02010-02-26 10:04:23 -0800281 log_device_t* devices = NULL;
282 log_device_t* dev;
283 bool needBinary = false;
Mark Salyzyna1062c72013-11-22 10:55:48 -0800284 struct logger_list *logger_list;
285 int tail_lines = 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800286
287 g_logformat = android_log_format_new();
288
289 if (argc == 2 && 0 == strcmp(argv[1], "--test")) {
290 logprint_run_tests();
291 exit(0);
292 }
293
294 if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
295 android::show_help(argv[0]);
296 exit(0);
297 }
298
299 for (;;) {
300 int ret;
301
Dan Egnord1d3b6d2010-03-11 20:32:17 -0800302 ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800303
304 if (ret < 0) {
305 break;
306 }
307
308 switch(ret) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800309 case 's':
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800310 // default to all silent
311 android_log_addFilterRule(g_logformat, "*:s");
312 break;
313
314 case 'c':
315 clearLog = 1;
316 mode = O_WRONLY;
317 break;
318
319 case 'd':
Mark Salyzyna1062c72013-11-22 10:55:48 -0800320 mode = O_RDONLY | O_NDELAY;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800321 break;
322
Dan Egnord1d3b6d2010-03-11 20:32:17 -0800323 case 't':
Mark Salyzyna1062c72013-11-22 10:55:48 -0800324 mode = O_RDONLY | O_NDELAY;
325 tail_lines = atoi(optarg);
Dan Egnord1d3b6d2010-03-11 20:32:17 -0800326 break;
327
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800328 case 'g':
329 getLogSize = 1;
330 break;
331
Joe Onorato6fa09a02010-02-26 10:04:23 -0800332 case 'b': {
Joe Onorato6fa09a02010-02-26 10:04:23 -0800333 bool binary = strcmp(optarg, "events") == 0;
334 if (binary) {
335 needBinary = true;
336 }
337
338 if (devices) {
339 dev = devices;
340 while (dev->next) {
341 dev = dev->next;
342 }
Mark Salyzyna1062c72013-11-22 10:55:48 -0800343 dev->next = new log_device_t(optarg, binary, optarg[0]);
Joe Onorato6fa09a02010-02-26 10:04:23 -0800344 } else {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800345 devices = new log_device_t(optarg, binary, optarg[0]);
Joe Onorato6fa09a02010-02-26 10:04:23 -0800346 }
347 android::g_devCount++;
348 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800349 break;
350
351 case 'B':
352 android::g_printBinary = 1;
353 break;
354
355 case 'f':
356 // redirect output to a file
357
358 android::g_outputFileName = optarg;
359
360 break;
361
362 case 'r':
Mark Salyzyna1062c72013-11-22 10:55:48 -0800363 if (optarg == NULL) {
364 android::g_logRotateSizeKBytes
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800365 = DEFAULT_LOG_ROTATE_SIZE_KBYTES;
366 } else {
367 long logRotateSize;
368 char *lastDigit;
369
370 if (!isdigit(optarg[0])) {
371 fprintf(stderr,"Invalid parameter to -r\n");
372 android::show_help(argv[0]);
373 exit(-1);
374 }
375 android::g_logRotateSizeKBytes = atoi(optarg);
376 }
377 break;
378
379 case 'n':
380 if (!isdigit(optarg[0])) {
381 fprintf(stderr,"Invalid parameter to -r\n");
382 android::show_help(argv[0]);
383 exit(-1);
384 }
385
386 android::g_maxRotatedLogs = atoi(optarg);
387 break;
388
389 case 'v':
390 err = setLogFormat (optarg);
391 if (err < 0) {
392 fprintf(stderr,"Invalid parameter to -v\n");
393 android::show_help(argv[0]);
394 exit(-1);
395 }
396
397 hasSetLogFormat = 1;
398 break;
399
400 case 'Q':
401 /* this is a *hidden* option used to start a version of logcat */
402 /* in an emulated device only. it basically looks for androidboot.logcat= */
403 /* on the kernel command line. If something is found, it extracts a log filter */
404 /* and uses it to run the program. If nothing is found, the program should */
405 /* quit immediately */
406#define KERNEL_OPTION "androidboot.logcat="
407#define CONSOLE_OPTION "androidboot.console="
408 {
409 int fd;
410 char* logcat;
411 char* console;
412 int force_exit = 1;
413 static char cmdline[1024];
414
415 fd = open("/proc/cmdline", O_RDONLY);
416 if (fd >= 0) {
417 int n = read(fd, cmdline, sizeof(cmdline)-1 );
418 if (n < 0) n = 0;
419 cmdline[n] = 0;
420 close(fd);
421 } else {
422 cmdline[0] = 0;
423 }
424
425 logcat = strstr( cmdline, KERNEL_OPTION );
426 console = strstr( cmdline, CONSOLE_OPTION );
427 if (logcat != NULL) {
428 char* p = logcat + sizeof(KERNEL_OPTION)-1;;
429 char* q = strpbrk( p, " \t\n\r" );;
430
431 if (q != NULL)
432 *q = 0;
433
434 forceFilters = p;
435 force_exit = 0;
436 }
437 /* if nothing found or invalid filters, exit quietly */
438 if (force_exit)
439 exit(0);
440
441 /* redirect our output to the emulator console */
442 if (console) {
443 char* p = console + sizeof(CONSOLE_OPTION)-1;
444 char* q = strpbrk( p, " \t\n\r" );
445 char devname[64];
446 int len;
447
448 if (q != NULL) {
449 len = q - p;
450 } else
451 len = strlen(p);
452
453 len = snprintf( devname, sizeof(devname), "/dev/%.*s", len, p );
454 fprintf(stderr, "logcat using %s (%d)\n", devname, len);
455 if (len < (int)sizeof(devname)) {
456 fd = open( devname, O_WRONLY );
457 if (fd >= 0) {
458 dup2(fd, 1);
459 dup2(fd, 2);
460 close(fd);
461 }
462 }
463 }
464 }
465 break;
466
467 default:
468 fprintf(stderr,"Unrecognized Option\n");
469 android::show_help(argv[0]);
470 exit(-1);
471 break;
472 }
473 }
474
Joe Onorato6fa09a02010-02-26 10:04:23 -0800475 if (!devices) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800476 devices = new log_device_t("main", false, 'm');
Joe Onorato6fa09a02010-02-26 10:04:23 -0800477 android::g_devCount = 1;
Mark Salyzyna1062c72013-11-22 10:55:48 -0800478 if (android_name_to_log_id("system") == LOG_ID_SYSTEM) {
479 devices->next = new log_device_t("system", false, 's');
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800480 android::g_devCount++;
481 }
Joe Onorato6fa09a02010-02-26 10:04:23 -0800482 }
483
Mark Salyzyna1062c72013-11-22 10:55:48 -0800484 if (android::g_logRotateSizeKBytes != 0
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800485 && android::g_outputFileName == NULL
486 ) {
487 fprintf(stderr,"-r requires -f as well\n");
488 android::show_help(argv[0]);
489 exit(-1);
490 }
491
492 android::setupOutput();
493
494 if (hasSetLogFormat == 0) {
495 const char* logFormat = getenv("ANDROID_PRINTF_LOG");
496
497 if (logFormat != NULL) {
498 err = setLogFormat(logFormat);
499
500 if (err < 0) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800501 fprintf(stderr, "invalid format in ANDROID_PRINTF_LOG '%s'\n",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800502 logFormat);
503 }
504 }
505 }
506
507 if (forceFilters) {
508 err = android_log_addFilterString(g_logformat, forceFilters);
509 if (err < 0) {
510 fprintf (stderr, "Invalid filter expression in -logcat option\n");
511 exit(0);
512 }
513 } else if (argc == optind) {
514 // Add from environment variable
515 char *env_tags_orig = getenv("ANDROID_LOG_TAGS");
516
517 if (env_tags_orig != NULL) {
518 err = android_log_addFilterString(g_logformat, env_tags_orig);
519
Mark Salyzyna1062c72013-11-22 10:55:48 -0800520 if (err < 0) {
521 fprintf(stderr, "Invalid filter expression in"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800522 " ANDROID_LOG_TAGS\n");
523 android::show_help(argv[0]);
524 exit(-1);
525 }
526 }
527 } else {
528 // Add from commandline
529 for (int i = optind ; i < argc ; i++) {
530 err = android_log_addFilterString(g_logformat, argv[i]);
531
Mark Salyzyna1062c72013-11-22 10:55:48 -0800532 if (err < 0) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800533 fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]);
534 android::show_help(argv[0]);
535 exit(-1);
536 }
537 }
538 }
539
Joe Onorato6fa09a02010-02-26 10:04:23 -0800540 dev = devices;
Mark Salyzyna1062c72013-11-22 10:55:48 -0800541 logger_list = android_logger_list_alloc(mode, tail_lines, 0);
Joe Onorato6fa09a02010-02-26 10:04:23 -0800542 while (dev) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800543 dev->logger_list = logger_list;
544 dev->logger = android_logger_open(logger_list,
545 android_name_to_log_id(dev->device));
546 if (!dev->logger) {
547 fprintf(stderr, "Unable to open log device '%s'\n", dev->device);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800548 exit(EXIT_FAILURE);
549 }
Joe Onorato6fa09a02010-02-26 10:04:23 -0800550
551 if (clearLog) {
552 int ret;
Mark Salyzyna1062c72013-11-22 10:55:48 -0800553 ret = android_logger_clear(dev->logger);
Joe Onorato6fa09a02010-02-26 10:04:23 -0800554 if (ret) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800555 perror("clearLog");
Joe Onorato6fa09a02010-02-26 10:04:23 -0800556 exit(EXIT_FAILURE);
557 }
Joe Onorato6fa09a02010-02-26 10:04:23 -0800558 }
559
560 if (getLogSize) {
561 int size, readable;
562
Mark Salyzyna1062c72013-11-22 10:55:48 -0800563 size = android_logger_get_log_size(dev->logger);
Joe Onorato6fa09a02010-02-26 10:04:23 -0800564 if (size < 0) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800565 perror("getLogSize");
Joe Onorato6fa09a02010-02-26 10:04:23 -0800566 exit(EXIT_FAILURE);
567 }
568
Mark Salyzyna1062c72013-11-22 10:55:48 -0800569 readable = android_logger_get_log_readable_size(dev->logger);
Joe Onorato6fa09a02010-02-26 10:04:23 -0800570 if (readable < 0) {
Mark Salyzyna1062c72013-11-22 10:55:48 -0800571 perror("getLogReadableSize");
Joe Onorato6fa09a02010-02-26 10:04:23 -0800572 exit(EXIT_FAILURE);
573 }
574
575 printf("%s: ring buffer is %dKb (%dKb consumed), "
576 "max entry is %db, max payload is %db\n", dev->device,
577 size / 1024, readable / 1024,
578 (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD);
579 }
580
581 dev = dev->next;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800582 }
583
584 if (getLogSize) {
Kenny Root4bf3c022011-09-30 17:10:14 -0700585 exit(0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800586 }
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800587 if (clearLog) {
Kenny Root4bf3c022011-09-30 17:10:14 -0700588 exit(0);
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800589 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800590
591 //LOG_EVENT_INT(10, 12345);
592 //LOG_EVENT_LONG(11, 0x1122334455667788LL);
593 //LOG_EVENT_STRING(0, "whassup, doc?");
594
Joe Onorato6fa09a02010-02-26 10:04:23 -0800595 if (needBinary)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800596 android::g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE);
597
Mark Salyzyna1062c72013-11-22 10:55:48 -0800598 while (1) {
599 struct log_msg log_msg;
600 int ret = android_logger_list_read(logger_list, &log_msg);
601
602 if (ret == 0) {
603 fprintf(stderr, "read: Unexpected EOF!\n");
604 exit(EXIT_FAILURE);
605 }
606
607 if (ret < 0) {
608 if (ret == -EAGAIN) {
609 break;
610 }
611
612 if (ret == -EIO) {
613 fprintf(stderr, "read: Unexpected EOF!\n");
614 exit(EXIT_FAILURE);
615 }
616 if (ret == -EINVAL) {
617 fprintf(stderr, "read: unexpected length.\n");
618 exit(EXIT_FAILURE);
619 }
620 perror("logcat read");
621 exit(EXIT_FAILURE);
622 }
623
624 for(dev = devices; dev; dev = dev->next) {
625 if (android_name_to_log_id(dev->device) == log_msg.id()) {
626 break;
627 }
628 }
629 if (!dev) {
630 fprintf(stderr, "read: Unexpected log ID!\n");
631 exit(EXIT_FAILURE);
632 }
633
634 android::maybePrintStart(dev);
635 if (android::g_printBinary) {
636 android::printBinary(&log_msg);
637 } else {
638 android::processBuffer(dev, &log_msg);
639 }
640 }
641
642 android_logger_list_free(logger_list);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800643
644 return 0;
645}