11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved.
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions of source code must retain the above copyright
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    the documentation and/or other materials provided with the
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    distribution.
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <time.h>
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <pthread.h>
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h>
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h>
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/uio.h>
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <arpa/inet.h>
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdarg.h>
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <fcntl.h>
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "logd.h"
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
436c8a2f2a5bc8d612ee953f528f2b5eb35983656aDavid 'Digit' Turner/* should match system/core/include/cutils/logger.h */
446c8a2f2a5bc8d612ee953f528f2b5eb35983656aDavid 'Digit' Turner#define LOGGER_LOG_MAIN     "log/main"
456c8a2f2a5bc8d612ee953f528f2b5eb35983656aDavid 'Digit' Turner#define LOGGER_LOG_RADIO    "log/radio"
466c8a2f2a5bc8d612ee953f528f2b5eb35983656aDavid 'Digit' Turner#define LOGGER_LOG_EVENTS   "log/events"
476c8a2f2a5bc8d612ee953f528f2b5eb35983656aDavid 'Digit' Turner#define LOGGER_LOG_SYSTEM   "log/system"
486c8a2f2a5bc8d612ee953f528f2b5eb35983656aDavid 'Digit' Turner
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <pthread.h>
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
51c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru/* IMPORTANT IMPORTANT IMPORTANT: TECHNICAL NOTE
52c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru *
53c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru * Some of the functions below can be called when our malloc() implementation
54c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru * has detected that the heap is corrupted, or even from a signal handler.
55c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru *
56c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru * These functions should *not* use a function that allocates heap memory
57c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru * or is not signal-safe. Using direct system calls is acceptable, and we
58c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru * also assume that pthread_mutex_lock/unlock can be used too.
59c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru */
60c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru
616c8a2f2a5bc8d612ee953f528f2b5eb35983656aDavid 'Digit' Turner#define LOG_BUF_SIZE    1024
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef enum {
64cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    LOG_ID_NONE = 0,
65cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    LOG_ID_MAIN,
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    LOG_ID_RADIO,
678b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    LOG_ID_EVENTS,
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    LOG_ID_MAX
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} log_id_t;
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
71cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov/* logger handles writing to object, pointed by log channel id */
72cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasovtypedef int (*logger_function_t)(log_id_t log_id, struct iovec *vec);
73cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov
74cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasovtypedef struct {
75cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    logger_function_t logger;
76cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    int               fd;
77cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    const char        *path;
78cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov} log_channel_t;
79cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov
80cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasovstatic int __write_to_log_init(log_id_t log_id, struct iovec *vec);
81cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasovstatic int __write_to_log_null(log_id_t log_id, struct iovec *vec);
82cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
855cdb2b73d269580b66297c84d9395f5f9b62d963Andy McFaddenstatic log_channel_t log_channels[LOG_ID_MAX] = {
86cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    { __write_to_log_null, -1, NULL },
87cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    { __write_to_log_init, -1, "/dev/"LOGGER_LOG_MAIN },
888b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    { __write_to_log_init, -1, "/dev/"LOGGER_LOG_RADIO },
898b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    { __write_to_log_init, -1, "/dev/"LOGGER_LOG_EVENTS }
90cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov};
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
92c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru/* Important: see technical note at start of source file */
93cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasovstatic int __write_to_log_null(log_id_t log_id, struct iovec *vec)
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
95c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru    /*
96cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov     * ALTERED behaviour from previous version
97cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov     * always returns successful result
98cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov     */
99cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    int    i = 0;
100cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    size_t res = 0;
101cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov
102cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    for ( ; i < 3; ++i) {
103cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov        res += vec[i].iov_len;
104cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    }
105cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov
106cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    return (int)res;
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
109cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov/*
110cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov *  it's supposed, that log_id contains valid id always.
111cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov *  this check must be performed in higher level functions
112cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov */
113c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru/* Important: see technical note at start of source file */
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int __write_to_log_kernel(log_id_t log_id, struct iovec *vec)
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
116c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru    return TEMP_FAILURE_RETRY( writev(log_channels[log_id].fd, vec, 3) );
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
119c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru/* Important: see technical note at start of source file */
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int __write_to_log_init(log_id_t log_id, struct iovec *vec)
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
122cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    if ((LOG_ID_NONE < log_id) && (log_id < LOG_ID_MAX)) {
123c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru        int fd;
124c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru
125cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov        pthread_mutex_lock(&log_init_lock);
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
127c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru        fd = TEMP_FAILURE_RETRY(open(log_channels[log_id].path, O_WRONLY));
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
129cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov        log_channels[log_id].logger =
130cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov            (fd < 0) ? __write_to_log_null : __write_to_log_kernel;
1315cdb2b73d269580b66297c84d9395f5f9b62d963Andy McFadden        log_channels[log_id].fd = fd;
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
133c22da7ed32f8b537b8e4653fd777056e8315ebdfAlexey Tarasov        log_channels[log_id].fd = fd;
134c22da7ed32f8b537b8e4653fd777056e8315ebdfAlexey Tarasov
135cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov        pthread_mutex_unlock(&log_init_lock);
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
137cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov        return log_channels[log_id].logger(log_id, vec);
138cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    }
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
140cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    /* log_id is invalid */
141cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    return -1;
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
144c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru/* Important: see technical note at start of source file */
145c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru__LIBC_HIDDEN__
146c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queruint __libc_android_log_write(int prio, const char *tag, const char *msg)
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    struct iovec vec[3];
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    log_id_t log_id = LOG_ID_MAIN;
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
151cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    if (tag == NULL)
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        tag = "";
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    if (!strcmp(tag, "HTC_RIL"))
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        log_id = LOG_ID_RADIO;
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vec[0].iov_base   = (unsigned char *) &prio;
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vec[0].iov_len    = 1;
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vec[1].iov_base   = (void *) tag;
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vec[1].iov_len    = strlen(tag) + 1;
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vec[2].iov_base   = (void *) msg;
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vec[2].iov_len    = strlen(msg) + 1;
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
164cc05d1271680d6a7804bc89d3b1fe14c40b32396Alexey Tarasov    return log_channels[log_id].logger(log_id, vec);
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
167c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru/* The functions below are not designed to be called from a heap panic
168c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru * function or from a signal handler. As such, they are free to use complex
169c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru * C library functions like vsnprintf()
170c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru */
171c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru__LIBC_HIDDEN__
172c4eee3765bf9dd81ff055e70ff7daa83a3926d2aDavid 'Digit' Turnerint __libc_android_log_vprint(int prio, const char *tag, const char *fmt,
173c4eee3765bf9dd81ff055e70ff7daa83a3926d2aDavid 'Digit' Turner                              va_list ap)
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
175c4eee3765bf9dd81ff055e70ff7daa83a3926d2aDavid 'Digit' Turner    char buf[LOG_BUF_SIZE];
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
179c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru    return __libc_android_log_write(prio, tag, buf);
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
182c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru__LIBC_HIDDEN__
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint __libc_android_log_print(int prio, const char *tag, const char *fmt, ...)
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    va_list ap;
186c4eee3765bf9dd81ff055e70ff7daa83a3926d2aDavid 'Digit' Turner    char buf[LOG_BUF_SIZE];
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    va_start(ap, fmt);
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    va_end(ap);
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
192c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru    return __libc_android_log_write(prio, tag, buf);
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
195c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru__LIBC_HIDDEN__
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint __libc_android_log_assert(const char *cond, const char *tag,
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			      const char *fmt, ...)
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    va_list ap;
200c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru    char buf[LOG_BUF_SIZE];
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    va_start(ap, fmt);
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    va_end(ap);
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
206c99376836021e6623516cf38d42259d38e1a480fJean-Baptiste Queru    __libc_android_log_write(ANDROID_LOG_FATAL, tag, buf);
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    exit(1);
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    return -1;
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2128b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra
2138b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra/*
2148b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra * Event logging.
2158b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra */
2168b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra
2178b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra// must be kept in sync with frameworks/base/core/java/android/util/EventLog.java
2188b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condratypedef enum {
2198b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    EVENT_TYPE_INT      = 0,
2208b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    EVENT_TYPE_LONG     = 1,
2218b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    EVENT_TYPE_STRING   = 2,
2228b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    EVENT_TYPE_LIST     = 3,
2238b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra} AndroidEventLogType;
2248b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra
2258b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condrastatic int __libc_android_log_btwrite(int32_t tag, char type, const void *payload, size_t len)
2268b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra{
2278b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    struct iovec vec[3];
2288b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra
2298b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    vec[0].iov_base = &tag;
2308b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    vec[0].iov_len = sizeof(tag);
2318b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    vec[1].iov_base = &type;
2328b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    vec[1].iov_len = sizeof(type);
2338b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    vec[2].iov_base = (void*)payload;
2348b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    vec[2].iov_len = len;
2358b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra
2368b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    return log_channels[LOG_ID_EVENTS].logger(LOG_ID_EVENTS, vec);
2378b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra}
2388b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra
2398b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra__LIBC_HIDDEN__
2408b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condravoid __libc_android_log_event_int(int32_t tag, int value)
2418b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra{
2428b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    __libc_android_log_btwrite(tag, EVENT_TYPE_INT, &value, sizeof(value));
2438b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra}
2448b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra
2458b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra__LIBC_HIDDEN__
2468b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condravoid __libc_android_log_event_uid(int32_t tag)
2478b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra{
2488b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra    __libc_android_log_event_int(tag, getuid());
2498b11c4cec21dc8eedd153866ce738614cfae57e6Geremy Condra}
250