1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn * Copyright (C) 2007-2016 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
17154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <errno.h>
18d45d36e011bf2a42bffac07424d3990022287f3cMark Salyzyn#include <stdatomic.h>
19154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <stdlib.h>
20154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <string.h>
21018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include <sys/time.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23c68fedce06da19de4fde0ae0683ad2a8916586f7Dan Albert#ifdef __BIONIC__
24c68fedce06da19de4fde0ae0683ad2a8916586f7Dan Albert#include <android/set_abort_message.h>
25c68fedce06da19de4fde0ae0683ad2a8916586f7Dan Albert#endif
26c68fedce06da19de4fde0ae0683ad2a8916586f7Dan Albert
27a0140047525b3c12e9e64903fb7b85fea0d5a0f9Mark Salyzyn#include <log/event_tag_map.h>
2881321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn#include <log/log_transport.h>
29154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn#include <private/android_filesystem_config.h>
307a80940121f0b7dac2a4dc8d08d8f5f67d8335ebMark Salyzyn#include <private/android_logger.h>
31e9c4196980208124066fb45fa03bfb85fe1d8581Mark Salyzyn
3271002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn#include "config_read.h" /* __android_log_config_read_close() definition */
33018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "config_write.h"
34018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "log_portability.h"
35018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "logger.h"
36be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark Salyzyn
37cf4aa030ce113ab4e18f41ac9e92002471a1a2beMark Salyzyn#define LOG_BUF_SIZE 1024
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr);
402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int (*write_to_log)(log_id_t, struct iovec* vec,
412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                           size_t nr) = __write_to_log_init;
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This is used by the C++ code to decide if it should write logs through
45154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn * the C code.  Basically, if /dev/socket/logd is available, we're running in
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the simulator rather than a desktop tool and want to use the device.
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic enum {
492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  kLogUninitialized,
502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  kLogNotAvailable,
512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  kLogAvailable
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} g_log_status = kLogUninitialized;
5353016d8949856713ef38e666e72d662cce0c5038Mark Salyzyn
542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int check_log_uid_permissions() {
550910d2dbb924fd70911e89526ad936282c54a650Dan Willemsen#if defined(__ANDROID__)
562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  uid_t uid = __android_log_uid();
57c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn
582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* Matches clientHasLogCredentials() in logd */
592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    uid = geteuid();
61c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn    if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      gid_t gid = getgid();
632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        gid = getegid();
652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          int num_groups;
672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          gid_t* groups;
682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          num_groups = getgroups(0, NULL);
702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          if (num_groups <= 0) {
712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            return -EPERM;
722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          }
732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          groups = calloc(num_groups, sizeof(gid_t));
742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          if (!groups) {
752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            return -ENOMEM;
762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          }
772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          num_groups = getgroups(num_groups, groups);
782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          while (num_groups > 0) {
792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            if (groups[num_groups - 1] == AID_LOG) {
802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn              break;
81c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn            }
822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            --num_groups;
832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          }
842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          free(groups);
852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          if (num_groups <= 0) {
862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            return -EPERM;
872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          }
88c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn        }
892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
90c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn    }
912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
92c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn#endif
932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return 0;
94c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn}
95c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn
96c33103c440517ae8fa5589c22eef795627adf793Mark Salyzynstatic void __android_log_cache_available(
972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct android_log_transport_write* node) {
982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  size_t i;
992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
1002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (node->logMask) {
1012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return;
1022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
1032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
1042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
1052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (node->write && (i != LOG_ID_KERNEL) &&
1062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        ((i != LOG_ID_SECURITY) || (check_log_uid_permissions() == 0)) &&
1072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        (!node->available || ((*node->available)(i) >= 0))) {
1082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      node->logMask |= 1 << i;
109c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn    }
1102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
111c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn}
112c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn
1132ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_dev_available() {
1142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_write* node;
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (list_empty(&__android_log_transport_write)) {
1172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return kLogUninitialized;
1182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
119c33103c440517ae8fa5589c22eef795627adf793Mark Salyzyn
1202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_transport_for_each(node, &__android_log_transport_write) {
1212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    __android_log_cache_available(node);
1222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (node->logMask) {
1232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return kLogAvailable;
124018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
1252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
1262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return kLogNotAvailable;
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
128ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn
1290910d2dbb924fd70911e89526ad936282c54a650Dan Willemsen#if defined(__ANDROID__)
130ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzynstatic atomic_uintptr_t tagMap;
131ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn#endif
132ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn
133df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn/*
134df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn * Release any logger resources. A new log write will immediately re-acquire.
135df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn */
1362ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC void __android_log_close() {
1372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_write* transport;
1380910d2dbb924fd70911e89526ad936282c54a650Dan Willemsen#if defined(__ANDROID__)
1392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  EventTagMap* m;
140ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn#endif
141df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn
1422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_lock();
143df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn
1442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_to_log = __write_to_log_init;
145df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn
1462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /*
1472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * Threads that are actively writing at this point are not held back
1482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * by a lock and are at risk of dropping the messages with a return code
1492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * -EBADF. Prefer to return error code than add the overhead of a lock to
1502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * each log writing call to guarantee delivery. In addition, anyone
1512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * calling this is doing so to release the logging resources and shut down,
1522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * for them to do so with outstanding log requests in other threads is a
1532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * disengenuous use of this function.
1542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   */
155df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn
1562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_transport_for_each(transport, &__android_log_persist_write) {
1572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (transport->close) {
1582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (*transport->close)();
159df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn    }
1602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
161df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn
1622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_transport_for_each(transport, &__android_log_transport_write) {
1632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (transport->close) {
1642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (*transport->close)();
165df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn    }
1662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
167df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn
1682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_config_write_close();
16971002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn
1700910d2dbb924fd70911e89526ad936282c54a650Dan Willemsen#if defined(__ANDROID__)
1712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /*
1722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * Additional risk here somewhat mitigated by immediately unlock flushing
1732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * the processor cache. The multi-threaded race that we choose to accept,
1742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * to minimize locking, is an atomic_load in a writer picking up a value
1752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * just prior to entering this routine. There will be an use after free.
1762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   *
1772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * Again, anyone calling this is doing so to release the logging resources
1782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * is most probably going to quiesce then shut down; or to restart after
1792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * a fork so the risk should be non-existent. For this reason we
1802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * choose a mitigation stance for efficiency instead of incuring the cost
1812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   * of a lock for every log write.
1822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn   */
1832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  m = (EventTagMap*)atomic_exchange(&tagMap, (uintptr_t)0);
184ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn#endif
185ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn
1862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_unlock();
187ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn
1880910d2dbb924fd70911e89526ad936282c54a650Dan Willemsen#if defined(__ANDROID__)
1892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (m != (EventTagMap*)(uintptr_t)-1LL) android_closeEventTagMap(m);
190ba1a798fd8073b6069165cc03289fb9399f0495bMark Salyzyn#endif
191df7a4c6bae5f85532d79a93b7d9197a2aab17825Mark Salyzyn}
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1938245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn/* log_init_lock assumed */
1942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int __write_to_log_initialize() {
1952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_write* transport;
1962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct listnode* n;
1972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  int i = 0, ret = 0;
1982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
1992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_config_write();
2002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
2012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    __android_log_cache_available(transport);
2022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!transport->logMask) {
2032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      list_remove(&transport->node);
2042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      continue;
2058245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn    }
2062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!transport->open || ((*transport->open)() < 0)) {
2072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (transport->close) {
2082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        (*transport->close)();
2092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
2102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      list_remove(&transport->node);
2112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      continue;
2122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
2132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ++ret;
2142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
2152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
2162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    __android_log_cache_available(transport);
2172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!transport->logMask) {
2182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      list_remove(&transport->node);
2192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      continue;
220018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn    }
2212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!transport->open || ((*transport->open)() < 0)) {
2222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (transport->close) {
2232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        (*transport->close)();
2242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
2252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      list_remove(&transport->node);
2262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      continue;
2278245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn    }
2282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ++i;
2292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
2302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!ret && !i) {
2312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -ENODEV;
2322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
2338245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn
2342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return ret;
2358245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn}
2368245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn
237018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn/*
238018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn * Extract a 4-byte value from a byte stream. le32toh open coded
239018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn */
2402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic inline uint32_t get4LE(const uint8_t* src) {
2412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
242018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn}
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
2442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) {
2452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct android_log_transport_write* node;
2462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  int ret;
2472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct timespec ts;
2482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  size_t len, i;
2498444eb81b37991ce0fc4ae1d8d79b01688a02426Mark Salyzyn
2502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  for (len = i = 0; i < nr; ++i) {
2512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    len += vec[i].iov_len;
2522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
2532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!len) {
2542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -EINVAL;
2552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
25631f7df5fd1016ccfdec6ba9d65cd296861b2c40fMark Salyzyn
2570910d2dbb924fd70911e89526ad936282c54a650Dan Willemsen#if defined(__ANDROID__)
2582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  clock_gettime(android_log_clockid(), &ts);
259142b43d4ab47f8f98748a9d560934a1f8f90c898Mark Salyzyn
2602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (log_id == LOG_ID_SECURITY) {
2612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (vec[0].iov_len < 4) {
2622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return -EINVAL;
2632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
264018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn
2652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ret = check_log_uid_permissions();
2662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (ret < 0) {
2672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return ret;
2682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
2692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!__android_log_security()) {
2702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      /* If only we could reset downstream logd counter */
2712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return -EPERM;
2722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
2732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else if (log_id == LOG_ID_EVENTS) {
2742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    const char* tag;
2752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    size_t len;
2762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    EventTagMap *m, *f;
2770ee8de3c2df48c579a12e60299ff820ebf3db12aMark Salyzyn
2782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (vec[0].iov_len < 4) {
2792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return -EINVAL;
2802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
281a0140047525b3c12e9e64903fb7b85fea0d5a0f9Mark Salyzyn
2822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    tag = NULL;
2832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    len = 0;
2842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    f = NULL;
2852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    m = (EventTagMap*)atomic_load(&tagMap);
2862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
2872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!m) {
2882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      ret = __android_log_trylock();
2892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      m = (EventTagMap*)atomic_load(&tagMap); /* trylock flush cache */
2902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (!m) {
2912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        m = android_openEventTagMap(NULL);
2922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        if (ret) { /* trylock failed, use local copy, mark for close */
2932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          f = m;
2942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        } else {
2952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          if (!m) { /* One chance to open map file */
2962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn            m = (EventTagMap*)(uintptr_t)-1LL;
2972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          }
2982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          atomic_store(&tagMap, (uintptr_t)m);
2990ee8de3c2df48c579a12e60299ff820ebf3db12aMark Salyzyn        }
3002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
3012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (!ret) { /* trylock succeeded, unlock */
3022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        __android_log_unlock();
3032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
3042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
3052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (m && (m != (EventTagMap*)(uintptr_t)-1LL)) {
3062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      tag = android_lookupEventTag_len(m, &len, get4LE(vec[0].iov_base));
3072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
3082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, tag, len,
3092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                        ANDROID_LOG_VERBOSE);
3102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (f) { /* local copy marked for close */
3112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      android_closeEventTagMap(f);
3122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
3132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!ret) {
3142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return -EPERM;
3152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
3162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else {
3172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    /* Validate the incoming tag, tag content can not split across iovec */
3182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    char prio = ANDROID_LOG_VERBOSE;
3192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    const char* tag = vec[0].iov_base;
3202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    size_t len = vec[0].iov_len;
3212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!tag) {
3222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      len = 0;
3232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
3242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (len > 0) {
3252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      prio = *tag;
3262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (len > 1) {
3272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        --len;
3282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        ++tag;
3292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      } else {
3302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        len = vec[1].iov_len;
3312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        tag = ((const char*)vec[1].iov_base);
332a0140047525b3c12e9e64903fb7b85fea0d5a0f9Mark Salyzyn        if (!tag) {
3332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn          len = 0;
334a0140047525b3c12e9e64903fb7b85fea0d5a0f9Mark Salyzyn        }
3352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
3362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
3372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    /* tag must be nul terminated */
3382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (tag && strnlen(tag, len) >= len) {
3392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      tag = NULL;
3402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    }
341a0140047525b3c12e9e64903fb7b85fea0d5a0f9Mark Salyzyn
3422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) {
3432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return -EPERM;
344083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    }
3452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
346018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#else
3472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* simulate clock_gettime(CLOCK_REALTIME, &ts); */
3482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  {
3492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    struct timeval tv;
3502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    gettimeofday(&tv, NULL);
3512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ts.tv_sec = tv.tv_sec;
3522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ts.tv_nsec = tv.tv_usec * 1000;
3532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
354018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#endif
355154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
3562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  ret = 0;
3572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  i = 1 << log_id;
3582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_transport_for_each(node, &__android_log_transport_write) {
3592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (node->logMask & i) {
3602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      ssize_t retval;
3612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      retval = (*node->write)(log_id, &ts, vec, nr);
3622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (ret >= 0) {
3632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        ret = retval;
3642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
3658245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn    }
3662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3678444eb81b37991ce0fc4ae1d8d79b01688a02426Mark Salyzyn
3682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  write_transport_for_each(node, &__android_log_persist_write) {
3692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (node->logMask & i) {
3702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (void)(*node->write)(log_id, &ts, vec, nr);
3718444eb81b37991ce0fc4ae1d8d79b01688a02426Mark Salyzyn    }
3722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
3738444eb81b37991ce0fc4ae1d8d79b01688a02426Mark Salyzyn
3742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return ret;
375154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn}
376154f4608aac6218af0e25c98b71d0803278c047eMark Salyzyn
3772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) {
3782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_lock();
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (write_to_log == __write_to_log_init) {
3812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    int ret;
3828245af1ffd1509d9b7cc391f8ed61b6d19105646Mark Salyzyn
3832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ret = __write_to_log_initialize();
3842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (ret < 0) {
3852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      __android_log_unlock();
3862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      if (!list_empty(&__android_log_persist_write)) {
3872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        __write_to_log_daemon(log_id, vec, nr);
3882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      }
3892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      return ret;
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    write_to_log = __write_to_log_daemon;
3932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_unlock();
3962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
3972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return write_to_log(log_id, vec, nr);
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4002ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char* tag,
4012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                          const char* msg) {
4022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
405be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio,
4062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                              const char* tag, const char* msg) {
4072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct iovec vec[3];
4082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  char tmp_tag[32];
4092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
4102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!tag) tag = "";
4112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
4122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  /* XXX: This needs to go! */
4132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if ((bufID != LOG_ID_RADIO) &&
4142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      (!strcmp(tag, "HTC_RIL") ||
4152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn       !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
4162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn       !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
4172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn       !strcmp(tag, "AT") || !strcmp(tag, "GSM") || !strcmp(tag, "STK") ||
4182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn       !strcmp(tag, "CDMA") || !strcmp(tag, "PHONE") || !strcmp(tag, "SMS"))) {
4192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    bufID = LOG_ID_RADIO;
4202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
4212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
4222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    tag = tmp_tag;
4232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
424e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato
425c7aadc49d323df9753744617d8951e1e3ff48843Dan Albert#if __BIONIC__
4262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (prio == ANDROID_LOG_FATAL) {
4272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    android_set_abort_message(msg);
4282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
429c7aadc49d323df9753744617d8951e1e3ff48843Dan Albert#endif
430c7aadc49d323df9753744617d8951e1e3ff48843Dan Albert
4312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_base = (unsigned char*)&prio;
4322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_len = 1;
4332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_base = (void*)tag;
4342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_len = strlen(tag) + 1;
4352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_base = (void*)msg;
4362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_len = strlen(msg) + 1;
437e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato
4382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return write_to_log(bufID, vec, 3);
439e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato}
440e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato
4412ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char* tag,
4422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                           const char* fmt, va_list ap) {
4432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  char buf[LOG_BUF_SIZE];
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return __android_log_write(prio, tag, buf);
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4502ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char* tag,
4512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                          const char* fmt, ...) {
4522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  va_list ap;
4532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  char buf[LOG_BUF_SIZE];
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  va_start(ap, fmt);
4562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
4572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  va_end(ap);
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return __android_log_write(prio, tag, buf);
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
462be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio,
4632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                              const char* tag, const char* fmt,
4642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                              ...) {
4652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  va_list ap;
4662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  char buf[LOG_BUF_SIZE];
467e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato
4682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  va_start(ap, fmt);
4692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
4702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  va_end(ap);
471e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato
4722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return __android_log_buf_write(bufID, prio, tag, buf);
473e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato}
474e2bf2ea4d2846031edfc52b942ad53e5467243f6Joe Onorato
4752ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC void __android_log_assert(const char* cond, const char* tag,
4762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                            const char* fmt, ...) {
4772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  char buf[LOG_BUF_SIZE];
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
4792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (fmt) {
4802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    va_list ap;
4812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    va_start(ap, fmt);
4822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
4832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    va_end(ap);
4842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else {
4852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    /* Msg not provided, log condition.  N.B. Do not use cond directly as
4862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn     * format string as it could contain spurious '%' syntax (e.g.
4872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn     * "%d" in "blocks%devs == 0").
4882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn     */
4892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if (cond)
4902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
4912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    else
4922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      strcpy(buf, "Unspecified assertion failed");
4932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
4942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
4952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  // Log assertion failures to stderr for the benefit of "adb shell" users
4962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  // and gtests (http://b/23675822).
4972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct iovec iov[2] = {
4982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    { buf, strlen(buf) }, { (char*)"\n", 1 },
4992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  };
5002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  TEMP_FAILURE_RETRY(writev(2, iov, 2));
5012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
5022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_write(ANDROID_LOG_FATAL, tag, buf);
5032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  abort(); /* abort so we have a chance to debug the situation */
5042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn           /* NOTREACHED */
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
5072ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag, const void* payload,
5082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                           size_t len) {
5092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct iovec vec[2];
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
5112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_base = &tag;
5122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_len = sizeof(tag);
5132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_base = (void*)payload;
5142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_len = len;
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
5162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return write_to_log(LOG_ID_EVENTS, vec, 2);
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
519be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,
5202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                    const void* payload,
5212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                    size_t len) {
5222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct iovec vec[2];
523083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
5242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_base = &tag;
5252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_len = sizeof(tag);
5262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_base = (void*)payload;
5272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_len = len;
528083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
5292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return write_to_log(LOG_ID_SECURITY, vec, 2);
530083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn}
531083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Like __android_log_bwrite, but takes the type as well.  Doesn't work
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * for the general case where we're generating lists of stuff, but very
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * handy if we just want to dump an integer into the log.
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
537be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type,
5382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                            const void* payload, size_t len) {
5392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct iovec vec[3];
5402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
5412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_base = &tag;
5422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_len = sizeof(tag);
5432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_base = &type;
5442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_len = sizeof(type);
5452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_base = (void*)payload;
5462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_len = len;
5472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
5482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return write_to_log(LOG_ID_EVENTS, vec, 3);
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
5502a4d05a4e38b84cf287bb2d2266c07b6f10c9deeNick Kralevich
5512a4d05a4e38b84cf287bb2d2266c07b6f10c9deeNick Kralevich/*
5522a4d05a4e38b84cf287bb2d2266c07b6f10c9deeNick Kralevich * Like __android_log_bwrite, but used for writing strings to the
5532a4d05a4e38b84cf287bb2d2266c07b6f10c9deeNick Kralevich * event log.
5542a4d05a4e38b84cf287bb2d2266c07b6f10c9deeNick Kralevich */
5552ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char* payload) {
5562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct iovec vec[4];
5572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  char type = EVENT_TYPE_STRING;
5582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  uint32_t len = strlen(payload);
5592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
5602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_base = &tag;
5612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_len = sizeof(tag);
5622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_base = &type;
5632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_len = sizeof(type);
5642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_base = &len;
5652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_len = sizeof(len);
5662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[3].iov_base = (void*)payload;
5672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[3].iov_len = len;
5682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
5692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return write_to_log(LOG_ID_EVENTS, vec, 4);
5702a4d05a4e38b84cf287bb2d2266c07b6f10c9deeNick Kralevich}
571d545d2930e042b9ff7fbbda52fea0da047148b26Rubin Xu
572d545d2930e042b9ff7fbbda52fea0da047148b26Rubin Xu/*
573d545d2930e042b9ff7fbbda52fea0da047148b26Rubin Xu * Like __android_log_security_bwrite, but used for writing strings to the
574d545d2930e042b9ff7fbbda52fea0da047148b26Rubin Xu * security log.
575d545d2930e042b9ff7fbbda52fea0da047148b26Rubin Xu */
576be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
5772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn                                                     const char* payload) {
5782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  struct iovec vec[4];
5792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  char type = EVENT_TYPE_STRING;
5802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  uint32_t len = strlen(payload);
5812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
5822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_base = &tag;
5832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[0].iov_len = sizeof(tag);
5842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_base = &type;
5852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[1].iov_len = sizeof(type);
5862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_base = &len;
5872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[2].iov_len = sizeof(len);
5882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[3].iov_base = (void*)payload;
5892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  vec[3].iov_len = len;
5902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
5912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return write_to_log(LOG_ID_SECURITY, vec, 4);
592d545d2930e042b9ff7fbbda52fea0da047148b26Rubin Xu}
593850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
5942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr) {
5952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  size_t len, i;
596850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
5972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) {
5982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -EINVAL;
5992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
600850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
6012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  for (len = i = 0; i < nr; ++i) {
6022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    len += vec[i].iov_len;
6032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
6042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (!len) {
6052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -EINVAL;
6062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
6072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return len;
608850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn}
609850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
610850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn/* Following functions need access to our internal write_to_log status */
611850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
61281321a7980903fbdb42f6bd838445c651fd7996eMark SalyzynLIBLOG_HIDDEN int __android_log_transport;
61371002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn
61481321a7980903fbdb42f6bd838445c651fd7996eMark SalyzynLIBLOG_ABI_PUBLIC int android_set_log_transport(int transport_flag) {
6152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  int retval;
61671002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn
61781321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn  if (transport_flag < 0) {
6182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return -EINVAL;
6192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
620850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
6212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  retval = LOGGER_NULL;
62271002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn
6232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_lock();
624850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
62581321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn  if (transport_flag & LOGGER_NULL) {
6262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    write_to_log = __write_to_log_null;
627850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
6282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    __android_log_unlock();
629850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
6302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    return retval;
6312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
632850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
63381321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn  __android_log_transport &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
634850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
63581321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn  transport_flag &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
63671002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn
63781321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn  if (__android_log_transport != transport_flag) {
63881321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn    __android_log_transport = transport_flag;
6392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    __android_log_config_write_close();
6402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    __android_log_config_read_close();
64171002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn
6422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    write_to_log = __write_to_log_init;
643850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn    /* generically we only expect these two values for write_to_log */
6442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else if ((write_to_log != __write_to_log_init) &&
6452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn             (write_to_log != __write_to_log_daemon)) {
6462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    write_to_log = __write_to_log_init;
6472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
648850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
64981321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn  retval = __android_log_transport;
65071002885325be3a0c4a0d09a6a6ad9b14531bdd7Mark Salyzyn
6512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_unlock();
652850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
6532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return retval;
654850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn}
655850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
65681321a7980903fbdb42f6bd838445c651fd7996eMark SalyzynLIBLOG_ABI_PUBLIC int android_get_log_transport() {
6572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  int ret = LOGGER_DEFAULT;
6582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn
6592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_lock();
6602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  if (write_to_log == __write_to_log_null) {
6612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    ret = LOGGER_NULL;
6622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  } else {
66381321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn    __android_log_transport &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR;
66481321a7980903fbdb42f6bd838445c651fd7996eMark Salyzyn    ret = __android_log_transport;
6652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn    if ((write_to_log != __write_to_log_init) &&
6662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn        (write_to_log != __write_to_log_daemon)) {
6672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn      ret = -EINVAL;
668850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn    }
6692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  }
6702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  __android_log_unlock();
671850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn
6722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn  return ret;
673850d06e1c94bd292841c3ed9d7e1c0161d84d743Mark Salyzyn}
674