1018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/*
2018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** Copyright 2013-2014, The Android Open Source Project
3018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn**
4018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** Licensed under the Apache License, Version 2.0 (the "License");
5018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** you may not use this file except in compliance with the License.
6018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** You may obtain a copy of the License at
7018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn**
8018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn**     http://www.apache.org/licenses/LICENSE-2.0
9018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn**
10018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** Unless required by applicable law or agreed to in writing, software
11018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** distributed under the License is distributed on an "AS IS" BASIS,
12018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** See the License for the specific language governing permissions and
14018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn** limitations under the License.
15018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn*/
16018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
17018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <errno.h>
18018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <fcntl.h>
19018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <pthread.h>
20018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <sched.h>
21018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <stddef.h>
22018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <stdlib.h>
23018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <string.h>
24018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <unistd.h>
25018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
266584d0a35ab7722bdc6590525dee29f72f0ec576Mark Salyzyn#include <android/log.h>
27018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <cutils/list.h>
28c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn#include <private/android_filesystem_config.h>
29018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
30018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "config_read.h"
31018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "log_portability.h"
32018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "logger.h"
33018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
34018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* android_logger_alloc unimplemented, no use case */
35018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* android_logger_free not exported */
362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic void android_logger_free(struct logger* logger) {
372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger* logger_internal =
382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (struct android_log_logger*)logger;
39018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger_internal) {
412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return;
422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
43018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_remove(&logger_internal->node);
45018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  free(logger_internal);
47018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
48018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
49018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* android_logger_alloc unimplemented, no use case */
50018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
51018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* method for getting the associated sublog id */
522ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC log_id_t android_logger_get_id(struct logger* logger) {
532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return ((struct android_log_logger*)logger)->logId;
54018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
55018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int init_transport_context(struct android_log_logger_list* logger_list) {
572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_read* transport;
582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct listnode* node;
59018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger_list) {
612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -EINVAL;
622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
63018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (list_empty(&logger_list->logger)) {
652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -EINVAL;
662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
67018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!list_empty(&logger_list->transport)) {
692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return 0;
702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_lock();
732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* mini __write_to_log_initialize() to populate transports */
742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (list_empty(&__android_log_transport_read) &&
752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      list_empty(&__android_log_persist_read)) {
762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    __android_log_config_read();
772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_unlock();
792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  node = (logger_list->mode & ANDROID_LOG_PSTORE)
812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn             ? &__android_log_persist_read
822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn             : &__android_log_transport_read;
832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  read_transport_for_each(transport, node) {
852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct android_log_transport_context* transp;
862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct android_log_logger* logger;
872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    unsigned logMask = 0;
882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    logger_for_each(logger, logger_list) {
902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      log_id_t logId = logger->logId;
912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if ((logId == LOG_ID_SECURITY) && (__android_log_uid() != AID_SYSTEM)) {
932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        continue;
942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (transport->read &&
962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          (!transport->available || (transport->available(logId) >= 0))) {
972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        logMask |= 1 << logId;
982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
99018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
1002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!logMask) {
1012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      continue;
102018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
1032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    transp = calloc(1, sizeof(*transp));
1042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!transp) {
1052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return -ENOMEM;
106018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
1072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    transp->parent = logger_list;
1082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    transp->transport = transport;
1092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    transp->logMask = logMask;
1102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    transp->ret = 1;
1112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    list_add_tail(&logger_list->transport, &transp->node);
1122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
1132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (list_empty(&logger_list->transport)) {
1142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -ENODEV;
1152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
1162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return 0;
117018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
118018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
1192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn#define LOGGER_FUNCTION(logger, def, func, args...)                   \
1202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  ssize_t ret = -EINVAL;                                              \
1212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_context* transp;                       \
1222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger* logger_internal =                        \
1232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (struct android_log_logger*)(logger);                           \
1242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                                      \
1252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger_internal) {                                             \
1262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return ret;                                                       \
1272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }                                                                   \
1282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  ret = init_transport_context(logger_internal->parent);              \
1292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (ret < 0) {                                                      \
1302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return ret;                                                       \
1312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }                                                                   \
1322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                                      \
1332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  ret = (def);                                                        \
1342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  transport_context_for_each(transp, logger_internal->parent) {       \
1352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if ((transp->logMask & (1 << logger_internal->logId)) &&          \
1362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        transp->transport && transp->transport->func) {               \
1372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      ssize_t retval =                                                \
1382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          (transp->transport->func)(logger_internal, transp, ##args); \
1392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if ((ret >= 0) || (ret == (def))) {                             \
1402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        ret = retval;                                                 \
1412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }                                                               \
1422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }                                                                 \
1432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }                                                                   \
1442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return ret
1452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
1462ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int android_logger_clear(struct logger* logger) {
1472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_FUNCTION(logger, -ENODEV, clear);
148018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
149018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
150018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* returns the total size of the log's ring buffer */
1512ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC long android_logger_get_log_size(struct logger* logger) {
1522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_FUNCTION(logger, -ENODEV, getSize);
153018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
154018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
1552ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int android_logger_set_log_size(struct logger* logger,
1562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                  unsigned long size) {
1572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_FUNCTION(logger, -ENODEV, setSize, size);
158018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
159018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
160018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/*
161018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn * returns the readable size of the log's ring buffer (that is, amount of the
162018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn * log consumed)
163018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn */
164018a96d03f0d452bf078084eedcd5693da42308dMark SalyzynLIBLOG_ABI_PUBLIC long android_logger_get_log_readable_size(
1652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct logger* logger) {
1662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_FUNCTION(logger, -ENODEV, getReadableSize);
167018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
168018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
169018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/*
170018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn * returns the logger version
171018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn */
1722ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int android_logger_get_log_version(struct logger* logger) {
1732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_FUNCTION(logger, 4, version);
174018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
175018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
1762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...)              \
1772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_context* transp;                            \
1782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger_list* logger_list_internal =                   \
1792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (struct android_log_logger_list*)(logger_list);                      \
1802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                                           \
1812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  ssize_t ret = init_transport_context(logger_list_internal);              \
1822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (ret < 0) {                                                           \
1832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return ret;                                                            \
1842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }                                                                        \
1852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                                           \
1862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  ret = (def);                                                             \
1872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  transport_context_for_each(transp, logger_list_internal) {               \
1882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (transp->transport && (transp->transport->func)) {                  \
1892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      ssize_t retval =                                                     \
1902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          (transp->transport->func)(logger_list_internal, transp, ##args); \
1912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if ((ret >= 0) || (ret == (def))) {                                  \
1922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        ret = retval;                                                      \
1932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }                                                                    \
1942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }                                                                      \
1952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }                                                                        \
1962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return ret
197018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
198018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/*
199018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn * returns statistics
200018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn */
201018a96d03f0d452bf078084eedcd5693da42308dMark SalyzynLIBLOG_ABI_PUBLIC ssize_t android_logger_get_statistics(
2022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct logger_list* logger_list, char* buf, size_t len) {
2032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getStats, buf, len);
204018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
205018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
206018a96d03f0d452bf078084eedcd5693da42308dMark SalyzynLIBLOG_ABI_PUBLIC ssize_t android_logger_get_prune_list(
2072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct logger_list* logger_list, char* buf, size_t len) {
2082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getPrune, buf, len);
209018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
210018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
211018a96d03f0d452bf078084eedcd5693da42308dMark SalyzynLIBLOG_ABI_PUBLIC int android_logger_set_prune_list(
2122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct logger_list* logger_list, char* buf, size_t len) {
2132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);
214018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
215018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2162ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_HIDDEN struct listnode __android_log_readers = { &__android_log_readers,
2172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                        &__android_log_readers };
218cf983bcbae801e4660521b9747d9a7516e7df1c1Mark Salyzyn#if !defined(_WIN32)
219cf983bcbae801e4660521b9747d9a7516e7df1c1Mark SalyzynLIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock =
220cf983bcbae801e4660521b9747d9a7516e7df1c1Mark Salyzyn    PTHREAD_RWLOCK_INITIALIZER;
221cf983bcbae801e4660521b9747d9a7516e7df1c1Mark Salyzyn#endif
222cf983bcbae801e4660521b9747d9a7516e7df1c1Mark Salyzyn
2232ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_alloc(
2242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    int mode, unsigned int tail, pid_t pid) {
2252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger_list* logger_list;
226018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list = calloc(1, sizeof(*logger_list));
2282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger_list) {
2292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return NULL;
2302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
231018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_init(&logger_list->logger);
2332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_init(&logger_list->transport);
2342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list->mode = mode;
2352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list->tail = tail;
2362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list->pid = pid;
237018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list_wrlock();
2392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_add_tail(&__android_log_readers, &logger_list->node);
2402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list_unlock();
241cf983bcbae801e4660521b9747d9a7516e7df1c1Mark Salyzyn
2422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return (struct logger_list*)logger_list;
243018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
244018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2452ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_alloc_time(
2462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    int mode, log_time start, pid_t pid) {
2472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger_list* logger_list;
248018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list = calloc(1, sizeof(*logger_list));
2502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger_list) {
2512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return NULL;
2522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
253018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_init(&logger_list->logger);
2552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_init(&logger_list->transport);
2562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list->mode = mode;
2572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list->start = start;
2582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list->pid = pid;
259018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list_wrlock();
2612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_add_tail(&__android_log_readers, &logger_list->node);
2622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list_unlock();
263cf983bcbae801e4660521b9747d9a7516e7df1c1Mark Salyzyn
2642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return (struct logger_list*)logger_list;
265018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
266018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
267018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* android_logger_list_register unimplemented, no use case */
268018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* android_logger_list_unregister unimplemented, no use case */
269018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
270018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* Open the named log and add it to the logger list */
2712ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC struct logger* android_logger_open(
2722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct logger_list* logger_list, log_id_t logId) {
2732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger_list* logger_list_internal =
2742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (struct android_log_logger_list*)logger_list;
2752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger* logger;
2762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
2772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger_list_internal || (logId >= LOG_ID_MAX)) {
2782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    goto err;
2792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
2802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
2812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_for_each(logger, logger_list_internal) {
2822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (logger->logId == logId) {
2832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      goto ok;
284018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
2852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
286018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger = calloc(1, sizeof(*logger));
2882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger) {
2892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    goto err;
2902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
291018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger->logId = logId;
2932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_add_tail(&logger_list_internal->logger, &logger->node);
2942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger->parent = logger_list_internal;
295018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* Reset known transports to re-evaluate, we just added one */
2972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  while (!list_empty(&logger_list_internal->transport)) {
2982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct listnode* node = list_head(&logger_list_internal->transport);
2992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct android_log_transport_context* transp =
3002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        node_to_item(node, struct android_log_transport_context, node);
301018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
3022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    list_remove(&transp->node);
3032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    free(transp);
3042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  goto ok;
306018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
307018a96d03f0d452bf078084eedcd5693da42308dMark Salyzynerr:
3082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger = NULL;
309018a96d03f0d452bf078084eedcd5693da42308dMark Salyzynok:
3102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return (struct logger*)logger;
311018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
312018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
313018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* Open the single named log and make it part of a new logger list */
3142ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_open(
3152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    log_id_t logId, int mode, unsigned int tail, pid_t pid) {
3162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid);
317018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
3182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!logger_list) {
3192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return NULL;
3202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!android_logger_open(logger_list, logId)) {
3232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    android_logger_list_free(logger_list);
3242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return NULL;
3252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
326018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
3272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return logger_list;
328018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
329018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
3308fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn/* Validate log_msg packet, read function has already been null checked */
3312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int android_transport_read(struct android_log_logger_list* logger_list,
3322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                  struct android_log_transport_context* transp,
3332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                  struct log_msg* log_msg) {
3342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  int ret = (*transp->transport->read)(logger_list, transp, log_msg);
3358fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn
3362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (ret > (int)sizeof(*log_msg)) {
3372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ret = sizeof(*log_msg);
3382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3398fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn
3402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  transp->ret = ret;
3418fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn
3422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* propagate errors, or make sure len & hdr_size members visible */
3432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (ret < (int)(sizeof(log_msg->entry.len) + sizeof(log_msg->entry.hdr_size))) {
3442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (ret >= (int)sizeof(log_msg->entry.len)) {
3452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      log_msg->entry.len = 0;
3468fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn    }
3478fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn    return ret;
3482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* hdr_size correction (logger_entry -> logger_entry_v2+ conversion) */
3512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (log_msg->entry_v2.hdr_size == 0) {
3522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    log_msg->entry_v2.hdr_size = sizeof(struct logger_entry);
3532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if ((log_msg->entry_v2.hdr_size < sizeof(log_msg->entry_v1)) ||
3552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (log_msg->entry_v2.hdr_size > sizeof(log_msg->entry))) {
3562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -EINVAL;
3572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* len validation */
3602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (ret <= log_msg->entry_v2.hdr_size) {
3612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    log_msg->entry.len = 0;
3622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else {
3632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    log_msg->entry.len = ret - log_msg->entry_v2.hdr_size;
3642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return ret;
3678fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn}
3688fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn
369018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* Read from the selected logs */
3702ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int android_logger_list_read(struct logger_list* logger_list,
3712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                               struct log_msg* log_msg) {
3722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_context* transp;
3732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger_list* logger_list_internal =
3742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (struct android_log_logger_list*)logger_list;
3752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  int ret = init_transport_context(logger_list_internal);
3772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (ret < 0) {
3782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return ret;
3792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* at least one transport */
3822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  transp = node_to_item(logger_list_internal->transport.next,
3832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                        struct android_log_transport_context, node);
3842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* more than one transport? */
3862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (transp->node.next != &logger_list_internal->transport) {
3872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    /* Poll and merge sort the entries if from multiple transports */
3882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct android_log_transport_context* oldest = NULL;
3892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    int ret;
3902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    int polled = 0;
3912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    do {
3922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (polled) {
3932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        sched_yield();
3942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
3952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      ret = -1000;
3962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      polled = 0;
3972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      do {
3982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        int retval = transp->ret;
3992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        if ((retval > 0) && !transp->logMsg.entry.len) {
4002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          if (!transp->transport->read) {
4012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            retval = transp->ret = 0;
4022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          } else if ((logger_list_internal->mode & ANDROID_LOG_NONBLOCK) ||
4032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                     !transp->transport->poll) {
4042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            retval = android_transport_read(logger_list_internal, transp,
4052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                            &transp->logMsg);
4062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          } else {
4072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            int pollval =
4082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                (*transp->transport->poll)(logger_list_internal, transp);
4092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            if (pollval <= 0) {
4102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              sched_yield();
4112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              pollval = (*transp->transport->poll)(logger_list_internal, transp);
412018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn            }
4132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            polled = 1;
4142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            if (pollval < 0) {
4152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              if ((pollval == -EINTR) || (pollval == -EAGAIN)) {
4162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                return -EAGAIN;
4172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              }
4182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              retval = transp->ret = pollval;
4192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            } else if (pollval > 0) {
4202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              retval = android_transport_read(logger_list_internal, transp,
4212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                              &transp->logMsg);
422018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn            }
4232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          }
4242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        }
4252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        if (ret < retval) {
4262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          ret = retval;
427018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn        }
4282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        if ((transp->ret > 0) && transp->logMsg.entry.len &&
4292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            (!oldest || (oldest->logMsg.entry.sec > transp->logMsg.entry.sec) ||
4302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn             ((oldest->logMsg.entry.sec == transp->logMsg.entry.sec) &&
4312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              (oldest->logMsg.entry.nsec > transp->logMsg.entry.nsec)))) {
4322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          oldest = transp;
4338fd1faa596bd6e08c697ac97a4d531d4cea4256aMark Salyzyn        }
4342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        transp = node_to_item(transp->node.next,
4352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                              struct android_log_transport_context, node);
4362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      } while (transp != node_to_item(&logger_list_internal->transport,
4372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                      struct android_log_transport_context,
4382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                      node));
4392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (!oldest && (logger_list_internal->mode & ANDROID_LOG_NONBLOCK)) {
4402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        return (ret < 0) ? ret : -EAGAIN;
4412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
4422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      transp = node_to_item(logger_list_internal->transport.next,
4432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                            struct android_log_transport_context, node);
4442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    } while (!oldest && (ret > 0));
4452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!oldest) {
4462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return ret;
4472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
4482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    // ret is a positive value less than sizeof(struct log_msg)
4492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ret = oldest->ret;
4502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (ret < oldest->logMsg.entry.hdr_size) {
4512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      // zero truncated header fields.
4522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      memset(log_msg, 0,
4532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn             (oldest->logMsg.entry.hdr_size > sizeof(oldest->logMsg)
4542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                  ? sizeof(oldest->logMsg)
4552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                  : oldest->logMsg.entry.hdr_size));
456018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
4572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    memcpy(log_msg, &oldest->logMsg, ret);
4582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    oldest->logMsg.entry.len = 0; /* Mark it as copied */
4592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return ret;
4602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
461018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
4622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* if only one, no need to copy into transport_context and merge-sort */
4632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return android_transport_read(logger_list_internal, transp, log_msg);
464018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
465018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
466018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/* Close all the logs */
4672ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC void android_logger_list_free(struct logger_list* logger_list) {
4682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_logger_list* logger_list_internal =
4692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (struct android_log_logger_list*)logger_list;
470018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
4712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (logger_list_internal == NULL) {
4722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return;
4732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
474018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
4752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list_wrlock();
4762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  list_remove(&logger_list_internal->node);
4772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  logger_list_unlock();
478cf983bcbae801e4660521b9747d9a7516e7df1c1Mark Salyzyn
4792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  while (!list_empty(&logger_list_internal->transport)) {
4802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct listnode* node = list_head(&logger_list_internal->transport);
4812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct android_log_transport_context* transp =
4822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        node_to_item(node, struct android_log_transport_context, node);
483018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
4842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (transp->transport && transp->transport->close) {
4852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (*transp->transport->close)(logger_list_internal, transp);
486018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
4872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    list_remove(&transp->node);
4882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    free(transp);
4892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
4902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
4912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  while (!list_empty(&logger_list_internal->logger)) {
4922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct listnode* node = list_head(&logger_list_internal->logger);
4932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct android_log_logger* logger =
4942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        node_to_item(node, struct android_log_logger, node);
4952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    android_logger_free((struct logger*)logger);
4962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
4972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
4982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  free(logger_list_internal);
499018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
500