liblog: specify clang format

Switch coding style to match

SideEffects: None
Test: compile
Bug: 27405083
Change-Id: Id426d5c5e3b18f2ceec22b31bbc9781aabf6bcca
This commit is contained in:
Mark Salyzyn 2017-03-09 08:09:43 -08:00
parent c1b3c8ef26
commit 2ed51d708e
52 changed files with 10147 additions and 10434 deletions

9
liblog/.clang-format Normal file
View File

@ -0,0 +1,9 @@
BasedOnStyle: Google
AllowShortFunctionsOnASingleLine: false
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
PointerAlignment: Left
PenaltyExcessCharacter: 32
Cpp11BracedListStyle: false

View File

@ -19,70 +19,68 @@
#include "config_read.h"
#include "logger.h"
LIBLOG_HIDDEN struct listnode __android_log_transport_read =
{ &__android_log_transport_read, &__android_log_transport_read };
LIBLOG_HIDDEN struct listnode __android_log_persist_read =
{ &__android_log_persist_read, &__android_log_persist_read };
LIBLOG_HIDDEN struct listnode __android_log_transport_read = {
&__android_log_transport_read, &__android_log_transport_read
};
LIBLOG_HIDDEN struct listnode __android_log_persist_read = {
&__android_log_persist_read, &__android_log_persist_read
};
static void __android_log_add_transport(
struct listnode *list, struct android_log_transport_read *transport) {
size_t i;
struct listnode* list, struct android_log_transport_read* transport) {
size_t i;
/* Try to keep one functioning transport for each log buffer id */
for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {
struct android_log_transport_read *transp;
/* Try to keep one functioning transport for each log buffer id */
for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {
struct android_log_transport_read* transp;
if (list_empty(list)) {
if (!transport->available || ((*transport->available)(i) >= 0)) {
list_add_tail(list, &transport->node);
return;
}
} else {
read_transport_for_each(transp, list) {
if (!transp->available) {
return;
}
if (((*transp->available)(i) < 0) &&
(!transport->available ||
((*transport->available)(i) >= 0))) {
list_add_tail(list, &transport->node);
return;
}
}
if (list_empty(list)) {
if (!transport->available || ((*transport->available)(i) >= 0)) {
list_add_tail(list, &transport->node);
return;
}
} else {
read_transport_for_each(transp, list) {
if (!transp->available) {
return;
}
if (((*transp->available)(i) < 0) &&
(!transport->available || ((*transport->available)(i) >= 0))) {
list_add_tail(list, &transport->node);
return;
}
}
}
}
}
LIBLOG_HIDDEN void __android_log_config_read() {
if (__android_log_frontend & LOGGER_LOCAL) {
extern struct android_log_transport_read localLoggerRead;
if (__android_log_frontend & LOGGER_LOCAL) {
extern struct android_log_transport_read localLoggerRead;
__android_log_add_transport(&__android_log_transport_read,
&localLoggerRead);
}
__android_log_add_transport(&__android_log_transport_read, &localLoggerRead);
}
#if (FAKE_LOG_DEVICE == 0)
if ((__android_log_frontend == LOGGER_DEFAULT) ||
(__android_log_frontend & LOGGER_LOGD)) {
extern struct android_log_transport_read logdLoggerRead;
extern struct android_log_transport_read pmsgLoggerRead;
if ((__android_log_frontend == LOGGER_DEFAULT) ||
(__android_log_frontend & LOGGER_LOGD)) {
extern struct android_log_transport_read logdLoggerRead;
extern struct android_log_transport_read pmsgLoggerRead;
__android_log_add_transport(&__android_log_transport_read,
&logdLoggerRead);
__android_log_add_transport(&__android_log_persist_read,
&pmsgLoggerRead);
}
__android_log_add_transport(&__android_log_transport_read, &logdLoggerRead);
__android_log_add_transport(&__android_log_persist_read, &pmsgLoggerRead);
}
#endif
}
LIBLOG_HIDDEN void __android_log_config_read_close() {
struct android_log_transport_read *transport;
struct listnode *n;
struct android_log_transport_read* transport;
struct listnode* n;
read_transport_for_each_safe(transport, n, &__android_log_transport_read) {
list_remove(&transport->node);
}
read_transport_for_each_safe(transport, n, &__android_log_persist_read) {
list_remove(&transport->node);
}
read_transport_for_each_safe(transport, n, &__android_log_transport_read) {
list_remove(&transport->node);
}
read_transport_for_each_safe(transport, n, &__android_log_persist_read) {
list_remove(&transport->node);
}
}

View File

@ -26,30 +26,26 @@ __BEGIN_DECLS
extern LIBLOG_HIDDEN struct listnode __android_log_transport_read;
extern LIBLOG_HIDDEN struct listnode __android_log_persist_read;
#define read_transport_for_each(transp, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_read, node); \
((transp) != node_to_item((transports), \
struct android_log_transport_read, \
node)) && \
((transp) != node_to_item((transp)->node.next, \
struct android_log_transport_read, \
node)); \
(transp) = node_to_item((transp)->node.next, \
struct android_log_transport_read, node))
#define read_transport_for_each(transp, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_read, node); \
((transp) != node_to_item((transports), \
struct android_log_transport_read, node)) && \
((transp) != node_to_item((transp)->node.next, \
struct android_log_transport_read, node)); \
(transp) = node_to_item((transp)->node.next, \
struct android_log_transport_read, node))
#define read_transport_for_each_safe(transp, n, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_read, node), \
(n) = (transp)->node.next; \
((transp) != node_to_item((transports), \
struct android_log_transport_read, \
node)) && \
((transp) != node_to_item((n), struct android_log_transport_read, \
node)); \
(transp) = node_to_item((n), struct android_log_transport_read, \
node), \
(n) = (transp)->node.next)
#define read_transport_for_each_safe(transp, n, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_read, node), \
(n) = (transp)->node.next; \
((transp) != node_to_item((transports), \
struct android_log_transport_read, node)) && \
((transp) != \
node_to_item((n), struct android_log_transport_read, node)); \
(transp) = node_to_item((n), struct android_log_transport_read, node), \
(n) = (transp)->node.next)
LIBLOG_HIDDEN void __android_log_config_read();
LIBLOG_HIDDEN void __android_log_config_read_close();

View File

@ -19,100 +19,100 @@
#include "config_write.h"
#include "logger.h"
LIBLOG_HIDDEN struct listnode __android_log_transport_write =
{ &__android_log_transport_write, &__android_log_transport_write };
LIBLOG_HIDDEN struct listnode __android_log_persist_write =
{ &__android_log_persist_write, &__android_log_persist_write};
LIBLOG_HIDDEN struct listnode __android_log_transport_write = {
&__android_log_transport_write, &__android_log_transport_write
};
LIBLOG_HIDDEN struct listnode __android_log_persist_write = {
&__android_log_persist_write, &__android_log_persist_write
};
static void __android_log_add_transport(
struct listnode *list, struct android_log_transport_write *transport) {
size_t i;
struct listnode* list, struct android_log_transport_write* transport) {
size_t i;
/* Try to keep one functioning transport for each log buffer id */
for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {
struct android_log_transport_write *transp;
/* Try to keep one functioning transport for each log buffer id */
for (i = LOG_ID_MIN; i < LOG_ID_MAX; i++) {
struct android_log_transport_write* transp;
if (list_empty(list)) {
if (!transport->available || ((*transport->available)(i) >= 0)) {
list_add_tail(list, &transport->node);
return;
}
} else {
write_transport_for_each(transp, list) {
if (!transp->available) {
return;
}
if (((*transp->available)(i) < 0) &&
(!transport->available ||
((*transport->available)(i) >= 0))) {
list_add_tail(list, &transport->node);
return;
}
}
if (list_empty(list)) {
if (!transport->available || ((*transport->available)(i) >= 0)) {
list_add_tail(list, &transport->node);
return;
}
} else {
write_transport_for_each(transp, list) {
if (!transp->available) {
return;
}
if (((*transp->available)(i) < 0) &&
(!transport->available || ((*transport->available)(i) >= 0))) {
list_add_tail(list, &transport->node);
return;
}
}
}
}
}
LIBLOG_HIDDEN void __android_log_config_write() {
if (__android_log_frontend & LOGGER_LOCAL) {
extern struct android_log_transport_write localLoggerWrite;
if (__android_log_frontend & LOGGER_LOCAL) {
extern struct android_log_transport_write localLoggerWrite;
__android_log_add_transport(&__android_log_transport_write,
&localLoggerWrite);
}
__android_log_add_transport(&__android_log_transport_write,
&localLoggerWrite);
}
if ((__android_log_frontend == LOGGER_DEFAULT) ||
(__android_log_frontend & LOGGER_LOGD)) {
if ((__android_log_frontend == LOGGER_DEFAULT) ||
(__android_log_frontend & LOGGER_LOGD)) {
#if (FAKE_LOG_DEVICE == 0)
extern struct android_log_transport_write logdLoggerWrite;
extern struct android_log_transport_write pmsgLoggerWrite;
extern struct android_log_transport_write logdLoggerWrite;
extern struct android_log_transport_write pmsgLoggerWrite;
__android_log_add_transport(&__android_log_transport_write,
&logdLoggerWrite);
__android_log_add_transport(&__android_log_persist_write,
&pmsgLoggerWrite);
__android_log_add_transport(&__android_log_transport_write,
&logdLoggerWrite);
__android_log_add_transport(&__android_log_persist_write, &pmsgLoggerWrite);
#else
extern struct android_log_transport_write fakeLoggerWrite;
extern struct android_log_transport_write fakeLoggerWrite;
__android_log_add_transport(&__android_log_transport_write,
&fakeLoggerWrite);
__android_log_add_transport(&__android_log_transport_write,
&fakeLoggerWrite);
#endif
}
}
if (__android_log_frontend & LOGGER_STDERR) {
extern struct android_log_transport_write stderrLoggerWrite;
if (__android_log_frontend & LOGGER_STDERR) {
extern struct android_log_transport_write stderrLoggerWrite;
/*
* stderr logger should be primary if we can be the only one, or if
* already in the primary list. Otherwise land in the persist list.
* Remember we can be called here if we are already initialized.
*/
if (list_empty(&__android_log_transport_write)) {
__android_log_add_transport(&__android_log_transport_write,
&stderrLoggerWrite);
} else {
struct android_log_transport_write *transp;
write_transport_for_each(transp, &__android_log_transport_write) {
if (transp == &stderrLoggerWrite) {
return;
}
}
__android_log_add_transport(&__android_log_persist_write,
&stderrLoggerWrite);
/*
* stderr logger should be primary if we can be the only one, or if
* already in the primary list. Otherwise land in the persist list.
* Remember we can be called here if we are already initialized.
*/
if (list_empty(&__android_log_transport_write)) {
__android_log_add_transport(&__android_log_transport_write,
&stderrLoggerWrite);
} else {
struct android_log_transport_write* transp;
write_transport_for_each(transp, &__android_log_transport_write) {
if (transp == &stderrLoggerWrite) {
return;
}
}
__android_log_add_transport(&__android_log_persist_write,
&stderrLoggerWrite);
}
}
}
LIBLOG_HIDDEN void __android_log_config_write_close() {
struct android_log_transport_write *transport;
struct listnode *n;
struct android_log_transport_write* transport;
struct listnode* n;
write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
transport->logMask = 0;
list_remove(&transport->node);
}
write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
transport->logMask = 0;
list_remove(&transport->node);
}
write_transport_for_each_safe(transport, n, &__android_log_transport_write) {
transport->logMask = 0;
list_remove(&transport->node);
}
write_transport_for_each_safe(transport, n, &__android_log_persist_write) {
transport->logMask = 0;
list_remove(&transport->node);
}
}

View File

@ -26,30 +26,26 @@ __BEGIN_DECLS
extern LIBLOG_HIDDEN struct listnode __android_log_transport_write;
extern LIBLOG_HIDDEN struct listnode __android_log_persist_write;
#define write_transport_for_each(transp, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_write, node); \
((transp) != node_to_item((transports), \
struct android_log_transport_write, \
node)) && \
((transp) != node_to_item((transp)->node.next, \
struct android_log_transport_write, \
node)); \
(transp) = node_to_item((transp)->node.next, \
struct android_log_transport_write, node))
#define write_transport_for_each(transp, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_write, node); \
((transp) != node_to_item((transports), \
struct android_log_transport_write, node)) && \
((transp) != node_to_item((transp)->node.next, \
struct android_log_transport_write, node)); \
(transp) = node_to_item((transp)->node.next, \
struct android_log_transport_write, node))
#define write_transport_for_each_safe(transp, n, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_write, node), \
(n) = (transp)->node.next; \
((transp) != node_to_item((transports), \
struct android_log_transport_write, \
node)) && \
((transp) != node_to_item((n), struct android_log_transport_write, \
node)); \
(transp) = node_to_item((n), struct android_log_transport_write, \
node), \
(n) = (transp)->node.next)
#define write_transport_for_each_safe(transp, n, transports) \
for ((transp) = node_to_item((transports)->next, \
struct android_log_transport_write, node), \
(n) = (transp)->node.next; \
((transp) != node_to_item((transports), \
struct android_log_transport_write, node)) && \
((transp) != \
node_to_item((n), struct android_log_transport_write, node)); \
(transp) = node_to_item((n), struct android_log_transport_write, node), \
(n) = (transp)->node.next)
LIBLOG_HIDDEN void __android_log_config_write();
LIBLOG_HIDDEN void __android_log_config_write_close();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,9 @@
struct iovec;
LIBLOG_HIDDEN int fakeLogOpen(const char *pathName, int flags);
LIBLOG_HIDDEN int fakeLogOpen(const char* pathName, int flags);
LIBLOG_HIDDEN int fakeLogClose(int fd);
LIBLOG_HIDDEN ssize_t fakeLogWritev(int fd,
const struct iovec* vector, int count);
LIBLOG_HIDDEN ssize_t fakeLogWritev(int fd, const struct iovec* vector,
int count);
#endif // _LIBLOG_FAKE_LOG_DEVICE_H
#endif // _LIBLOG_FAKE_LOG_DEVICE_H

View File

@ -27,78 +27,77 @@
static int fakeOpen();
static void fakeClose();
static int fakeWrite(log_id_t log_id, struct timespec *ts,
struct iovec *vec, size_t nr);
static int fakeWrite(log_id_t log_id, struct timespec* ts, struct iovec* vec,
size_t nr);
static int logFds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1, -1 };
LIBLOG_HIDDEN struct android_log_transport_write fakeLoggerWrite = {
.node = { &fakeLoggerWrite.node, &fakeLoggerWrite.node },
.context.private = &logFds,
.name = "fake",
.available = NULL,
.open = fakeOpen,
.close = fakeClose,
.write = fakeWrite,
.node = { &fakeLoggerWrite.node, &fakeLoggerWrite.node },
.context.private = &logFds,
.name = "fake",
.available = NULL,
.open = fakeOpen,
.close = fakeClose,
.write = fakeWrite,
};
static int fakeOpen() {
int i;
int i;
for (i = 0; i < LOG_ID_MAX; i++) {
/*
* Known maximum size string, plus an 8 character margin to deal with
* possible independent changes to android_log_id_to_name().
*/
char buf[sizeof("/dev/log_security") + 8];
if (logFds[i] >= 0) {
continue;
}
snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i));
logFds[i] = fakeLogOpen(buf, O_WRONLY);
if (logFds[i] < 0) {
fprintf(stderr, "fakeLogOpen(%s, O_WRONLY) failed\n", buf);
}
for (i = 0; i < LOG_ID_MAX; i++) {
/*
* Known maximum size string, plus an 8 character margin to deal with
* possible independent changes to android_log_id_to_name().
*/
char buf[sizeof("/dev/log_security") + 8];
if (logFds[i] >= 0) {
continue;
}
return 0;
snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i));
logFds[i] = fakeLogOpen(buf, O_WRONLY);
if (logFds[i] < 0) {
fprintf(stderr, "fakeLogOpen(%s, O_WRONLY) failed\n", buf);
}
}
return 0;
}
static void fakeClose() {
int i;
int i;
for (i = 0; i < LOG_ID_MAX; i++) {
fakeLogClose(logFds[i]);
logFds[i] = -1;
}
for (i = 0; i < LOG_ID_MAX; i++) {
fakeLogClose(logFds[i]);
logFds[i] = -1;
}
}
static int fakeWrite(log_id_t log_id, struct timespec *ts __unused,
struct iovec *vec, size_t nr)
{
ssize_t ret;
size_t i;
int logFd, len;
static int fakeWrite(log_id_t log_id, struct timespec* ts __unused,
struct iovec* vec, size_t nr) {
ssize_t ret;
size_t i;
int logFd, len;
if (/*(int)log_id >= 0 &&*/ (int)log_id >= (int)LOG_ID_MAX) {
return -EINVAL;
}
if (/*(int)log_id >= 0 &&*/ (int)log_id >= (int)LOG_ID_MAX) {
return -EINVAL;
}
len = 0;
for (i = 0; i < nr; ++i) {
len += vec[i].iov_len;
}
len = 0;
for (i = 0; i < nr; ++i) {
len += vec[i].iov_len;
}
if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
len = LOGGER_ENTRY_MAX_PAYLOAD;
}
if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
len = LOGGER_ENTRY_MAX_PAYLOAD;
}
logFd = logFds[(int)log_id];
ret = TEMP_FAILURE_RETRY(fakeLogWritev(logFd, vec, nr));
if (ret < 0) {
ret = -errno;
} else if (ret > len) {
ret = len;
}
logFd = logFds[(int)log_id];
ret = TEMP_FAILURE_RETRY(fakeLogWritev(logFd, vec, nr));
if (ret < 0) {
ret = -errno;
} else if (ret > len) {
ret = len;
}
return ret;
return ret;
}

View File

@ -50,8 +50,8 @@
* limit (e.g. 1023 characters max).
*
* Note that a newline character ("\n") will be appended automatically to your
* log message, if not already there. It is not possible to send several messages
* and have them appear on a single line in logcat.
* log message, if not already there. It is not possible to send several
* messages and have them appear on a single line in logcat.
*
* PLEASE USE LOGS WITH MODERATION:
*
@ -77,15 +77,15 @@ extern "C" {
* Android log priority values, in ascending priority order.
*/
typedef enum android_LogPriority {
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
ANDROID_LOG_UNKNOWN = 0,
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
/*
@ -96,16 +96,16 @@ int __android_log_write(int prio, const char* tag, const char* text);
/*
* Send a formatted string to the log, used like printf(fmt,...)
*/
int __android_log_print(int prio, const char* tag, const char* fmt, ...)
int __android_log_print(int prio, const char* tag, const char* fmt, ...)
#if defined(__GNUC__)
#ifdef __USE_MINGW_ANSI_STDIO
#if __USE_MINGW_ANSI_STDIO
__attribute__ ((__format__(gnu_printf, 3, 4)))
__attribute__((__format__(gnu_printf, 3, 4)))
#else
__attribute__ ((__format__(printf, 3, 4)))
__attribute__((__format__(printf, 3, 4)))
#endif
#else
__attribute__ ((__format__(printf, 3, 4)))
__attribute__((__format__(printf, 3, 4)))
#endif
#endif
;
@ -114,17 +114,16 @@ int __android_log_print(int prio, const char* tag, const char* fmt, ...)
* A variant of __android_log_print() that takes a va_list to list
* additional parameters.
*/
int __android_log_vprint(int prio, const char* tag,
const char* fmt, va_list ap)
int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap)
#if defined(__GNUC__)
#ifdef __USE_MINGW_ANSI_STDIO
#if __USE_MINGW_ANSI_STDIO
__attribute__ ((__format__(gnu_printf, 3, 0)))
__attribute__((__format__(gnu_printf, 3, 0)))
#else
__attribute__ ((__format__(printf, 3, 0)))
__attribute__((__format__(printf, 3, 0)))
#endif
#else
__attribute__ ((__format__(printf, 3, 0)))
__attribute__((__format__(printf, 3, 0)))
#endif
#endif
;
@ -133,18 +132,18 @@ int __android_log_vprint(int prio, const char* tag,
* Log an assertion failure and abort the process to have a chance
* to inspect it if a debugger is attached. This uses the FATAL priority.
*/
void __android_log_assert(const char* cond, const char* tag,
const char* fmt, ...)
void __android_log_assert(const char* cond, const char* tag, const char* fmt,
...)
#if defined(__GNUC__)
__attribute__ ((__noreturn__))
__attribute__((__noreturn__))
#ifdef __USE_MINGW_ANSI_STDIO
#if __USE_MINGW_ANSI_STDIO
__attribute__ ((__format__(gnu_printf, 3, 4)))
__attribute__((__format__(gnu_printf, 3, 4)))
#else
__attribute__ ((__format__(printf, 3, 4)))
__attribute__((__format__(printf, 3, 4)))
#endif
#else
__attribute__ ((__format__(printf, 3, 4)))
__attribute__((__format__(printf, 3, 4)))
#endif
#endif
;

View File

@ -21,7 +21,7 @@
extern "C" {
#endif
#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags"
#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags"
struct EventTagMap;
typedef struct EventTagMap EventTagMap;
@ -42,21 +42,23 @@ void android_closeEventTagMap(EventTagMap* map);
* Look up a tag by index. Returns the tag string, or NULL if not found.
*/
const char* android_lookupEventTag(const EventTagMap* map, unsigned int tag)
__attribute__((deprecated("use android_lookupEventTag_len() instead to minimize MAP_PRIVATE copy-on-write memory impact")));
__attribute__((
deprecated("use android_lookupEventTag_len() instead to minimize "
"MAP_PRIVATE copy-on-write memory impact")));
/*
* Look up a tag by index. Returns the tag string & string length, or NULL if
* not found. Returned string is not guaranteed to be nul terminated.
*/
const char* android_lookupEventTag_len(const EventTagMap* map,
size_t* len, unsigned int tag);
const char* android_lookupEventTag_len(const EventTagMap* map, size_t* len,
unsigned int tag);
/*
* Look up a format by index. Returns the format string & string length,
* or NULL if not found. Returned string is not guaranteed to be nul terminated.
*/
const char* android_lookupEventFormat_len(const EventTagMap* map,
size_t* len, unsigned int tag);
const char* android_lookupEventFormat_len(const EventTagMap* map, size_t* len,
unsigned int tag);
/*
* Look up tagname, generate one if necessary, and return a tag

View File

@ -21,7 +21,7 @@
#if !defined(_WIN32)
#include <pthread.h>
#endif
#include <stdint.h> /* uint16_t, int32_t */
#include <stdint.h> /* uint16_t, int32_t */
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
@ -95,9 +95,9 @@ int __android_log_btwrite(int32_t tag, char type, const void* payload,
int __android_log_bswrite(int32_t tag, const char* payload);
#define android_bWriteLog(tag, payload, len) \
__android_log_bwrite(tag, payload, len)
__android_log_bwrite(tag, payload, len)
#define android_btWriteLog(tag, type, payload, len) \
__android_log_btwrite(tag, type, payload, len)
__android_log_btwrite(tag, type, payload, len)
/*
* Event log entry types.
@ -105,45 +105,46 @@ int __android_log_bswrite(int32_t tag, const char* payload);
#ifndef __AndroidEventLogType_defined
#define __AndroidEventLogType_defined
typedef enum {
/* Special markers for android_log_list_element type */
EVENT_TYPE_LIST_STOP = '\n', /* declare end of list */
EVENT_TYPE_UNKNOWN = '?', /* protocol error */
/* Special markers for android_log_list_element type */
EVENT_TYPE_LIST_STOP = '\n', /* declare end of list */
EVENT_TYPE_UNKNOWN = '?', /* protocol error */
/* must match with declaration in java/android/android/util/EventLog.java */
EVENT_TYPE_INT = 0, /* int32_t */
EVENT_TYPE_LONG = 1, /* int64_t */
EVENT_TYPE_STRING = 2,
EVENT_TYPE_LIST = 3,
EVENT_TYPE_FLOAT = 4,
/* must match with declaration in java/android/android/util/EventLog.java */
EVENT_TYPE_INT = 0, /* int32_t */
EVENT_TYPE_LONG = 1, /* int64_t */
EVENT_TYPE_STRING = 2,
EVENT_TYPE_LIST = 3,
EVENT_TYPE_FLOAT = 4,
} AndroidEventLogType;
#endif
#define sizeof_AndroidEventLogType sizeof(typeof_AndroidEventLogType)
#define typeof_AndroidEventLogType unsigned char
#ifndef LOG_EVENT_INT
#define LOG_EVENT_INT(_tag, _value) { \
int intBuf = _value; \
(void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, \
sizeof(intBuf)); \
}
#define LOG_EVENT_INT(_tag, _value) \
{ \
int intBuf = _value; \
(void)android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, sizeof(intBuf)); \
}
#endif
#ifndef LOG_EVENT_LONG
#define LOG_EVENT_LONG(_tag, _value) { \
long long longBuf = _value; \
(void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, \
sizeof(longBuf)); \
}
#define LOG_EVENT_LONG(_tag, _value) \
{ \
long long longBuf = _value; \
(void)android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf)); \
}
#endif
#ifndef LOG_EVENT_FLOAT
#define LOG_EVENT_FLOAT(_tag, _value) { \
float floatBuf = _value; \
(void) android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf, \
sizeof(floatBuf)); \
}
#define LOG_EVENT_FLOAT(_tag, _value) \
{ \
float floatBuf = _value; \
(void)android_btWriteLog(_tag, EVENT_TYPE_FLOAT, &floatBuf, \
sizeof(floatBuf)); \
}
#endif
#ifndef LOG_EVENT_STRING
#define LOG_EVENT_STRING(_tag, _value) \
(void) __android_log_bswrite(_tag, _value);
#define LOG_EVENT_STRING(_tag, _value) \
(void)__android_log_bswrite(_tag, _value);
#endif
#ifdef __linux__
@ -179,10 +180,10 @@ clockid_t android_log_clockid();
#if __ANDROID_USE_LIBLOG_SAFETYNET_INTERFACE
#define android_errorWriteLog(tag, subTag) \
__android_log_error_write(tag, subTag, -1, NULL, 0)
__android_log_error_write(tag, subTag, -1, NULL, 0)
#define android_errorWriteWithInfoLog(tag, subTag, uid, data, dataLen) \
__android_log_error_write(tag, subTag, uid, data, dataLen)
__android_log_error_write(tag, subTag, uid, data, dataLen)
int __android_log_error_write(int tag, const char* subTag, int32_t uid,
const char* data, uint32_t dataLen);
@ -246,10 +247,9 @@ int __android_log_ratelimit(time_t seconds, time_t* last);
* }
*/
#define IF_ALOG_RATELIMIT() \
if (__android_log_ratelimit(0, NULL) > 0)
#define IF_ALOG_RATELIMIT() if (__android_log_ratelimit(0, NULL) > 0)
#define IF_ALOG_RATELIMIT_LOCAL(seconds, state) \
if (__android_log_ratelimit(seconds, state) > 0)
if (__android_log_ratelimit(seconds, state) > 0)
#else

View File

@ -61,15 +61,15 @@ typedef struct android_log_context_internal* android_log_context;
#ifndef __android_log_list_element_defined
#define __android_log_list_element_defined
typedef struct {
AndroidEventLogType type;
uint16_t complete;
uint16_t len;
union {
int32_t int32;
int64_t int64;
char* string;
float float32;
} data;
AndroidEventLogType type;
uint16_t complete;
uint16_t len;
union {
int32_t int32;
int64_t int64;
char* string;
float float32;
} data;
} android_log_list_element;
#endif
@ -91,8 +91,8 @@ int android_log_write_list_end(android_log_context ctx);
int android_log_write_int32(android_log_context ctx, int32_t value);
int android_log_write_int64(android_log_context ctx, int64_t value);
int android_log_write_string8(android_log_context ctx, const char* value);
int android_log_write_string8_len(android_log_context ctx,
const char* value, size_t maxlen);
int android_log_write_string8_len(android_log_context ctx, const char* value,
size_t maxlen);
int android_log_write_float32(android_log_context ctx, float value);
/* Submit the composed list context to the specified logger id */
@ -116,173 +116,182 @@ int android_log_destroy(android_log_context* ctx);
/* android_log_list C++ helpers */
extern "C++" {
class android_log_event_list {
friend class __android_log_event_list;
friend class __android_log_event_list;
private:
android_log_context ctx;
int ret;
private:
android_log_context ctx;
int ret;
android_log_event_list(const android_log_event_list&) = delete;
void operator =(const android_log_event_list&) = delete;
android_log_event_list(const android_log_event_list&) = delete;
void operator=(const android_log_event_list&) = delete;
public:
explicit android_log_event_list(int tag) : ret(0) {
ctx = create_android_logger(static_cast<uint32_t>(tag));
}
explicit android_log_event_list(log_msg& log_msg) : ret(0) {
ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
log_msg.entry.len - sizeof(uint32_t));
}
~android_log_event_list() { android_log_destroy(&ctx); }
public:
explicit android_log_event_list(int tag) : ret(0) {
ctx = create_android_logger(static_cast<uint32_t>(tag));
}
explicit android_log_event_list(log_msg& log_msg) : ret(0) {
ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
log_msg.entry.len - sizeof(uint32_t));
}
~android_log_event_list() {
android_log_destroy(&ctx);
}
int close() {
int retval = android_log_destroy(&ctx);
if (retval < 0) ret = retval;
return retval;
}
int close() {
int retval = android_log_destroy(&ctx);
if (retval < 0) ret = retval;
return retval;
}
/* To allow above C calls to use this class as parameter */
operator android_log_context() const { return ctx; }
/* To allow above C calls to use this class as parameter */
operator android_log_context() const {
return ctx;
}
int status() const { return ret; }
int status() const {
return ret;
}
int begin() {
int retval = android_log_write_list_begin(ctx);
if (retval < 0) ret = retval;
return ret;
}
int end() {
int retval = android_log_write_list_end(ctx);
if (retval < 0) ret = retval;
return ret;
}
int begin() {
int retval = android_log_write_list_begin(ctx);
if (retval < 0) ret = retval;
return ret;
}
int end() {
int retval = android_log_write_list_end(ctx);
if (retval < 0) ret = retval;
return ret;
}
android_log_event_list& operator <<(int32_t value) {
int retval = android_log_write_int32(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator<<(int32_t value) {
int retval = android_log_write_int32(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator <<(uint32_t value) {
int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator<<(uint32_t value) {
int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator <<(int64_t value) {
int retval = android_log_write_int64(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator<<(int64_t value) {
int retval = android_log_write_int64(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator <<(uint64_t value) {
int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator<<(uint64_t value) {
int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator <<(const char* value) {
int retval = android_log_write_string8(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator<<(const char* value) {
int retval = android_log_write_string8(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
#if defined(_USING_LIBCXX)
android_log_event_list& operator <<(const std::string& value) {
int retval = android_log_write_string8_len(ctx,
value.data(),
value.length());
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator<<(const std::string& value) {
int retval =
android_log_write_string8_len(ctx, value.data(), value.length());
if (retval < 0) ret = retval;
return *this;
}
#endif
android_log_event_list& operator <<(float value) {
int retval = android_log_write_float32(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
android_log_event_list& operator<<(float value) {
int retval = android_log_write_float32(ctx, value);
if (retval < 0) ret = retval;
return *this;
}
int write(log_id_t id = LOG_ID_EVENTS) {
int retval = android_log_write_list(ctx, id);
if (retval < 0) ret = retval;
return ret;
}
int write(log_id_t id = LOG_ID_EVENTS) {
int retval = android_log_write_list(ctx, id);
if (retval < 0) ret = retval;
return ret;
}
int operator <<(log_id_t id) {
int retval = android_log_write_list(ctx, id);
if (retval < 0) ret = retval;
android_log_destroy(&ctx);
return ret;
}
int operator<<(log_id_t id) {
int retval = android_log_write_list(ctx, id);
if (retval < 0) ret = retval;
android_log_destroy(&ctx);
return ret;
}
/*
* Append<Type> methods removes any integer promotion
* confusion, and adds access to string with length.
* Append methods are also added for all types for
* convenience.
*/
/*
* Append<Type> methods removes any integer promotion
* confusion, and adds access to string with length.
* Append methods are also added for all types for
* convenience.
*/
bool AppendInt(int32_t value) {
int retval = android_log_write_int32(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendInt(int32_t value) {
int retval = android_log_write_int32(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendLong(int64_t value) {
int retval = android_log_write_int64(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendLong(int64_t value) {
int retval = android_log_write_int64(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendString(const char* value) {
int retval = android_log_write_string8(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendString(const char* value) {
int retval = android_log_write_string8(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendString(const char* value, size_t len) {
int retval = android_log_write_string8_len(ctx, value, len);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendString(const char* value, size_t len) {
int retval = android_log_write_string8_len(ctx, value, len);
if (retval < 0) ret = retval;
return ret >= 0;
}
#if defined(_USING_LIBCXX)
bool AppendString(const std::string& value) {
int retval = android_log_write_string8_len(ctx,
value.data(),
value.length());
if (retval < 0) ret = retval;
return ret;
}
bool AppendString(const std::string& value) {
int retval =
android_log_write_string8_len(ctx, value.data(), value.length());
if (retval < 0) ret = retval;
return ret;
}
bool Append(const std::string& value) {
int retval = android_log_write_string8_len(ctx,
value.data(),
value.length());
if (retval < 0) ret = retval;
return ret;
}
bool Append(const std::string& value) {
int retval =
android_log_write_string8_len(ctx, value.data(), value.length());
if (retval < 0) ret = retval;
return ret;
}
#endif
bool AppendFloat(float value) {
int retval = android_log_write_float32(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
bool AppendFloat(float value) {
int retval = android_log_write_float32(ctx, value);
if (retval < 0) ret = retval;
return ret >= 0;
}
template <typename Tvalue>
bool Append(Tvalue value) { *this << value; return ret >= 0; }
template <typename Tvalue>
bool Append(Tvalue value) {
*this << value;
return ret >= 0;
}
bool Append(const char* value, size_t len) {
int retval = android_log_write_string8_len(ctx, value, len);
if (retval < 0) ret = retval;
return ret >= 0;
}
android_log_list_element read() { return android_log_read_next(ctx); }
android_log_list_element peek() { return android_log_peek_next(ctx); }
bool Append(const char* value, size_t len) {
int retval = android_log_write_string8_len(ctx, value, len);
if (retval < 0) ret = retval;
return ret >= 0;
}
android_log_list_element read() {
return android_log_read_next(ctx);
}
android_log_list_element peek() {
return android_log_peek_next(ctx);
}
};
}
#endif

View File

@ -17,12 +17,14 @@ extern "C" {
/*
* Logging frontends, bit mask to select features. Function returns selection.
*/
/* clang-format off */
#define LOGGER_DEFAULT 0x00
#define LOGGER_LOGD 0x01
#define LOGGER_KERNEL 0x02 /* Reserved/Deprecated */
#define LOGGER_NULL 0x04 /* Does not release resources of other selections */
#define LOGGER_LOCAL 0x08 /* logs sent to local memory */
#define LOGGER_STDERR 0x10 /* logs sent to stderr */
/* clang-format on */
/* Both return the selected frontend flag mask, or negative errno */
int android_set_log_frontend(int frontend_flag);

View File

@ -24,17 +24,17 @@ extern "C" {
#ifndef log_id_t_defined
#define log_id_t_defined
typedef enum log_id {
LOG_ID_MIN = 0,
LOG_ID_MIN = 0,
LOG_ID_MAIN = 0,
LOG_ID_RADIO = 1,
LOG_ID_EVENTS = 2,
LOG_ID_SYSTEM = 3,
LOG_ID_CRASH = 4,
LOG_ID_SECURITY = 5,
LOG_ID_KERNEL = 6, /* place last, third-parties can not use it */
LOG_ID_MAIN = 0,
LOG_ID_RADIO = 1,
LOG_ID_EVENTS = 2,
LOG_ID_SYSTEM = 3,
LOG_ID_CRASH = 4,
LOG_ID_SECURITY = 5,
LOG_ID_KERNEL = 6, /* place last, third-parties can not use it */
LOG_ID_MAX
LOG_ID_MAX
} log_id_t;
#endif
#define sizeof_log_id_t sizeof(typeof_log_id_t)
@ -43,8 +43,10 @@ typedef enum log_id {
/*
* Send a simple string to the log.
*/
int __android_log_buf_write(int bufID, int prio, const char* tag, const char* text);
int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...)
int __android_log_buf_write(int bufID, int prio, const char* tag,
const char* text);
int __android_log_buf_print(int bufID, int prio, const char* tag,
const char* fmt, ...)
#if defined(__GNUC__)
__attribute__((__format__(printf, 4, 5)))
#endif

View File

@ -56,21 +56,19 @@ extern "C" {
#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
#endif
#define android_writeLog(prio, tag, text) \
__android_log_write(prio, tag, text)
#define android_writeLog(prio, tag, text) __android_log_write(prio, tag, text)
#define android_printLog(prio, tag, ...) \
__android_log_print(prio, tag, __VA_ARGS__)
__android_log_print(prio, tag, __VA_ARGS__)
#define android_vprintLog(prio, cond, tag, ...) \
__android_log_vprint(prio, tag, __VA_ARGS__)
__android_log_vprint(prio, tag, __VA_ARGS__)
/*
* Log macro that allows you to specify a number for the priority.
*/
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
android_printLog(priority, tag, __VA_ARGS__)
#define LOG_PRI(priority, tag, ...) android_printLog(priority, tag, __VA_ARGS__)
#endif
/*
@ -78,7 +76,7 @@ extern "C" {
*/
#ifndef LOG_PRI_VA
#define LOG_PRI_VA(priority, tag, fmt, args) \
android_vprintLog(priority, NULL, tag, fmt, args)
android_vprintLog(priority, NULL, tag, fmt, args)
#endif
/* --------------------------------------------------------------------- */
@ -91,16 +89,17 @@ extern "C" {
/* Returns 2nd arg. Used to substitute default value if caller's vararg list
* is empty.
*/
#define __android_second(dummy, second, ...) second
#define __android_second(dummy, second, ...) second
/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
* returns nothing.
*/
#define __android_rest(first, ...) , ## __VA_ARGS__
#define __android_rest(first, ...) , ##__VA_ARGS__
#define android_printAssert(cond, tag, ...) \
__android_log_assert(cond, tag, \
__android_second(0, ## __VA_ARGS__, NULL) __android_rest(__VA_ARGS__))
#define android_printAssert(cond, tag, ...) \
__android_log_assert(cond, tag, \
__android_second(0, ##__VA_ARGS__, NULL) \
__android_rest(__VA_ARGS__))
/*
* Log a fatal error. If the given condition fails, this stops program
@ -109,15 +108,15 @@ extern "C" {
* is -inverted- from the normal assert() semantics.
*/
#ifndef LOG_ALWAYS_FATAL_IF
#define LOG_ALWAYS_FATAL_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)android_printAssert(#cond, LOG_TAG, ## __VA_ARGS__)) \
: (void)0 )
#define LOG_ALWAYS_FATAL_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)android_printAssert(#cond, LOG_TAG, ##__VA_ARGS__)) \
: (void)0)
#endif
#ifndef LOG_ALWAYS_FATAL
#define LOG_ALWAYS_FATAL(...) \
( ((void)android_printAssert(NULL, LOG_TAG, ## __VA_ARGS__)) )
(((void)android_printAssert(NULL, LOG_TAG, ##__VA_ARGS__)))
#endif
/*
@ -137,7 +136,7 @@ extern "C" {
#else
#ifndef LOG_FATAL_IF
#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ##__VA_ARGS__)
#endif
#ifndef LOG_FATAL
#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
@ -150,7 +149,7 @@ extern "C" {
* Stripped out of release builds. Uses the current LOG_TAG.
*/
#ifndef ALOG_ASSERT
#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ##__VA_ARGS__)
#endif
/* --------------------------------------------------------------------- */
@ -175,7 +174,12 @@ extern "C" {
#ifndef ALOGV
#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#if LOG_NDEBUG
#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)
#define ALOGV(...) \
do { \
if (0) { \
__ALOGV(__VA_ARGS__); \
} \
} while (0)
#else
#define ALOGV(...) __ALOGV(__VA_ARGS__)
#endif
@ -183,12 +187,11 @@ extern "C" {
#ifndef ALOGV_IF
#if LOG_NDEBUG
#define ALOGV_IF(cond, ...) ((void)0)
#define ALOGV_IF(cond, ...) ((void)0)
#else
#define ALOGV_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define ALOGV_IF(cond, ...) \
((__predict_false(cond)) ? ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
#endif
@ -200,10 +203,9 @@ extern "C" {
#endif
#ifndef ALOGD_IF
#define ALOGD_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define ALOGD_IF(cond, ...) \
((__predict_false(cond)) ? ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
@ -214,10 +216,9 @@ extern "C" {
#endif
#ifndef ALOGI_IF
#define ALOGI_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define ALOGI_IF(cond, ...) \
((__predict_false(cond)) ? ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
@ -228,10 +229,9 @@ extern "C" {
#endif
#ifndef ALOGW_IF
#define ALOGW_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define ALOGW_IF(cond, ...) \
((__predict_false(cond)) ? ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
@ -242,10 +242,9 @@ extern "C" {
#endif
#ifndef ALOGE_IF
#define ALOGE_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define ALOGE_IF(cond, ...) \
((__predict_false(cond)) ? ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/* --------------------------------------------------------------------- */
@ -305,16 +304,14 @@ extern "C" {
* The second argument may be NULL or "" to indicate the "global" tag.
*/
#ifndef ALOG
#define ALOG(priority, tag, ...) \
LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#define ALOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif
/*
* Conditional given a desired logging priority and tag.
*/
#ifndef IF_ALOG
#define IF_ALOG(priority, tag) \
if (android_testLog(ANDROID_##priority, tag))
#define IF_ALOG(priority, tag) if (android_testLog(ANDROID_##priority, tag))
#endif
/* --------------------------------------------------------------------- */
@ -357,23 +354,23 @@ int __android_log_is_loggable_len(int prio, const char* tag, size_t len,
int default_prio);
#if LOG_NDEBUG /* Production */
#define android_testLog(prio, tag) \
(__android_log_is_loggable_len(prio, tag, (tag && *tag) ? strlen(tag) : 0, \
ANDROID_LOG_DEBUG) != 0)
#define android_testLog(prio, tag) \
(__android_log_is_loggable_len(prio, tag, (tag && *tag) ? strlen(tag) : 0, \
ANDROID_LOG_DEBUG) != 0)
#else
#define android_testLog(prio, tag) \
(__android_log_is_loggable_len(prio, tag, (tag && *tag) ? strlen(tag) : 0, \
ANDROID_LOG_VERBOSE) != 0)
#define android_testLog(prio, tag) \
(__android_log_is_loggable_len(prio, tag, (tag && *tag) ? strlen(tag) : 0, \
ANDROID_LOG_VERBOSE) != 0)
#endif
#else
#if LOG_NDEBUG /* Production */
#define android_testLog(prio, tag) \
(__android_log_is_loggable(prio, tag, ANDROID_LOG_DEBUG) != 0)
(__android_log_is_loggable(prio, tag, ANDROID_LOG_DEBUG) != 0)
#else
#define android_testLog(prio, tag) \
(__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE) != 0)
(__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE) != 0)
#endif
#endif

View File

@ -46,10 +46,16 @@
* Simplified macro to send a verbose radio log message using current LOG_TAG.
*/
#ifndef RLOGV
#define __RLOGV(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#define __RLOGV(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, \
__VA_ARGS__))
#if LOG_NDEBUG
#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0)
#define RLOGV(...) \
do { \
if (0) { \
__RLOGV(__VA_ARGS__); \
} \
} while (0)
#else
#define RLOGV(...) __RLOGV(__VA_ARGS__)
#endif
@ -57,12 +63,13 @@
#ifndef RLOGV_IF
#if LOG_NDEBUG
#define RLOGV_IF(cond, ...) ((void)0)
#define RLOGV_IF(cond, ...) ((void)0)
#else
#define RLOGV_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define RLOGV_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
#endif
@ -70,60 +77,68 @@
* Simplified macro to send a debug radio log message using current LOG_TAG.
*/
#ifndef RLOGD
#define RLOGD(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define RLOGD(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef RLOGD_IF
#define RLOGD_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define RLOGD_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_DEBUG, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
* Simplified macro to send an info radio log message using current LOG_TAG.
*/
#ifndef RLOGI
#define RLOGI(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define RLOGI(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef RLOGI_IF
#define RLOGI_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define RLOGI_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
* Simplified macro to send a warning radio log message using current LOG_TAG.
*/
#ifndef RLOGW
#define RLOGW(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define RLOGW(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef RLOGW_IF
#define RLOGW_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define RLOGW_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_WARN, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
* Simplified macro to send an error radio log message using current LOG_TAG.
*/
#ifndef RLOGE
#define RLOGE(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define RLOGE(...) \
((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef RLOGE_IF
#define RLOGE_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define RLOGE_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
#endif /* _LIBS_LOG_LOG_RADIO_H */

View File

@ -53,14 +53,14 @@ extern "C" {
#ifndef __struct_logger_entry_defined
#define __struct_logger_entry_defined
struct logger_entry {
uint16_t len; /* length of the payload */
uint16_t __pad; /* no matter what, we get 2 bytes of padding */
int32_t pid; /* generating process's pid */
int32_t tid; /* generating process's tid */
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
uint16_t len; /* length of the payload */
uint16_t __pad; /* no matter what, we get 2 bytes of padding */
int32_t pid; /* generating process's pid */
int32_t tid; /* generating process's tid */
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
#ifndef __cplusplus
char msg[0]; /* the entry's payload */
char msg[0]; /* the entry's payload */
#endif
};
#endif
@ -71,15 +71,15 @@ struct logger_entry {
#ifndef __struct_logger_entry_v2_defined
#define __struct_logger_entry_v2_defined
struct logger_entry_v2 {
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
int32_t pid; /* generating process's pid */
int32_t tid; /* generating process's tid */
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
uint32_t euid; /* effective UID of logger */
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
int32_t pid; /* generating process's pid */
int32_t tid; /* generating process's tid */
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
uint32_t euid; /* effective UID of logger */
#ifndef __cplusplus
char msg[0]; /* the entry's payload */
char msg[0]; /* the entry's payload */
#endif
} __attribute__((__packed__));
#endif
@ -90,15 +90,15 @@ struct logger_entry_v2 {
#ifndef __struct_logger_entry_v3_defined
#define __struct_logger_entry_v3_defined
struct logger_entry_v3 {
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
int32_t pid; /* generating process's pid */
int32_t tid; /* generating process's tid */
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
uint32_t lid; /* log id of the payload */
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
int32_t pid; /* generating process's pid */
int32_t tid; /* generating process's tid */
int32_t sec; /* seconds since Epoch */
int32_t nsec; /* nanoseconds */
uint32_t lid; /* log id of the payload */
#ifndef __cplusplus
char msg[0]; /* the entry's payload */
char msg[0]; /* the entry's payload */
#endif
} __attribute__((__packed__));
#endif
@ -109,16 +109,16 @@ struct logger_entry_v3 {
#ifndef __struct_logger_entry_v4_defined
#define __struct_logger_entry_v4_defined
struct logger_entry_v4 {
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v4) */
int32_t pid; /* generating process's pid */
uint32_t tid; /* generating process's tid */
uint32_t sec; /* seconds since Epoch */
uint32_t nsec; /* nanoseconds */
uint32_t lid; /* log id of the payload, bottom 4 bits currently */
uint32_t uid; /* generating process's uid */
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v4) */
int32_t pid; /* generating process's pid */
uint32_t tid; /* generating process's tid */
uint32_t sec; /* seconds since Epoch */
uint32_t nsec; /* nanoseconds */
uint32_t lid; /* log id of the payload, bottom 4 bits currently */
uint32_t uid; /* generating process's uid */
#ifndef __cplusplus
char msg[0]; /* the entry's payload */
char msg[0]; /* the entry's payload */
#endif
};
#endif
@ -135,77 +135,64 @@ struct logger_entry_v4 {
* An attempt to read less than this amount may result
* in read() returning EINVAL.
*/
#define LOGGER_ENTRY_MAX_LEN (5*1024)
#define LOGGER_ENTRY_MAX_LEN (5 * 1024)
#ifndef __struct_log_msg_defined
#define __struct_log_msg_defined
struct log_msg {
union {
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
struct logger_entry_v4 entry;
struct logger_entry_v4 entry_v4;
struct logger_entry_v3 entry_v3;
struct logger_entry_v2 entry_v2;
struct logger_entry entry_v1;
} __attribute__((aligned(4)));
union {
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
struct logger_entry_v4 entry;
struct logger_entry_v4 entry_v4;
struct logger_entry_v3 entry_v3;
struct logger_entry_v2 entry_v2;
struct logger_entry entry_v1;
} __attribute__((aligned(4)));
#ifdef __cplusplus
/* Matching log_time operators */
bool operator== (const log_msg& T) const
{
return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec);
}
bool operator!= (const log_msg& T) const
{
return !(*this == T);
}
bool operator< (const log_msg& T) const
{
return (entry.sec < T.entry.sec)
|| ((entry.sec == T.entry.sec)
&& (entry.nsec < T.entry.nsec));
}
bool operator>= (const log_msg& T) const
{
return !(*this < T);
}
bool operator> (const log_msg& T) const
{
return (entry.sec > T.entry.sec)
|| ((entry.sec == T.entry.sec)
&& (entry.nsec > T.entry.nsec));
}
bool operator<= (const log_msg& T) const
{
return !(*this > T);
}
uint64_t nsec() const
{
return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;
}
/* Matching log_time operators */
bool operator==(const log_msg& T) const {
return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec);
}
bool operator!=(const log_msg& T) const {
return !(*this == T);
}
bool operator<(const log_msg& T) const {
return (entry.sec < T.entry.sec) ||
((entry.sec == T.entry.sec) && (entry.nsec < T.entry.nsec));
}
bool operator>=(const log_msg& T) const {
return !(*this < T);
}
bool operator>(const log_msg& T) const {
return (entry.sec > T.entry.sec) ||
((entry.sec == T.entry.sec) && (entry.nsec > T.entry.nsec));
}
bool operator<=(const log_msg& T) const {
return !(*this > T);
}
uint64_t nsec() const {
return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec;
}
/* packet methods */
log_id_t id()
{
return static_cast<log_id_t>(entry.lid);
/* packet methods */
log_id_t id() {
return static_cast<log_id_t>(entry.lid);
}
char* msg() {
unsigned short hdr_size = entry.hdr_size;
if (!hdr_size) {
hdr_size = sizeof(entry_v1);
}
char* msg()
{
unsigned short hdr_size = entry.hdr_size;
if (!hdr_size) {
hdr_size = sizeof(entry_v1);
}
if ((hdr_size < sizeof(entry_v1)) || (hdr_size > sizeof(entry))) {
return NULL;
}
return reinterpret_cast<char*>(buf) + hdr_size;
}
unsigned int len()
{
return (entry.hdr_size ?
entry.hdr_size :
static_cast<uint16_t>(sizeof(entry_v1))) +
entry.len;
if ((hdr_size < sizeof(entry_v1)) || (hdr_size > sizeof(entry))) {
return NULL;
}
return reinterpret_cast<char*>(buf) + hdr_size;
}
unsigned int len() {
return (entry.hdr_size ? entry.hdr_size
: static_cast<uint16_t>(sizeof(entry_v1))) +
entry.len;
}
#endif
};
#endif
@ -243,32 +230,30 @@ ssize_t android_logger_get_statistics(struct logger_list* logger_list,
char* buf, size_t len);
ssize_t android_logger_get_prune_list(struct logger_list* logger_list,
char* buf, size_t len);
int android_logger_set_prune_list(struct logger_list* logger_list,
char* buf, size_t len);
int android_logger_set_prune_list(struct logger_list* logger_list, char* buf,
size_t len);
#endif
#define ANDROID_LOG_RDONLY O_RDONLY
#define ANDROID_LOG_WRONLY O_WRONLY
#define ANDROID_LOG_RDWR O_RDWR
#define ANDROID_LOG_ACCMODE O_ACCMODE
#define ANDROID_LOG_RDONLY O_RDONLY
#define ANDROID_LOG_WRONLY O_WRONLY
#define ANDROID_LOG_RDWR O_RDWR
#define ANDROID_LOG_ACCMODE O_ACCMODE
#ifndef O_NONBLOCK
#define ANDROID_LOG_NONBLOCK 0x00000800
#else
#define ANDROID_LOG_NONBLOCK O_NONBLOCK
#endif
#if __ANDROID_USE_LIBLOG_READER_INTERFACE > 2
#define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */
#define ANDROID_LOG_WRAP 0x40000000 /* Block until buffer about to wrap */
#define ANDROID_LOG_WRAP_DEFAULT_TIMEOUT 7200 /* 2 hour default */
#endif
#if __ANDROID_USE_LIBLOG_READER_INTERFACE > 1
#define ANDROID_LOG_PSTORE 0x80000000
#define ANDROID_LOG_PSTORE 0x80000000
#endif
struct logger_list* android_logger_list_alloc(int mode,
unsigned int tail,
struct logger_list* android_logger_list_alloc(int mode, unsigned int tail,
pid_t pid);
struct logger_list* android_logger_list_alloc_time(int mode,
log_time start,
struct logger_list* android_logger_list_alloc_time(int mode, log_time start,
pid_t pid);
void android_logger_list_free(struct logger_list* logger_list);
/* In the purest sense, the following two are orthogonal interfaces */
@ -276,14 +261,11 @@ int android_logger_list_read(struct logger_list* logger_list,
struct log_msg* log_msg);
/* Multiple log_id_t opens */
struct logger* android_logger_open(struct logger_list* logger_list,
log_id_t id);
struct logger* android_logger_open(struct logger_list* logger_list, log_id_t id);
#define android_logger_close android_logger_free
/* Single log_id_t open */
struct logger_list* android_logger_list_open(log_id_t id,
int mode,
unsigned int tail,
pid_t pid);
struct logger_list* android_logger_list_open(log_id_t id, int mode,
unsigned int tail, pid_t pid);
#define android_logger_list_close android_logger_list_free
#endif /* __ANDROID_USE_LIBLOG_READER_INTERFACE */

View File

@ -44,10 +44,16 @@
* Simplified macro to send a verbose system log message using current LOG_TAG.
*/
#ifndef SLOGV
#define __SLOGV(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
#define __SLOGV(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, \
__VA_ARGS__))
#if LOG_NDEBUG
#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0)
#define SLOGV(...) \
do { \
if (0) { \
__SLOGV(__VA_ARGS__); \
} \
} while (0)
#else
#define SLOGV(...) __SLOGV(__VA_ARGS__)
#endif
@ -55,12 +61,13 @@
#ifndef SLOGV_IF
#if LOG_NDEBUG
#define SLOGV_IF(cond, ...) ((void)0)
#define SLOGV_IF(cond, ...) ((void)0)
#else
#define SLOGV_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define SLOGV_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
#endif
@ -68,60 +75,68 @@
* Simplified macro to send a debug system log message using current LOG_TAG.
*/
#ifndef SLOGD
#define SLOGD(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#define SLOGD(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef SLOGD_IF
#define SLOGD_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define SLOGD_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
* Simplified macro to send an info system log message using current LOG_TAG.
*/
#ifndef SLOGI
#define SLOGI(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define SLOGI(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef SLOGI_IF
#define SLOGI_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define SLOGI_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
* Simplified macro to send a warning system log message using current LOG_TAG.
*/
#ifndef SLOGW
#define SLOGW(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define SLOGW(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef SLOGW_IF
#define SLOGW_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define SLOGW_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_WARN, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
/*
* Simplified macro to send an error system log message using current LOG_TAG.
*/
#ifndef SLOGE
#define SLOGE(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
#define SLOGE(...) \
((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, \
__VA_ARGS__))
#endif
#ifndef SLOGE_IF
#define SLOGE_IF(cond, ...) \
( (__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#define SLOGE_IF(cond, ...) \
((__predict_false(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, \
LOG_TAG, __VA_ARGS__)) \
: (void)0)
#endif
#endif /* _LIBS_LOG_LOG_SYSTEM_H */

View File

@ -34,159 +34,135 @@
* efficient behavior. Also, pass-by-reference breaks C/C++ ABI.
*/
struct log_time {
public:
uint32_t tv_sec; /* good to Feb 5 2106 */
uint32_t tv_nsec;
public:
uint32_t tv_sec; /* good to Feb 5 2106 */
uint32_t tv_nsec;
static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
static const uint32_t tv_nsec_max = 999999999UL;
static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
static const uint32_t tv_nsec_max = 999999999UL;
log_time(const timespec& T)
{
tv_sec = static_cast<uint32_t>(T.tv_sec);
tv_nsec = static_cast<uint32_t>(T.tv_nsec);
}
log_time(uint32_t sec, uint32_t nsec)
{
tv_sec = sec;
tv_nsec = nsec;
}
log_time(const timespec& T) {
tv_sec = static_cast<uint32_t>(T.tv_sec);
tv_nsec = static_cast<uint32_t>(T.tv_nsec);
}
log_time(uint32_t sec, uint32_t nsec) {
tv_sec = sec;
tv_nsec = nsec;
}
#ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
#define __struct_log_time_private_defined
static const timespec EPOCH;
static const timespec EPOCH;
#endif
log_time()
{
}
log_time() {
}
#ifdef __linux__
log_time(clockid_t id)
{
timespec T;
clock_gettime(id, &T);
tv_sec = static_cast<uint32_t>(T.tv_sec);
tv_nsec = static_cast<uint32_t>(T.tv_nsec);
}
log_time(clockid_t id) {
timespec T;
clock_gettime(id, &T);
tv_sec = static_cast<uint32_t>(T.tv_sec);
tv_nsec = static_cast<uint32_t>(T.tv_nsec);
}
#endif
log_time(const char* T)
{
const uint8_t* c = reinterpret_cast<const uint8_t*>(T);
tv_sec = c[0] |
(static_cast<uint32_t>(c[1]) << 8) |
(static_cast<uint32_t>(c[2]) << 16) |
(static_cast<uint32_t>(c[3]) << 24);
tv_nsec = c[4] |
(static_cast<uint32_t>(c[5]) << 8) |
(static_cast<uint32_t>(c[6]) << 16) |
(static_cast<uint32_t>(c[7]) << 24);
}
log_time(const char* T) {
const uint8_t* c = reinterpret_cast<const uint8_t*>(T);
tv_sec = c[0] | (static_cast<uint32_t>(c[1]) << 8) |
(static_cast<uint32_t>(c[2]) << 16) |
(static_cast<uint32_t>(c[3]) << 24);
tv_nsec = c[4] | (static_cast<uint32_t>(c[5]) << 8) |
(static_cast<uint32_t>(c[6]) << 16) |
(static_cast<uint32_t>(c[7]) << 24);
}
/* timespec */
bool operator== (const timespec& T) const
{
return (tv_sec == static_cast<uint32_t>(T.tv_sec))
&& (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
}
bool operator!= (const timespec& T) const
{
return !(*this == T);
}
bool operator< (const timespec& T) const
{
return (tv_sec < static_cast<uint32_t>(T.tv_sec))
|| ((tv_sec == static_cast<uint32_t>(T.tv_sec))
&& (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
}
bool operator>= (const timespec& T) const
{
return !(*this < T);
}
bool operator> (const timespec& T) const
{
return (tv_sec > static_cast<uint32_t>(T.tv_sec))
|| ((tv_sec == static_cast<uint32_t>(T.tv_sec))
&& (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
}
bool operator<= (const timespec& T) const
{
return !(*this > T);
}
/* timespec */
bool operator==(const timespec& T) const {
return (tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
(tv_nsec == static_cast<uint32_t>(T.tv_nsec));
}
bool operator!=(const timespec& T) const {
return !(*this == T);
}
bool operator<(const timespec& T) const {
return (tv_sec < static_cast<uint32_t>(T.tv_sec)) ||
((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
(tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
}
bool operator>=(const timespec& T) const {
return !(*this < T);
}
bool operator>(const timespec& T) const {
return (tv_sec > static_cast<uint32_t>(T.tv_sec)) ||
((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
(tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
}
bool operator<=(const timespec& T) const {
return !(*this > T);
}
#ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
log_time operator-= (const timespec& T);
log_time operator- (const timespec& T) const
{
log_time local(*this);
return local -= T;
}
log_time operator+= (const timespec& T);
log_time operator+ (const timespec& T) const
{
log_time local(*this);
return local += T;
}
log_time operator-=(const timespec& T);
log_time operator-(const timespec& T) const {
log_time local(*this);
return local -= T;
}
log_time operator+=(const timespec& T);
log_time operator+(const timespec& T) const {
log_time local(*this);
return local += T;
}
#endif
/* log_time */
bool operator== (const log_time& T) const
{
return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
}
bool operator!= (const log_time& T) const
{
return !(*this == T);
}
bool operator< (const log_time& T) const
{
return (tv_sec < T.tv_sec)
|| ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
}
bool operator>= (const log_time& T) const
{
return !(*this < T);
}
bool operator> (const log_time& T) const
{
return (tv_sec > T.tv_sec)
|| ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
}
bool operator<= (const log_time& T) const
{
return !(*this > T);
}
/* log_time */
bool operator==(const log_time& T) const {
return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
}
bool operator!=(const log_time& T) const {
return !(*this == T);
}
bool operator<(const log_time& T) const {
return (tv_sec < T.tv_sec) ||
((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
}
bool operator>=(const log_time& T) const {
return !(*this < T);
}
bool operator>(const log_time& T) const {
return (tv_sec > T.tv_sec) ||
((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
}
bool operator<=(const log_time& T) const {
return !(*this > T);
}
#ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
log_time operator-= (const log_time& T);
log_time operator- (const log_time& T) const
{
log_time local(*this);
return local -= T;
}
log_time operator+= (const log_time& T);
log_time operator+ (const log_time& T) const
{
log_time local(*this);
return local += T;
}
log_time operator-=(const log_time& T);
log_time operator-(const log_time& T) const {
log_time local(*this);
return local -= T;
}
log_time operator+=(const log_time& T);
log_time operator+(const log_time& T) const {
log_time local(*this);
return local += T;
}
#endif
uint64_t nsec() const
{
return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
}
uint64_t nsec() const {
return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
}
#ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
static const char default_format[];
static const char default_format[];
/* Add %#q for the fraction of a second to the standard library functions */
char* strptime(const char* s, const char* format = default_format);
/* Add %#q for the fraction of a second to the standard library functions */
char* strptime(const char* s, const char* format = default_format);
#endif
} __attribute__((__packed__));
#else
typedef struct log_time {
uint32_t tv_sec;
uint32_t tv_nsec;
uint32_t tv_sec;
uint32_t tv_nsec;
} __attribute__((__packed__)) log_time;
#endif

View File

@ -27,43 +27,43 @@ extern "C" {
#endif
typedef enum {
/* Verbs */
FORMAT_OFF = 0,
FORMAT_BRIEF,
FORMAT_PROCESS,
FORMAT_TAG,
FORMAT_THREAD,
FORMAT_RAW,
FORMAT_TIME,
FORMAT_THREADTIME,
FORMAT_LONG,
/* Adverbs. The following are modifiers to above format verbs */
FORMAT_MODIFIER_COLOR, /* converts priority to color */
FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */
FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */
FORMAT_MODIFIER_YEAR, /* Adds year to date */
FORMAT_MODIFIER_ZONE, /* Adds zone to date, + UTC */
FORMAT_MODIFIER_EPOCH, /* Print time as seconds since Jan 1 1970 */
FORMAT_MODIFIER_MONOTONIC, /* Print cpu time as seconds since start */
FORMAT_MODIFIER_UID, /* Adds uid */
FORMAT_MODIFIER_DESCRIPT, /* Adds descriptive */
/* private, undocumented */
FORMAT_MODIFIER_TIME_NSEC, /* switches from msec to nsec time precision */
/* Verbs */
FORMAT_OFF = 0,
FORMAT_BRIEF,
FORMAT_PROCESS,
FORMAT_TAG,
FORMAT_THREAD,
FORMAT_RAW,
FORMAT_TIME,
FORMAT_THREADTIME,
FORMAT_LONG,
/* Adverbs. The following are modifiers to above format verbs */
FORMAT_MODIFIER_COLOR, /* converts priority to color */
FORMAT_MODIFIER_TIME_USEC, /* switches from msec to usec time precision */
FORMAT_MODIFIER_PRINTABLE, /* converts non-printable to printable escapes */
FORMAT_MODIFIER_YEAR, /* Adds year to date */
FORMAT_MODIFIER_ZONE, /* Adds zone to date, + UTC */
FORMAT_MODIFIER_EPOCH, /* Print time as seconds since Jan 1 1970 */
FORMAT_MODIFIER_MONOTONIC, /* Print cpu time as seconds since start */
FORMAT_MODIFIER_UID, /* Adds uid */
FORMAT_MODIFIER_DESCRIPT, /* Adds descriptive */
/* private, undocumented */
FORMAT_MODIFIER_TIME_NSEC, /* switches from msec to nsec time precision */
} AndroidLogPrintFormat;
typedef struct AndroidLogFormat_t AndroidLogFormat;
typedef struct AndroidLogEntry_t {
time_t tv_sec;
long tv_nsec;
android_LogPriority priority;
int32_t uid;
int32_t pid;
int32_t tid;
const char* tag;
size_t tagLen;
size_t messageLen;
const char* message;
time_t tv_sec;
long tv_nsec;
android_LogPriority priority;
int32_t uid;
int32_t pid;
int32_t tid;
const char* tag;
size_t tagLen;
size_t messageLen;
const char* message;
} AndroidLogEntry;
AndroidLogFormat* android_log_format_new();
@ -72,7 +72,7 @@ void android_log_format_free(AndroidLogFormat* p_format);
/* currently returns 0 if format is a modifier, 1 if not */
int android_log_setPrintFormat(AndroidLogFormat* p_format,
AndroidLogPrintFormat format);
AndroidLogPrintFormat format);
/**
* Returns FORMAT_OFF on invalid string
@ -90,7 +90,7 @@ AndroidLogPrintFormat android_log_formatFromString(const char* s);
*/
int android_log_addFilterRule(AndroidLogFormat* p_format,
const char* filterExpression);
const char* filterExpression);
/**
* filterString: a whitespace-separated set of filter expressions
@ -103,14 +103,14 @@ int android_log_addFilterRule(AndroidLogFormat* p_format,
*/
int android_log_addFilterString(AndroidLogFormat* p_format,
const char* filterString);
const char* filterString);
/**
* returns 1 if this log line should be printed based on its priority
* and tag, and 0 if it should not
*/
int android_log_shouldPrintLine (
AndroidLogFormat* p_format, const char* tag, android_LogPriority pri);
int android_log_shouldPrintLine(AndroidLogFormat* p_format, const char* tag,
android_LogPriority pri);
/**
* Splits a wire-format buffer into an AndroidLogEntry
@ -129,8 +129,9 @@ int android_log_processLogBuffer(struct logger_entry* buf,
* into a string.
*/
int android_log_processBinaryLogBuffer(struct logger_entry* buf,
AndroidLogEntry* entry, const EventTagMap* map, char* messageBuf,
int messageBufLen);
AndroidLogEntry* entry,
const EventTagMap* map, char* messageBuf,
int messageBufLen);
/**
* Formats a log message into a buffer
@ -140,12 +141,10 @@ int android_log_processBinaryLogBuffer(struct logger_entry* buf,
* Returns NULL on malloc error
*/
char* android_log_formatLogLine (
AndroidLogFormat* p_format,
char* defaultBuffer,
size_t defaultBufferSize,
const AndroidLogEntry* p_line,
size_t* p_outLength);
char* android_log_formatLogLine(AndroidLogFormat* p_format, char* defaultBuffer,
size_t defaultBufferSize,
const AndroidLogEntry* p_line,
size_t* p_outLength);
/**
* Either print or do not print log line, based on filter
@ -153,10 +152,8 @@ char* android_log_formatLogLine (
* Assumes single threaded execution
*
*/
int android_log_printLogLine(
AndroidLogFormat* p_format,
int fd,
const AndroidLogEntry* entry);
int android_log_printLogLine(AndroidLogFormat* p_format, int fd,
const AndroidLogEntry* entry);
#ifdef __cplusplus
}

View File

@ -34,12 +34,12 @@ extern "C" {
#include <stddef.h>
struct iovec {
void* iov_base;
size_t iov_len;
void* iov_base;
size_t iov_len;
};
extern int readv( int fd, struct iovec* vecs, int count );
extern int writev( int fd, const struct iovec* vecs, int count );
extern int readv(int fd, struct iovec* vecs, int count);
extern int writev(int fd, const struct iovec* vecs, int count);
#ifdef __cplusplus
}
@ -48,4 +48,3 @@ extern int writev( int fd, const struct iovec* vecs, int count );
#endif
#endif /* _LIBS_UTILS_UIO_H */

View File

@ -31,8 +31,8 @@ extern "C++" {
}
#endif
#include <log/log_event_list.h>
#include <log/log.h>
#include <log/log_event_list.h>
#define LOGGER_MAGIC 'l'
@ -42,46 +42,46 @@ extern "C" {
/* Header Structure to pstore */
typedef struct __attribute__((__packed__)) {
uint8_t magic;
uint16_t len;
uint16_t uid;
uint16_t pid;
uint8_t magic;
uint16_t len;
uint16_t uid;
uint16_t pid;
} android_pmsg_log_header_t;
/* Header Structure to logd, and second header for pstore */
typedef struct __attribute__((__packed__)) {
typeof_log_id_t id;
uint16_t tid;
log_time realtime;
typeof_log_id_t id;
uint16_t tid;
log_time realtime;
} android_log_header_t;
/* Event Header Structure to logd */
typedef struct __attribute__((__packed__)) {
int32_t tag; // Little Endian Order
int32_t tag; // Little Endian Order
} android_event_header_t;
/* Event payload EVENT_TYPE_INT */
typedef struct __attribute__((__packed__)) {
int8_t type; // EVENT_TYPE_INT
int32_t data; // Little Endian Order
int8_t type; // EVENT_TYPE_INT
int32_t data; // Little Endian Order
} android_event_int_t;
/* Event with single EVENT_TYPE_INT */
typedef struct __attribute__((__packed__)) {
android_event_header_t header;
android_event_int_t payload;
android_event_header_t header;
android_event_int_t payload;
} android_log_event_int_t;
/* Event payload EVENT_TYPE_LONG */
typedef struct __attribute__((__packed__)) {
int8_t type; // EVENT_TYPE_LONG
int64_t data; // Little Endian Order
int8_t type; // EVENT_TYPE_LONG
int64_t data; // Little Endian Order
} android_event_long_t;
/* Event with single EVENT_TYPE_LONG */
typedef struct __attribute__((__packed__)) {
android_event_header_t header;
android_event_long_t payload;
android_event_header_t header;
android_event_long_t payload;
} android_log_event_long_t;
/*
@ -97,41 +97,39 @@ typedef struct __attribute__((__packed__)) {
*/
typedef struct __attribute__((__packed__)) {
int8_t type; // EVENT_TYPE_STRING;
int32_t length; // Little Endian Order
char data[];
int8_t type; // EVENT_TYPE_STRING;
int32_t length; // Little Endian Order
char data[];
} android_event_string_t;
/* Event with single EVENT_TYPE_STRING */
typedef struct __attribute__((__packed__)) {
android_event_header_t header;
int8_t type; // EVENT_TYPE_STRING;
int32_t length; // Little Endian Order
char data[];
android_event_header_t header;
int8_t type; // EVENT_TYPE_STRING;
int32_t length; // Little Endian Order
char data[];
} android_log_event_string_t;
#define ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE 256 /* 1MB file */
#define ANDROID_LOG_PMSG_FILE_SEQUENCE 1000
#define ANDROID_LOG_PMSG_FILE_SEQUENCE 1000
ssize_t __android_log_pmsg_file_write(
log_id_t logId,
char prio,
const char* filename,
const char* buf, size_t len);
ssize_t __android_log_pmsg_file_write(log_id_t logId, char prio,
const char* filename, const char* buf,
size_t len);
#define LOG_ID_ANY ((log_id_t)-1)
#define LOG_ID_ANY ((log_id_t)-1)
#define ANDROID_LOG_ANY ANDROID_LOG_UNKNOWN
/* first 5 arguments match __android_log_msg_file_write, a cast is safe */
typedef ssize_t (*__android_log_pmsg_file_read_fn)(
log_id_t logId,
char prio,
const char* filename,
const char* buf, size_t len, void* arg);
typedef ssize_t (*__android_log_pmsg_file_read_fn)(log_id_t logId, char prio,
const char* filename,
const char* buf, size_t len,
void* arg);
ssize_t __android_log_pmsg_file_read(
log_id_t logId, char prio, const char* prefix,
__android_log_pmsg_file_read_fn fn, void* arg);
ssize_t __android_log_pmsg_file_read(log_id_t logId, char prio,
const char* prefix,
__android_log_pmsg_file_read_fn fn,
void* arg);
int __android_log_security_bwrite(int32_t tag, const void* payload, size_t len);
int __android_log_security_bswrite(int32_t tag, const char* payload);
@ -140,14 +138,15 @@ int __android_log_security(); /* Device Owner is present */
int __android_log_is_debuggable();
#define BOOL_DEFAULT_FLAG_TRUE_FALSE 0x1
#define BOOL_DEFAULT_FALSE 0x0 /* false if property not present */
#define BOOL_DEFAULT_TRUE 0x1 /* true if property not present */
#define BOOL_DEFAULT_FLAG_PERSIST 0x2 /* <key>, persist.<key>, ro.<key> */
#define BOOL_DEFAULT_FLAG_ENG 0x4 /* off for user */
#define BOOL_DEFAULT_FLAG_SVELTE 0x8 /* off for low_ram */
#define BOOL_DEFAULT_FALSE 0x0 /* false if property not present */
#define BOOL_DEFAULT_TRUE 0x1 /* true if property not present */
#define BOOL_DEFAULT_FLAG_PERSIST 0x2 /* <key>, persist.<key>, ro.<key> */
#define BOOL_DEFAULT_FLAG_ENG 0x4 /* off for user */
#define BOOL_DEFAULT_FLAG_SVELTE 0x8 /* off for low_ram */
bool __android_logger_property_get_bool(const char* key, int flag);
#define LOG_BUFFER_SIZE (256 * 1024) /* Tuned with ro.logd.size per-platform */
#define LOG_BUFFER_SIZE (256 * 1024) /* Tuned with ro.logd.size per-platform \
*/
#define LOG_BUFFER_MIN_SIZE (64 * 1024UL)
#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL)
unsigned long __android_logger_get_buffer_size(log_id_t logId);
@ -163,24 +162,26 @@ int android_log_write_list_buffer(android_log_context ctx, const char** msg);
/* android_log_context C++ helpers */
extern "C++" {
class __android_log_event_list : public android_log_event_list {
__android_log_event_list(const android_log_event_list&) = delete;
void operator =(const __android_log_event_list&) = delete;
__android_log_event_list(const android_log_event_list&) = delete;
void operator=(const __android_log_event_list&) = delete;
public:
explicit __android_log_event_list(int tag) : android_log_event_list(tag) { }
explicit __android_log_event_list(log_msg& log_msg) : android_log_event_list(log_msg) { }
public:
explicit __android_log_event_list(int tag) : android_log_event_list(tag) {
}
explicit __android_log_event_list(log_msg& log_msg)
: android_log_event_list(log_msg) {
}
#if defined(_USING_LIBCXX)
operator std::string() {
if (ret) return std::string("");
const char* cp = NULL;
ssize_t len = android_log_write_list_buffer(ctx, &cp);
if (len < 0) ret = len;
if (!cp || (len <= 0)) return std::string("");
return std::string(cp, len);
}
operator std::string() {
if (ret) return std::string("");
const char* cp = NULL;
ssize_t len = android_log_write_list_buffer(ctx, &cp);
if (len < 0) ret = len;
if (!cp || (len <= 0)) return std::string("");
return std::string(cp, len);
}
#endif
};
}
#endif

View File

@ -20,11 +20,11 @@
#if !defined(__MINGW32__)
#include <pwd.h>
#endif
#include <log/uio.h>
#include <sched.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <log/uio.h>
#include <cutils/list.h> /* template, no library dependency */
#include <log/log_frontend.h>
@ -42,56 +42,54 @@ static const char baseServiceName[] = "android.logd";
static int writeToLocalInit();
static int writeToLocalAvailable(log_id_t logId);
static void writeToLocalReset();
static int writeToLocalWrite(log_id_t logId, struct timespec *ts,
struct iovec *vec, size_t nr);
static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
struct iovec* vec, size_t nr);
LIBLOG_HIDDEN struct android_log_transport_write localLoggerWrite = {
.node = { &localLoggerWrite.node, &localLoggerWrite.node },
.context.private = NULL,
.name = "local",
.available = writeToLocalAvailable,
.open = writeToLocalInit,
.close = writeToLocalReset,
.write = writeToLocalWrite,
.node = { &localLoggerWrite.node, &localLoggerWrite.node },
.context.private = NULL,
.name = "local",
.available = writeToLocalAvailable,
.open = writeToLocalInit,
.close = writeToLocalReset,
.write = writeToLocalWrite,
};
static int writeToLocalVersion(struct android_log_logger *logger,
struct android_log_transport_context *transp);
static int writeToLocalRead(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp,
struct log_msg *log_msg);
static int writeToLocalPoll(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp);
static void writeToLocalClose(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp);
static int writeToLocalClear(struct android_log_logger *logger,
struct android_log_transport_context *transp);
static ssize_t writeToLocalGetSize(
struct android_log_logger *logger,
struct android_log_transport_context *transp);
static int writeToLocalVersion(struct android_log_logger* logger,
struct android_log_transport_context* transp);
static int writeToLocalRead(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp,
struct log_msg* log_msg);
static int writeToLocalPoll(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp);
static void writeToLocalClose(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp);
static int writeToLocalClear(struct android_log_logger* logger,
struct android_log_transport_context* transp);
static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
struct android_log_transport_context* transp);
static ssize_t writeToLocalSetSize(
struct android_log_logger *logger,
struct android_log_transport_context *transp __unused,
size_t size);
struct android_log_logger* logger,
struct android_log_transport_context* transp __unused, size_t size);
static ssize_t writeToLocalGetReadbleSize(
struct android_log_logger *logger,
struct android_log_transport_context *transp);
struct android_log_logger* logger,
struct android_log_transport_context* transp);
struct android_log_transport_read localLoggerRead = {
.node = { &localLoggerRead.node, &localLoggerRead.node },
.name = "local",
.available = writeToLocalAvailable,
.version = writeToLocalVersion,
.read = writeToLocalRead,
.poll = writeToLocalPoll,
.close = writeToLocalClose,
.clear = writeToLocalClear,
.getSize = writeToLocalGetSize,
.setSize = writeToLocalSetSize,
.getReadableSize = writeToLocalGetReadbleSize,
.getPrune = NULL,
.setPrune = NULL,
.getStats = NULL,
.node = { &localLoggerRead.node, &localLoggerRead.node },
.name = "local",
.available = writeToLocalAvailable,
.version = writeToLocalVersion,
.read = writeToLocalRead,
.poll = writeToLocalPoll,
.close = writeToLocalClose,
.clear = writeToLocalClear,
.getSize = writeToLocalGetSize,
.setSize = writeToLocalSetSize,
.getReadableSize = writeToLocalGetReadbleSize,
.getPrune = NULL,
.setPrune = NULL,
.getStats = NULL,
};
struct LogBufferElement {
@ -115,53 +113,51 @@ static const size_t MAX_SIZE_DEFAULT = 32768;
*
* Confirm the following should <log/log_id.h> be adjusted in the future.
*/
#define NUMBER_OF_LOG_BUFFERS ((LOG_ID_SECURITY == (LOG_ID_MAX - 2)) ? \
LOG_ID_SECURITY : \
LOG_ID_KERNEL)
#define BLOCK_LOG_BUFFERS(id) (((id) == LOG_ID_SECURITY) || \
((id) == LOG_ID_KERNEL))
#define NUMBER_OF_LOG_BUFFERS \
((LOG_ID_SECURITY == (LOG_ID_MAX - 2)) ? LOG_ID_SECURITY : LOG_ID_KERNEL)
#define BLOCK_LOG_BUFFERS(id) \
(((id) == LOG_ID_SECURITY) || ((id) == LOG_ID_KERNEL))
static struct LogBuffer {
struct listnode head;
pthread_rwlock_t listLock;
char *serviceName; /* Also indicates ready by having a value */
char* serviceName; /* Also indicates ready by having a value */
/* Order and proximity important for memset */
size_t number[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
size_t size[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
size_t totalSize[NUMBER_OF_LOG_BUFFERS]; /* init memset */
size_t maxSize[NUMBER_OF_LOG_BUFFERS]; /* init MAX_SIZE_DEFAULT */
struct listnode *last[NUMBER_OF_LOG_BUFFERS]; /* init &head */
struct listnode* last[NUMBER_OF_LOG_BUFFERS]; /* init &head */
} logbuf = {
.head = { &logbuf.head, &logbuf.head },
.listLock = PTHREAD_RWLOCK_INITIALIZER,
.head = { &logbuf.head, &logbuf.head }, .listLock = PTHREAD_RWLOCK_INITIALIZER,
};
static void LogBufferInit(struct LogBuffer *log) {
static void LogBufferInit(struct LogBuffer* log) {
size_t i;
pthread_rwlock_wrlock(&log->listLock);
list_init(&log->head);
memset(log->number, 0,
sizeof(log->number) + sizeof(log->size) + sizeof(log->totalSize));
sizeof(log->number) + sizeof(log->size) + sizeof(log->totalSize));
for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) {
log->maxSize[i] = MAX_SIZE_DEFAULT;
log->last[i] = &log->head;
}
#ifdef __BIONIC__
asprintf(&log->serviceName, "%s@%d:%d", baseServiceName,
__android_log_uid(), getpid());
asprintf(&log->serviceName, "%s@%d:%d", baseServiceName, __android_log_uid(),
getpid());
#else
char buffer[sizeof(baseServiceName) + 1 + 5 + 1 + 5 + 8];
snprintf(buffer, sizeof(buffer), "%s@%d:%d", baseServiceName,
__android_log_uid(), getpid());
__android_log_uid(), getpid());
log->serviceName = strdup(buffer);
#endif
pthread_rwlock_unlock(&log->listLock);
}
static void LogBufferClear(struct LogBuffer *log) {
static void LogBufferClear(struct LogBuffer* log) {
size_t i;
struct listnode *node;
struct listnode* node;
pthread_rwlock_wrlock(&log->listLock);
memset(log->number, 0, sizeof(log->number) + sizeof(log->size));
@ -169,7 +165,7 @@ static void LogBufferClear(struct LogBuffer *log) {
log->last[i] = &log->head;
}
while ((node = list_head(&log->head)) != &log->head) {
struct LogBufferElement *element;
struct LogBufferElement* element;
element = node_to_item(node, struct LogBufferElement, node);
list_remove(node);
@ -178,7 +174,7 @@ static void LogBufferClear(struct LogBuffer *log) {
pthread_rwlock_unlock(&log->listLock);
}
static inline void LogBufferFree(struct LogBuffer *log) {
static inline void LogBufferFree(struct LogBuffer* log) {
pthread_rwlock_wrlock(&log->listLock);
free(log->serviceName);
log->serviceName = NULL;
@ -186,8 +182,8 @@ static inline void LogBufferFree(struct LogBuffer *log) {
LogBufferClear(log);
}
static int LogBufferLog(struct LogBuffer *log,
struct LogBufferElement *element) {
static int LogBufferLog(struct LogBuffer* log,
struct LogBufferElement* element) {
log_id_t logId = element->logId;
pthread_rwlock_wrlock(&log->listLock);
@ -199,16 +195,16 @@ static int LogBufferLog(struct LogBuffer *log,
log->last[logId] = list_tail(&log->head);
}
while (log->size[logId] > log->maxSize[logId]) {
struct listnode *node = log->last[logId];
struct LogBufferElement *e;
struct android_log_logger_list *logger_list;
struct listnode* node = log->last[logId];
struct LogBufferElement* e;
struct android_log_logger_list* logger_list;
e = node_to_item(node, struct LogBufferElement, node);
log->number[logId]--;
log->size[logId] -= e->len;
logger_list_rdlock();
logger_list_for_each(logger_list) {
struct android_log_transport_context *transp;
struct android_log_transport_context* transp;
transport_context_for_each(transp, logger_list) {
if ((transp->transport == &localLoggerRead) &&
@ -243,7 +239,7 @@ static int LogBufferLog(struct LogBuffer *log,
*/
static int writeToLocalInit() {
pthread_attr_t attr;
struct LogBuffer *log;
struct LogBuffer* log;
if (writeToLocalAvailable(LOG_ID_MAIN) < 0) {
return -EPERM;
@ -251,7 +247,7 @@ static int writeToLocalInit() {
log = &logbuf;
if (!log->serviceName) {
LogBufferInit(log);
LogBufferInit(log);
}
if (!log->serviceName) {
@ -275,7 +271,7 @@ static int writeToLocalAvailable(log_id_t logId) {
return -EINVAL;
}
/* Android hard coded permitted, system goes to logd */
/* Android hard coded permitted, system goes to logd */
#if !defined(__MINGW32__)
if (__android_log_frontend == LOGGER_DEFAULT) {
uid = __android_log_uid();
@ -290,10 +286,10 @@ static int writeToLocalAvailable(log_id_t logId) {
return 0;
}
static int writeToLocalWrite(log_id_t logId, struct timespec *ts,
struct iovec *vec, size_t nr) {
static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
struct iovec* vec, size_t nr) {
size_t len, i;
struct LogBufferElement *element;
struct LogBufferElement* element;
if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
return -EINVAL;
@ -307,8 +303,8 @@ static int writeToLocalWrite(log_id_t logId, struct timespec *ts,
if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
len = LOGGER_ENTRY_MAX_PAYLOAD;
}
element = (struct LogBufferElement *)calloc(1,
sizeof(struct LogBufferElement) + len + 1);
element = (struct LogBufferElement*)calloc(
1, sizeof(struct LogBufferElement) + len + 1);
if (!element) {
return errno ? -errno : -ENOMEM;
}
@ -322,7 +318,7 @@ static int writeToLocalWrite(log_id_t logId, struct timespec *ts,
element->logId = logId;
element->len = len;
char *cp = element->msg;
char* cp = element->msg;
for (i = 0; i < nr; ++i) {
size_t iov_len = vec[i].iov_len;
if (iov_len > len) {
@ -339,17 +335,17 @@ static int writeToLocalWrite(log_id_t logId, struct timespec *ts,
return LogBufferLog(&logbuf, element);
}
static int writeToLocalVersion(
struct android_log_logger *logger __unused,
struct android_log_transport_context *transp __unused) {
static int writeToLocalVersion(struct android_log_logger* logger __unused,
struct android_log_transport_context* transp
__unused) {
return 3;
}
/* within reader lock, serviceName already validated */
static struct listnode *writeToLocalNode(
struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp) {
struct listnode *node;
static struct listnode* writeToLocalNode(
struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp) {
struct listnode* node;
unsigned logMask;
unsigned int tail;
@ -366,7 +362,7 @@ static struct listnode *writeToLocalNode(
tail = logger_list->tail;
for (node = list_head(&logbuf.head); node != &logbuf.head; node = node->next) {
struct LogBufferElement *element;
struct LogBufferElement* element;
log_id_t logId;
element = node_to_item(node, struct LogBufferElement, node);
@ -380,12 +376,11 @@ static struct listnode *writeToLocalNode(
return transp->context.node = node;
}
static int writeToLocalRead(
struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp,
struct log_msg *log_msg) {
static int writeToLocalRead(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp,
struct log_msg* log_msg) {
int ret;
struct listnode *node;
struct listnode* node;
unsigned logMask;
pthread_rwlock_rdlock(&logbuf.listLock);
@ -401,7 +396,7 @@ static int writeToLocalRead(
ret = 0;
while (node != list_head(&logbuf.head)) {
struct LogBufferElement *element;
struct LogBufferElement* element;
log_id_t logId;
node = node->prev;
@ -429,23 +424,22 @@ static int writeToLocalRead(
return ret;
}
static int writeToLocalPoll(
struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp) {
static int writeToLocalPoll(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp) {
int ret = (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
pthread_rwlock_rdlock(&logbuf.listLock);
if (logbuf.serviceName) {
unsigned logMask = transp->logMask;
struct listnode *node = writeToLocalNode(logger_list, transp);
struct listnode* node = writeToLocalNode(logger_list, transp);
ret = (node != list_head(&logbuf.head));
if (ret) {
do {
ret = !!(logMask & (1 << (node_to_item(node->prev,
struct LogBufferElement,
node))->logId));
ret = !!(logMask &
(1 << (node_to_item(node->prev, struct LogBufferElement, node))
->logId));
} while (!ret && ((node = node->prev) != list_head(&logbuf.head)));
}
@ -457,17 +451,17 @@ static int writeToLocalPoll(
return ret;
}
static void writeToLocalClose(
struct android_log_logger_list *logger_list __unused,
struct android_log_transport_context *transp) {
static void writeToLocalClose(struct android_log_logger_list* logger_list
__unused,
struct android_log_transport_context* transp) {
pthread_rwlock_wrlock(&logbuf.listLock);
transp->context.node = list_head(&logbuf.head);
pthread_rwlock_unlock(&logbuf.listLock);
}
static int writeToLocalClear(
struct android_log_logger *logger,
struct android_log_transport_context *unused __unused) {
static int writeToLocalClear(struct android_log_logger* logger,
struct android_log_transport_context* unused
__unused) {
log_id_t logId = logger->logId;
struct listnode *node, *n;
@ -479,15 +473,15 @@ static int writeToLocalClear(
logbuf.number[logId] = 0;
logbuf.last[logId] = &logbuf.head;
list_for_each_safe(node, n, &logbuf.head) {
struct LogBufferElement *element;
struct LogBufferElement* element;
element = node_to_item(node, struct LogBufferElement, node);
if (logId == element->logId) {
struct android_log_logger_list *logger_list;
struct android_log_logger_list* logger_list;
logger_list_rdlock();
logger_list_for_each(logger_list) {
struct android_log_transport_context *transp;
struct android_log_transport_context* transp;
transport_context_for_each(transp, logger_list) {
if ((transp->transport == &localLoggerRead) &&
@ -507,9 +501,9 @@ static int writeToLocalClear(
return 0;
}
static ssize_t writeToLocalGetSize(
struct android_log_logger *logger,
struct android_log_transport_context *transp __unused) {
static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
struct android_log_transport_context* transp
__unused) {
ssize_t ret = -EINVAL;
log_id_t logId = logger->logId;
@ -523,9 +517,8 @@ static ssize_t writeToLocalGetSize(
}
static ssize_t writeToLocalSetSize(
struct android_log_logger *logger,
struct android_log_transport_context *transp __unused,
size_t size) {
struct android_log_logger* logger,
struct android_log_transport_context* transp __unused, size_t size) {
ssize_t ret = -EINVAL;
if ((size > LOGGER_ENTRY_MAX_LEN) || (size < (4 * 1024 * 1024))) {
@ -541,8 +534,8 @@ static ssize_t writeToLocalSetSize(
}
static ssize_t writeToLocalGetReadbleSize(
struct android_log_logger *logger,
struct android_log_transport_context *transp __unused) {
struct android_log_logger* logger,
struct android_log_transport_context* transp __unused) {
ssize_t ret = -EINVAL;
log_id_t logId = logger->logId;

View File

@ -30,270 +30,266 @@
#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
typedef struct {
uint32_t tag;
unsigned pos; /* Read/write position into buffer */
unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */
unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */
unsigned list_nest_depth;
unsigned len; /* Length or raw buffer. */
bool overflow;
bool list_stop; /* next call decrement list_nest_depth and issue a stop */
enum {
kAndroidLoggerRead = 1,
kAndroidLoggerWrite = 2,
} read_write_flag;
uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
uint32_t tag;
unsigned pos; /* Read/write position into buffer */
unsigned count[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* Number of elements */
unsigned list[ANDROID_MAX_LIST_NEST_DEPTH + 1]; /* pos for list counter */
unsigned list_nest_depth;
unsigned len; /* Length or raw buffer. */
bool overflow;
bool list_stop; /* next call decrement list_nest_depth and issue a stop */
enum {
kAndroidLoggerRead = 1,
kAndroidLoggerWrite = 2,
} read_write_flag;
uint8_t storage[LOGGER_ENTRY_MAX_PAYLOAD];
} android_log_context_internal;
LIBLOG_ABI_PUBLIC android_log_context create_android_logger(uint32_t tag) {
size_t needed, i;
android_log_context_internal *context;
size_t needed, i;
android_log_context_internal* context;
context = calloc(1, sizeof(android_log_context_internal));
if (!context) {
return NULL;
}
context->tag = tag;
context->read_write_flag = kAndroidLoggerWrite;
needed = sizeof(uint8_t) + sizeof(uint8_t);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
}
/* Everything is a list */
context->storage[context->pos + 0] = EVENT_TYPE_LIST;
context->list[0] = context->pos + 1;
context->pos += needed;
context = calloc(1, sizeof(android_log_context_internal));
if (!context) {
return NULL;
}
context->tag = tag;
context->read_write_flag = kAndroidLoggerWrite;
needed = sizeof(uint8_t) + sizeof(uint8_t);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
}
/* Everything is a list */
context->storage[context->pos + 0] = EVENT_TYPE_LIST;
context->list[0] = context->pos + 1;
context->pos += needed;
return (android_log_context)context;
return (android_log_context)context;
}
LIBLOG_ABI_PUBLIC android_log_context create_android_log_parser(
const char *msg,
size_t len) {
android_log_context_internal *context;
size_t i;
LIBLOG_ABI_PUBLIC android_log_context create_android_log_parser(const char* msg,
size_t len) {
android_log_context_internal* context;
size_t i;
context = calloc(1, sizeof(android_log_context_internal));
if (!context) {
return NULL;
}
len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
context->len = len;
memcpy(context->storage, msg, len);
context->read_write_flag = kAndroidLoggerRead;
context = calloc(1, sizeof(android_log_context_internal));
if (!context) {
return NULL;
}
len = (len <= MAX_EVENT_PAYLOAD) ? len : MAX_EVENT_PAYLOAD;
context->len = len;
memcpy(context->storage, msg, len);
context->read_write_flag = kAndroidLoggerRead;
return (android_log_context)context;
return (android_log_context)context;
}
LIBLOG_ABI_PUBLIC int android_log_destroy(android_log_context *ctx) {
android_log_context_internal *context;
LIBLOG_ABI_PUBLIC int android_log_destroy(android_log_context* ctx) {
android_log_context_internal* context;
context = (android_log_context_internal *)*ctx;
if (!context) {
return -EBADF;
}
memset(context, 0, sizeof(*context));
free(context);
*ctx = NULL;
return 0;
context = (android_log_context_internal*)*ctx;
if (!context) {
return -EBADF;
}
memset(context, 0, sizeof(*context));
free(context);
*ctx = NULL;
return 0;
}
LIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) {
size_t needed;
android_log_context_internal *context;
size_t needed;
android_log_context_internal* context;
context = (android_log_context_internal *)ctx;
if (!context ||
(kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
context->overflow = true;
return -EOVERFLOW;
}
needed = sizeof(uint8_t) + sizeof(uint8_t);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
context->count[context->list_nest_depth]++;
context->list_nest_depth++;
if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
context->overflow = true;
return -EOVERFLOW;
}
if (context->overflow) {
return -EIO;
}
context->storage[context->pos + 0] = EVENT_TYPE_LIST;
context->storage[context->pos + 1] = 0;
context->list[context->list_nest_depth] = context->pos + 1;
context->count[context->list_nest_depth] = 0;
context->pos += needed;
return 0;
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
context->overflow = true;
return -EOVERFLOW;
}
needed = sizeof(uint8_t) + sizeof(uint8_t);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
context->count[context->list_nest_depth]++;
context->list_nest_depth++;
if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
context->overflow = true;
return -EOVERFLOW;
}
if (context->overflow) {
return -EIO;
}
context->storage[context->pos + 0] = EVENT_TYPE_LIST;
context->storage[context->pos + 1] = 0;
context->list[context->list_nest_depth] = context->pos + 1;
context->count[context->list_nest_depth] = 0;
context->pos += needed;
return 0;
}
static inline void copy4LE(uint8_t *buf, uint32_t val)
{
buf[0] = val & 0xFF;
buf[1] = (val >> 8) & 0xFF;
buf[2] = (val >> 16) & 0xFF;
buf[3] = (val >> 24) & 0xFF;
static inline void copy4LE(uint8_t* buf, uint32_t val) {
buf[0] = val & 0xFF;
buf[1] = (val >> 8) & 0xFF;
buf[2] = (val >> 16) & 0xFF;
buf[3] = (val >> 24) & 0xFF;
}
LIBLOG_ABI_PUBLIC int android_log_write_int32(android_log_context ctx,
int32_t value) {
size_t needed;
android_log_context_internal *context;
size_t needed;
android_log_context_internal* context;
context = (android_log_context_internal *)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->overflow) {
return -EIO;
}
needed = sizeof(uint8_t) + sizeof(value);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_INT;
copy4LE(&context->storage[context->pos + 1], value);
context->pos += needed;
return 0;
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->overflow) {
return -EIO;
}
needed = sizeof(uint8_t) + sizeof(value);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_INT;
copy4LE(&context->storage[context->pos + 1], value);
context->pos += needed;
return 0;
}
static inline void copy8LE(uint8_t *buf, uint64_t val)
{
buf[0] = val & 0xFF;
buf[1] = (val >> 8) & 0xFF;
buf[2] = (val >> 16) & 0xFF;
buf[3] = (val >> 24) & 0xFF;
buf[4] = (val >> 32) & 0xFF;
buf[5] = (val >> 40) & 0xFF;
buf[6] = (val >> 48) & 0xFF;
buf[7] = (val >> 56) & 0xFF;
static inline void copy8LE(uint8_t* buf, uint64_t val) {
buf[0] = val & 0xFF;
buf[1] = (val >> 8) & 0xFF;
buf[2] = (val >> 16) & 0xFF;
buf[3] = (val >> 24) & 0xFF;
buf[4] = (val >> 32) & 0xFF;
buf[5] = (val >> 40) & 0xFF;
buf[6] = (val >> 48) & 0xFF;
buf[7] = (val >> 56) & 0xFF;
}
LIBLOG_ABI_PUBLIC int android_log_write_int64(android_log_context ctx,
int64_t value) {
size_t needed;
android_log_context_internal *context;
size_t needed;
android_log_context_internal* context;
context = (android_log_context_internal *)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->overflow) {
return -EIO;
}
needed = sizeof(uint8_t) + sizeof(value);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_LONG;
copy8LE(&context->storage[context->pos + 1], value);
context->pos += needed;
return 0;
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->overflow) {
return -EIO;
}
needed = sizeof(uint8_t) + sizeof(value);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_LONG;
copy8LE(&context->storage[context->pos + 1], value);
context->pos += needed;
return 0;
}
LIBLOG_ABI_PUBLIC int android_log_write_string8_len(android_log_context ctx,
const char *value,
const char* value,
size_t maxlen) {
size_t needed;
ssize_t len;
android_log_context_internal *context;
size_t needed;
ssize_t len;
android_log_context_internal* context;
context = (android_log_context_internal *)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->overflow) {
return -EIO;
}
if (!value) {
value = "";
}
len = strnlen(value, maxlen);
needed = sizeof(uint8_t) + sizeof(int32_t) + len;
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
/* Truncate string for delivery */
len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
if (len <= 0) {
context->overflow = true;
return -EIO;
}
if (context->overflow) {
return -EIO;
}
if (!value) {
value = "";
}
len = strnlen(value, maxlen);
needed = sizeof(uint8_t) + sizeof(int32_t) + len;
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
/* Truncate string for delivery */
len = MAX_EVENT_PAYLOAD - context->pos - 1 - sizeof(int32_t);
if (len <= 0) {
context->overflow = true;
return -EIO;
}
}
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_STRING;
copy4LE(&context->storage[context->pos + 1], len);
if (len) {
memcpy(&context->storage[context->pos + 5], value, len);
}
context->pos += needed;
return len;
}
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_STRING;
copy4LE(&context->storage[context->pos + 1], len);
if (len) {
memcpy(&context->storage[context->pos + 5], value, len);
}
context->pos += needed;
return len;
}
LIBLOG_ABI_PUBLIC int android_log_write_string8(android_log_context ctx,
const char *value) {
return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
const char* value) {
return android_log_write_string8_len(ctx, value, MAX_EVENT_PAYLOAD);
}
LIBLOG_ABI_PUBLIC int android_log_write_float32(android_log_context ctx,
float value) {
size_t needed;
uint32_t ivalue;
android_log_context_internal *context;
size_t needed;
uint32_t ivalue;
android_log_context_internal* context;
context = (android_log_context_internal *)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->overflow) {
return -EIO;
}
needed = sizeof(uint8_t) + sizeof(ivalue);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
ivalue = *(uint32_t *)&value;
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;
copy4LE(&context->storage[context->pos + 1], ivalue);
context->pos += needed;
return 0;
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->overflow) {
return -EIO;
}
needed = sizeof(uint8_t) + sizeof(ivalue);
if ((context->pos + needed) > MAX_EVENT_PAYLOAD) {
context->overflow = true;
return -EIO;
}
ivalue = *(uint32_t*)&value;
context->count[context->list_nest_depth]++;
context->storage[context->pos + 0] = EVENT_TYPE_FLOAT;
copy4LE(&context->storage[context->pos + 1], ivalue);
context->pos += needed;
return 0;
}
LIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) {
android_log_context_internal *context;
android_log_context_internal* context;
context = (android_log_context_internal *)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
context->overflow = true;
context->list_nest_depth--;
return -EOVERFLOW;
}
if (!context->list_nest_depth) {
context->overflow = true;
return -EOVERFLOW;
}
if (context->list[context->list_nest_depth] <= 0) {
context->list_nest_depth--;
context->overflow = true;
return -EOVERFLOW;
}
context->storage[context->list[context->list_nest_depth]] =
context->count[context->list_nest_depth];
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) {
context->overflow = true;
context->list_nest_depth--;
return 0;
return -EOVERFLOW;
}
if (!context->list_nest_depth) {
context->overflow = true;
return -EOVERFLOW;
}
if (context->list[context->list_nest_depth] <= 0) {
context->list_nest_depth--;
context->overflow = true;
return -EOVERFLOW;
}
context->storage[context->list[context->list_nest_depth]] =
context->count[context->list_nest_depth];
context->list_nest_depth--;
return 0;
}
/*
@ -301,86 +297,84 @@ LIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) {
*/
LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx,
log_id_t id) {
android_log_context_internal *context;
const char *msg;
ssize_t len;
android_log_context_internal* context;
const char* msg;
ssize_t len;
if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY)) {
return -EINVAL;
}
if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY)) {
return -EINVAL;
}
context = (android_log_context_internal *)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->list_nest_depth) {
return -EIO;
}
/* NB: if there was overflow, then log is truncated. Nothing reported */
context->storage[1] = context->count[0];
len = context->len = context->pos;
msg = (const char*)context->storage;
/* it's not a list */
if (context->count[0] <= 1) {
len -= sizeof(uint8_t) + sizeof(uint8_t);
if (len < 0) {
len = 0;
}
if (context->list_nest_depth) {
return -EIO;
}
/* NB: if there was overflow, then log is truncated. Nothing reported */
context->storage[1] = context->count[0];
len = context->len = context->pos;
msg = (const char *)context->storage;
/* it's not a list */
if (context->count[0] <= 1) {
len -= sizeof(uint8_t) + sizeof(uint8_t);
if (len < 0) {
len = 0;
}
msg += sizeof(uint8_t) + sizeof(uint8_t);
}
return (id == LOG_ID_EVENTS) ?
__android_log_bwrite(context->tag, msg, len) :
__android_log_security_bwrite(context->tag, msg, len);
msg += sizeof(uint8_t) + sizeof(uint8_t);
}
return (id == LOG_ID_EVENTS)
? __android_log_bwrite(context->tag, msg, len)
: __android_log_security_bwrite(context->tag, msg, len);
}
LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
const char **buffer) {
android_log_context_internal *context;
const char *msg;
ssize_t len;
const char** buffer) {
android_log_context_internal* context;
const char* msg;
ssize_t len;
context = (android_log_context_internal *)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
context = (android_log_context_internal*)ctx;
if (!context || (kAndroidLoggerWrite != context->read_write_flag)) {
return -EBADF;
}
if (context->list_nest_depth) {
return -EIO;
}
if (buffer == NULL) {
return -EFAULT;
}
/* NB: if there was overflow, then log is truncated. Nothing reported */
context->storage[1] = context->count[0];
len = context->len = context->pos;
msg = (const char*)context->storage;
/* it's not a list */
if (context->count[0] <= 1) {
len -= sizeof(uint8_t) + sizeof(uint8_t);
if (len < 0) {
len = 0;
}
if (context->list_nest_depth) {
return -EIO;
}
if (buffer == NULL) {
return -EFAULT;
}
/* NB: if there was overflow, then log is truncated. Nothing reported */
context->storage[1] = context->count[0];
len = context->len = context->pos;
msg = (const char *)context->storage;
/* it's not a list */
if (context->count[0] <= 1) {
len -= sizeof(uint8_t) + sizeof(uint8_t);
if (len < 0) {
len = 0;
}
msg += sizeof(uint8_t) + sizeof(uint8_t);
}
*buffer = msg;
return len;
msg += sizeof(uint8_t) + sizeof(uint8_t);
}
*buffer = msg;
return len;
}
/*
* Extract a 4-byte value from a byte stream.
*/
static inline uint32_t get4LE(const uint8_t* src)
{
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
static inline uint32_t get4LE(const uint8_t* src) {
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}
/*
* Extract an 8-byte value from a byte stream.
*/
static inline uint64_t get8LE(const uint8_t* src)
{
uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
return ((uint64_t) high << 32) | (uint64_t) low;
static inline uint64_t get8LE(const uint8_t* src) {
uint32_t low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
uint32_t high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
return ((uint64_t)high << 32) | (uint64_t)low;
}
/*
@ -391,181 +385,181 @@ static inline uint64_t get8LE(const uint8_t* src)
* (although it won't crash).
*/
static android_log_list_element android_log_read_next_internal(
android_log_context ctx, int peek) {
android_log_list_element elem;
unsigned pos;
android_log_context_internal *context;
android_log_context ctx, int peek) {
android_log_list_element elem;
unsigned pos;
android_log_context_internal* context;
context = (android_log_context_internal *)ctx;
context = (android_log_context_internal*)ctx;
memset(&elem, 0, sizeof(elem));
memset(&elem, 0, sizeof(elem));
/* Nothing to parse from this context, so return complete. */
if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
(context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
(context->count[context->list_nest_depth] >=
(MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
elem.type = EVENT_TYPE_UNKNOWN;
if (context &&
(context->list_stop ||
((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
!context->count[context->list_nest_depth]))) {
elem.type = EVENT_TYPE_LIST_STOP;
/* Nothing to parse from this context, so return complete. */
if (!context || (kAndroidLoggerRead != context->read_write_flag) ||
(context->list_nest_depth > ANDROID_MAX_LIST_NEST_DEPTH) ||
(context->count[context->list_nest_depth] >=
(MAX_EVENT_PAYLOAD / (sizeof(uint8_t) + sizeof(uint8_t))))) {
elem.type = EVENT_TYPE_UNKNOWN;
if (context && (context->list_stop ||
((context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) &&
!context->count[context->list_nest_depth]))) {
elem.type = EVENT_TYPE_LIST_STOP;
}
elem.complete = true;
return elem;
}
/*
* Use a different variable to update the position in case this
* operation is a "peek".
*/
pos = context->pos;
if (context->list_stop) {
elem.type = EVENT_TYPE_LIST_STOP;
elem.complete = !context->count[0] &&
(!context->list_nest_depth ||
((context->list_nest_depth == 1) && !context->count[1]));
if (!peek) {
/* Suck in superfluous stop */
if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
context->pos = pos + 1;
}
if (context->list_nest_depth) {
--context->list_nest_depth;
if (context->count[context->list_nest_depth]) {
context->list_stop = false;
}
elem.complete = true;
return elem;
} else {
context->list_stop = false;
}
}
return elem;
}
if ((pos + 1) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = true;
return elem;
}
/*
* Use a different variable to update the position in case this
* operation is a "peek".
*/
pos = context->pos;
if (context->list_stop) {
elem.type = EVENT_TYPE_LIST_STOP;
elem.complete = !context->count[0] && (!context->list_nest_depth ||
((context->list_nest_depth == 1) && !context->count[1]));
if (!peek) {
/* Suck in superfluous stop */
if (context->storage[pos] == EVENT_TYPE_LIST_STOP) {
context->pos = pos + 1;
}
if (context->list_nest_depth) {
--context->list_nest_depth;
if (context->count[context->list_nest_depth]) {
context->list_stop = false;
}
} else {
context->list_stop = false;
}
}
return elem;
}
if ((pos + 1) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = true;
return elem;
}
elem.type = context->storage[pos++];
switch ((int)elem.type) {
elem.type = context->storage[pos++];
switch ((int)elem.type) {
case EVENT_TYPE_FLOAT:
/* Rely on union to translate elem.data.int32 into elem.data.float32 */
/* FALLTHRU */
/* Rely on union to translate elem.data.int32 into elem.data.float32 */
/* FALLTHRU */
case EVENT_TYPE_INT:
elem.len = sizeof(int32_t);
if ((pos + elem.len) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
elem.data.int32 = get4LE(&context->storage[pos]);
/* common tangeable object suffix */
pos += elem.len;
elem.complete = !context->list_nest_depth && !context->count[0];
if (!peek) {
if (!context->count[context->list_nest_depth] ||
!--(context->count[context->list_nest_depth])) {
context->list_stop = true;
}
context->pos = pos;
}
elem.len = sizeof(int32_t);
if ((pos + elem.len) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
elem.data.int32 = get4LE(&context->storage[pos]);
/* common tangeable object suffix */
pos += elem.len;
elem.complete = !context->list_nest_depth && !context->count[0];
if (!peek) {
if (!context->count[context->list_nest_depth] ||
!--(context->count[context->list_nest_depth])) {
context->list_stop = true;
}
context->pos = pos;
}
return elem;
case EVENT_TYPE_LONG:
elem.len = sizeof(int64_t);
if ((pos + elem.len) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
elem.data.int64 = get8LE(&context->storage[pos]);
/* common tangeable object suffix */
pos += elem.len;
elem.complete = !context->list_nest_depth && !context->count[0];
if (!peek) {
if (!context->count[context->list_nest_depth] ||
!--(context->count[context->list_nest_depth])) {
context->list_stop = true;
}
context->pos = pos;
}
elem.len = sizeof(int64_t);
if ((pos + elem.len) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
elem.data.int64 = get8LE(&context->storage[pos]);
/* common tangeable object suffix */
pos += elem.len;
elem.complete = !context->list_nest_depth && !context->count[0];
if (!peek) {
if (!context->count[context->list_nest_depth] ||
!--(context->count[context->list_nest_depth])) {
context->list_stop = true;
}
context->pos = pos;
}
return elem;
case EVENT_TYPE_STRING:
if ((pos + sizeof(int32_t)) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = true;
return elem;
}
elem.len = get4LE(&context->storage[pos]);
pos += sizeof(int32_t);
if ((pos + elem.len) > context->len) {
elem.len = context->len - pos; /* truncate string */
elem.complete = true;
if (!elem.len) {
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
}
elem.data.string = (char *)&context->storage[pos];
/* common tangeable object suffix */
pos += elem.len;
elem.complete = !context->list_nest_depth && !context->count[0];
if (!peek) {
if (!context->count[context->list_nest_depth] ||
!--(context->count[context->list_nest_depth])) {
context->list_stop = true;
}
context->pos = pos;
}
if ((pos + sizeof(int32_t)) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = true;
return elem;
}
elem.len = get4LE(&context->storage[pos]);
pos += sizeof(int32_t);
if ((pos + elem.len) > context->len) {
elem.len = context->len - pos; /* truncate string */
elem.complete = true;
if (!elem.len) {
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
}
elem.data.string = (char*)&context->storage[pos];
/* common tangeable object suffix */
pos += elem.len;
elem.complete = !context->list_nest_depth && !context->count[0];
if (!peek) {
if (!context->count[context->list_nest_depth] ||
!--(context->count[context->list_nest_depth])) {
context->list_stop = true;
}
context->pos = pos;
}
return elem;
case EVENT_TYPE_LIST:
if ((pos + sizeof(uint8_t)) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = true;
return elem;
}
elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
if (peek) {
return elem;
}
if (context->count[context->list_nest_depth]) {
context->count[context->list_nest_depth]--;
}
context->list_stop = !context->storage[pos];
context->list_nest_depth++;
if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
context->count[context->list_nest_depth] = context->storage[pos];
}
context->pos = pos + sizeof(uint8_t);
if ((pos + sizeof(uint8_t)) > context->len) {
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = true;
return elem;
}
elem.complete = context->list_nest_depth >= ANDROID_MAX_LIST_NEST_DEPTH;
if (peek) {
return elem;
}
if (context->count[context->list_nest_depth]) {
context->count[context->list_nest_depth]--;
}
context->list_stop = !context->storage[pos];
context->list_nest_depth++;
if (context->list_nest_depth <= ANDROID_MAX_LIST_NEST_DEPTH) {
context->count[context->list_nest_depth] = context->storage[pos];
}
context->pos = pos + sizeof(uint8_t);
return elem;
case EVENT_TYPE_LIST_STOP: /* Suprise Newline terminates lists. */
if (!peek) {
context->pos = pos;
}
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = !context->list_nest_depth;
if (context->list_nest_depth > 0) {
elem.type = EVENT_TYPE_LIST_STOP;
if (!peek) {
context->pos = pos;
context->list_nest_depth--;
}
elem.type = EVENT_TYPE_UNKNOWN;
elem.complete = !context->list_nest_depth;
if (context->list_nest_depth > 0) {
elem.type = EVENT_TYPE_LIST_STOP;
if (!peek) {
context->list_nest_depth--;
}
}
return elem;
}
return elem;
default:
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
elem.type = EVENT_TYPE_UNKNOWN;
return elem;
}
}
LIBLOG_ABI_PUBLIC android_log_list_element android_log_read_next(
android_log_context ctx) {
return android_log_read_next_internal(ctx, 0);
LIBLOG_ABI_PUBLIC android_log_list_element
android_log_read_next(android_log_context ctx) {
return android_log_read_next_internal(ctx, 0);
}
LIBLOG_ABI_PUBLIC android_log_list_element android_log_peek_next(
android_log_context ctx) {
return android_log_read_next_internal(ctx, 1);
LIBLOG_ABI_PUBLIC android_log_list_element
android_log_peek_next(android_log_context ctx) {
return android_log_read_next_internal(ctx, 1);
}

View File

@ -24,31 +24,28 @@
#define MAX_SUBTAG_LEN 32
LIBLOG_ABI_PUBLIC int __android_log_error_write(
int tag,
const char *subTag,
int32_t uid,
const char *data, uint32_t dataLen)
{
int ret = -EINVAL;
LIBLOG_ABI_PUBLIC int __android_log_error_write(int tag, const char* subTag,
int32_t uid, const char* data,
uint32_t dataLen) {
int ret = -EINVAL;
if (subTag && (data || !dataLen)) {
android_log_context ctx = create_android_logger(tag);
if (subTag && (data || !dataLen)) {
android_log_context ctx = create_android_logger(tag);
ret = -ENOMEM;
if (ctx) {
ret = android_log_write_string8_len(ctx, subTag, MAX_SUBTAG_LEN);
if (ret >= 0) {
ret = android_log_write_int32(ctx, uid);
if (ret >= 0) {
ret = android_log_write_string8_len(ctx, data, dataLen);
if (ret >= 0) {
ret = android_log_write_list(ctx, LOG_ID_EVENTS);
}
}
}
android_log_destroy(&ctx);
ret = -ENOMEM;
if (ctx) {
ret = android_log_write_string8_len(ctx, subTag, MAX_SUBTAG_LEN);
if (ret >= 0) {
ret = android_log_write_int32(ctx, uid);
if (ret >= 0) {
ret = android_log_write_string8_len(ctx, data, dataLen);
if (ret >= 0) {
ret = android_log_write_list(ctx, LOG_ID_EVENTS);
}
}
}
android_log_destroy(&ctx);
}
return ret;
}
return ret;
}

View File

@ -46,7 +46,7 @@
#if defined(_WIN32)
#define LIBLOG_WEAK static /* Accept that it is totally private */
#else
#define LIBLOG_WEAK __attribute__((weak,visibility("default")))
#define LIBLOG_WEAK __attribute__((weak, visibility("default")))
#endif
/* possible missing definitions in sys/cdefs.h */
@ -54,8 +54,8 @@
/* DECLS */
#ifndef __BEGIN_DECLS
#if defined(__cplusplus)
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS }
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS }
#else
#define __BEGIN_DECLS
#define __END_DECLS
@ -64,19 +64,21 @@
/* Unused argument. For C code only, remove symbol name for C++ */
#ifndef __unused
#define __unused __attribute__((__unused__))
#define __unused __attribute__((__unused__))
#endif
/* possible missing definitions in unistd.h */
#ifndef TEMP_FAILURE_RETRY
/* Used to retry syscalls that can return EINTR. */
#define TEMP_FAILURE_RETRY(exp) ({ \
#define TEMP_FAILURE_RETRY(exp) \
({ \
__typeof__(exp) _rc; \
do { \
_rc = (exp); \
_rc = (exp); \
} while (_rc == -1 && errno == EINTR); \
_rc; })
_rc; \
})
#endif
#endif /* _LIBLOG_PORTABILITY_H__ */

View File

@ -31,8 +31,8 @@ static time_t g_last_clock;
// of varying the 'seconds' argument to their pleasure.
static time_t g_last_seconds;
static const time_t last_seconds_default = 10;
static const time_t last_seconds_max = 24 * 60 * 60; // maximum of a day
static const time_t last_seconds_min = 2; // granularity
static const time_t last_seconds_max = 24 * 60 * 60; // maximum of a day
static const time_t last_seconds_min = 2; // granularity
// Lock to protect last_clock and last_seconds, but also 'last'
// argument (not NULL) as supplied to __android_log_ratelimit.
static pthread_mutex_t lock_ratelimit = PTHREAD_MUTEX_INITIALIZER;
@ -43,44 +43,44 @@ static pthread_mutex_t lock_ratelimit = PTHREAD_MUTEX_INITIALIZER;
// can not acquire a lock, 0 if we are not to log a message, and 1
// if we are ok to log a message. Caller should check > 0 for true.
LIBLOG_ABI_PUBLIC int __android_log_ratelimit(time_t seconds, time_t* last) {
int save_errno = errno;
int save_errno = errno;
// Two reasons for trylock failure:
// 1. In a signal handler. Must prevent deadlock
// 2. Too many threads calling __android_log_ratelimit.
// Bonus to not print if they race here because that
// dovetails the goal of ratelimiting. One may print
// and the others will wait their turn ...
if (pthread_mutex_trylock(&lock_ratelimit)) {
if (save_errno) errno = save_errno;
return -1;
}
// Two reasons for trylock failure:
// 1. In a signal handler. Must prevent deadlock
// 2. Too many threads calling __android_log_ratelimit.
// Bonus to not print if they race here because that
// dovetails the goal of ratelimiting. One may print
// and the others will wait their turn ...
if (pthread_mutex_trylock(&lock_ratelimit)) {
if (save_errno) errno = save_errno;
return -1;
}
if (seconds == 0) {
seconds = last_seconds_default;
} else if (seconds < last_seconds_min) {
seconds = last_seconds_min;
} else if (seconds > last_seconds_max) {
seconds = last_seconds_max;
}
if (seconds == 0) {
seconds = last_seconds_default;
} else if (seconds < last_seconds_min) {
seconds = last_seconds_min;
} else if (seconds > last_seconds_max) {
seconds = last_seconds_max;
}
if (!last) {
if (g_last_seconds > seconds) {
seconds = g_last_seconds;
} else if (g_last_seconds < seconds) {
g_last_seconds = seconds;
}
last = &g_last_clock;
if (!last) {
if (g_last_seconds > seconds) {
seconds = g_last_seconds;
} else if (g_last_seconds < seconds) {
g_last_seconds = seconds;
}
last = &g_last_clock;
}
time_t now = time(NULL);
if ((now == (time_t)-1) || ((*last + seconds) > now)) {
pthread_mutex_unlock(&lock_ratelimit);
if (save_errno) errno = save_errno;
return 0;
}
*last = now;
time_t now = time(NULL);
if ((now == (time_t)-1) || ((*last + seconds) > now)) {
pthread_mutex_unlock(&lock_ratelimit);
if (save_errno) errno = save_errno;
return 1;
return 0;
}
*last = now;
pthread_mutex_unlock(&lock_ratelimit);
if (save_errno) errno = save_errno;
return 1;
}

View File

@ -28,164 +28,164 @@ LIBLOG_ABI_PRIVATE const timespec log_time::EPOCH = { 0, 0 };
// Add %#q for fractional seconds to standard strptime function
LIBLOG_ABI_PRIVATE char *log_time::strptime(const char *s, const char *format) {
time_t now;
LIBLOG_ABI_PRIVATE char* log_time::strptime(const char* s, const char* format) {
time_t now;
#ifdef __linux__
*this = log_time(CLOCK_REALTIME);
now = tv_sec;
*this = log_time(CLOCK_REALTIME);
now = tv_sec;
#else
time(&now);
tv_sec = now;
tv_nsec = 0;
time(&now);
tv_sec = now;
tv_nsec = 0;
#endif
struct tm *ptm;
struct tm* ptm;
#if !defined(_WIN32)
struct tm tmBuf;
ptm = localtime_r(&now, &tmBuf);
struct tm tmBuf;
ptm = localtime_r(&now, &tmBuf);
#else
ptm = localtime(&now);
ptm = localtime(&now);
#endif
char fmt[strlen(format) + 1];
strcpy(fmt, format);
char fmt[strlen(format) + 1];
strcpy(fmt, format);
char *ret = const_cast<char *> (s);
char *cp;
for (char *f = cp = fmt; ; ++cp) {
if (!*cp) {
if (f != cp) {
ret = ::strptime(ret, f, ptm);
}
break;
}
if (*cp != '%') {
continue;
}
char *e = cp;
++e;
char* ret = const_cast<char*>(s);
char* cp;
for (char* f = cp = fmt;; ++cp) {
if (!*cp) {
if (f != cp) {
ret = ::strptime(ret, f, ptm);
}
break;
}
if (*cp != '%') {
continue;
}
char* e = cp;
++e;
#if (defined(__BIONIC__))
if (*e == 's') {
*cp = '\0';
if (*f) {
ret = ::strptime(ret, f, ptm);
if (!ret) {
break;
}
}
tv_sec = 0;
while (isdigit(*ret)) {
tv_sec = tv_sec * 10 + *ret - '0';
++ret;
}
now = tv_sec;
#if !defined(_WIN32)
ptm = localtime_r(&now, &tmBuf);
#else
ptm = localtime(&now);
#endif
} else
#endif
{
unsigned num = 0;
while (isdigit(*e)) {
num = num * 10 + *e - '0';
++e;
}
if (*e != 'q') {
continue;
}
*cp = '\0';
if (*f) {
ret = ::strptime(ret, f, ptm);
if (!ret) {
break;
}
}
unsigned long mul = NS_PER_SEC;
if (num == 0) {
num = INT_MAX;
}
tv_nsec = 0;
while (isdigit(*ret) && num && (mul > 1)) {
--num;
mul /= 10;
tv_nsec = tv_nsec + (*ret - '0') * mul;
++ret;
}
if (*e == 's') {
*cp = '\0';
if (*f) {
ret = ::strptime(ret, f, ptm);
if (!ret) {
break;
}
f = cp = e;
++f;
}
if (ret) {
tv_sec = mktime(ptm);
return ret;
}
// Upon error, place a known value into the class, the current time.
#ifdef __linux__
*this = log_time(CLOCK_REALTIME);
}
tv_sec = 0;
while (isdigit(*ret)) {
tv_sec = tv_sec * 10 + *ret - '0';
++ret;
}
now = tv_sec;
#if !defined(_WIN32)
ptm = localtime_r(&now, &tmBuf);
#else
time(&now);
tv_sec = now;
tv_nsec = 0;
ptm = localtime(&now);
#endif
} else
#endif
{
unsigned num = 0;
while (isdigit(*e)) {
num = num * 10 + *e - '0';
++e;
}
if (*e != 'q') {
continue;
}
*cp = '\0';
if (*f) {
ret = ::strptime(ret, f, ptm);
if (!ret) {
break;
}
}
unsigned long mul = NS_PER_SEC;
if (num == 0) {
num = INT_MAX;
}
tv_nsec = 0;
while (isdigit(*ret) && num && (mul > 1)) {
--num;
mul /= 10;
tv_nsec = tv_nsec + (*ret - '0') * mul;
++ret;
}
}
f = cp = e;
++f;
}
if (ret) {
tv_sec = mktime(ptm);
return ret;
}
// Upon error, place a known value into the class, the current time.
#ifdef __linux__
*this = log_time(CLOCK_REALTIME);
#else
time(&now);
tv_sec = now;
tv_nsec = 0;
#endif
return ret;
}
LIBLOG_ABI_PRIVATE log_time log_time::operator-= (const timespec &T) {
// No concept of negative time, clamp to EPOCH
if (*this <= T) {
return *this = EPOCH;
}
LIBLOG_ABI_PRIVATE log_time log_time::operator-=(const timespec& T) {
// No concept of negative time, clamp to EPOCH
if (*this <= T) {
return *this = EPOCH;
}
if (this->tv_nsec < (unsigned long int)T.tv_nsec) {
--this->tv_sec;
this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
} else {
this->tv_nsec -= T.tv_nsec;
}
this->tv_sec -= T.tv_sec;
if (this->tv_nsec < (unsigned long int)T.tv_nsec) {
--this->tv_sec;
this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
} else {
this->tv_nsec -= T.tv_nsec;
}
this->tv_sec -= T.tv_sec;
return *this;
return *this;
}
LIBLOG_ABI_PRIVATE log_time log_time::operator+= (const timespec &T) {
this->tv_nsec += (unsigned long int)T.tv_nsec;
if (this->tv_nsec >= NS_PER_SEC) {
this->tv_nsec -= NS_PER_SEC;
++this->tv_sec;
}
this->tv_sec += T.tv_sec;
LIBLOG_ABI_PRIVATE log_time log_time::operator+=(const timespec& T) {
this->tv_nsec += (unsigned long int)T.tv_nsec;
if (this->tv_nsec >= NS_PER_SEC) {
this->tv_nsec -= NS_PER_SEC;
++this->tv_sec;
}
this->tv_sec += T.tv_sec;
return *this;
return *this;
}
LIBLOG_ABI_PRIVATE log_time log_time::operator-= (const log_time &T) {
// No concept of negative time, clamp to EPOCH
if (*this <= T) {
return *this = EPOCH;
}
LIBLOG_ABI_PRIVATE log_time log_time::operator-=(const log_time& T) {
// No concept of negative time, clamp to EPOCH
if (*this <= T) {
return *this = EPOCH;
}
if (this->tv_nsec < T.tv_nsec) {
--this->tv_sec;
this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
} else {
this->tv_nsec -= T.tv_nsec;
}
this->tv_sec -= T.tv_sec;
if (this->tv_nsec < T.tv_nsec) {
--this->tv_sec;
this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
} else {
this->tv_nsec -= T.tv_nsec;
}
this->tv_sec -= T.tv_sec;
return *this;
return *this;
}
LIBLOG_ABI_PRIVATE log_time log_time::operator+= (const log_time &T) {
this->tv_nsec += T.tv_nsec;
if (this->tv_nsec >= NS_PER_SEC) {
this->tv_nsec -= NS_PER_SEC;
++this->tv_sec;
}
this->tv_sec += T.tv_sec;
LIBLOG_ABI_PRIVATE log_time log_time::operator+=(const log_time& T) {
this->tv_nsec += T.tv_nsec;
if (this->tv_nsec >= NS_PER_SEC) {
this->tv_nsec -= NS_PER_SEC;
++this->tv_sec;
}
this->tv_sec += T.tv_sec;
return *this;
return *this;
}

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@
__BEGIN_DECLS
LIBLOG_HIDDEN ssize_t __send_log_msg(char *buf, size_t buf_size);
LIBLOG_HIDDEN ssize_t __send_log_msg(char* buf, size_t buf_size);
__END_DECLS

View File

@ -24,9 +24,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <unistd.h>
@ -40,260 +40,251 @@
#include "logger.h"
/* branchless on many architectures. */
#define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
#define min(x, y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))
static int logdAvailable(log_id_t LogId);
static int logdOpen();
static void logdClose();
static int logdWrite(log_id_t logId, struct timespec *ts,
struct iovec *vec, size_t nr);
static int logdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec,
size_t nr);
LIBLOG_HIDDEN struct android_log_transport_write logdLoggerWrite = {
.node = { &logdLoggerWrite.node, &logdLoggerWrite.node },
.context.sock = -EBADF,
.name = "logd",
.available = logdAvailable,
.open = logdOpen,
.close = logdClose,
.write = logdWrite,
.node = { &logdLoggerWrite.node, &logdLoggerWrite.node },
.context.sock = -EBADF,
.name = "logd",
.available = logdAvailable,
.open = logdOpen,
.close = logdClose,
.write = logdWrite,
};
/* log_init_lock assumed */
static int logdOpen()
{
int i, ret = 0;
static int logdOpen() {
int i, ret = 0;
i = atomic_load(&logdLoggerWrite.context.sock);
if (i < 0) {
int sock = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM |
SOCK_CLOEXEC |
SOCK_NONBLOCK, 0));
if (sock < 0) {
ret = -errno;
} else {
struct sockaddr_un un;
memset(&un, 0, sizeof(struct sockaddr_un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, "/dev/socket/logdw");
i = atomic_load(&logdLoggerWrite.context.sock);
if (i < 0) {
int sock = TEMP_FAILURE_RETRY(
socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
if (sock < 0) {
ret = -errno;
} else {
struct sockaddr_un un;
memset(&un, 0, sizeof(struct sockaddr_un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, "/dev/socket/logdw");
if (TEMP_FAILURE_RETRY(connect(sock, (struct sockaddr *)&un,
sizeof(struct sockaddr_un))) < 0) {
ret = -errno;
switch (ret) {
case -ENOTCONN:
case -ECONNREFUSED:
case -ENOENT:
i = atomic_exchange(&logdLoggerWrite.context.sock, ret);
/* FALLTHRU */
default:
break;
}
close(sock);
} else {
ret = atomic_exchange(&logdLoggerWrite.context.sock, sock);
if ((ret >= 0) && (ret != sock)) {
close(ret);
}
ret = 0;
}
}
}
return ret;
}
static void __logdClose(int negative_errno)
{
int sock = atomic_exchange(&logdLoggerWrite.context.sock, negative_errno);
if (sock >= 0) {
close(sock);
}
}
static void logdClose()
{
__logdClose(-EBADF);
}
static int logdAvailable(log_id_t logId)
{
if (logId >= LOG_ID_MAX || logId == LOG_ID_KERNEL) {
return -EINVAL;
}
if (atomic_load(&logdLoggerWrite.context.sock) < 0) {
if (access("/dev/socket/logdw", W_OK) == 0) {
return 0;
}
return -EBADF;
}
return 1;
}
static int logdWrite(log_id_t logId, struct timespec *ts,
struct iovec *vec, size_t nr)
{
ssize_t ret;
int sock;
static const unsigned headerLength = 1;
struct iovec newVec[nr + headerLength];
android_log_header_t header;
size_t i, payloadSize;
static atomic_int_fast32_t dropped;
static atomic_int_fast32_t droppedSecurity;
sock = atomic_load(&logdLoggerWrite.context.sock);
if (sock < 0) switch (sock) {
case -ENOTCONN:
case -ECONNREFUSED:
case -ENOENT:
break;
default:
return -EBADF;
}
/* logd, after initialization and priv drop */
if (__android_log_uid() == AID_LOGD) {
/*
* ignore log messages we send to ourself (logd).
* Such log messages are often generated by libraries we depend on
* which use standard Android logging.
*/
return 0;
}
/*
* struct {
* // what we provide to socket
* android_log_header_t header;
* // caller provides
* union {
* struct {
* char prio;
* char payload[];
* } string;
* struct {
* uint32_t tag
* char payload[];
* } binary;
* };
* };
*/
header.tid = gettid();
header.realtime.tv_sec = ts->tv_sec;
header.realtime.tv_nsec = ts->tv_nsec;
newVec[0].iov_base = (unsigned char *)&header;
newVec[0].iov_len = sizeof(header);
if (sock >= 0) {
int32_t snapshot = atomic_exchange_explicit(&droppedSecurity, 0,
memory_order_relaxed);
if (snapshot) {
android_log_event_int_t buffer;
header.id = LOG_ID_SECURITY;
buffer.header.tag = htole32(LIBLOG_LOG_TAG);
buffer.payload.type = EVENT_TYPE_INT;
buffer.payload.data = htole32(snapshot);
newVec[headerLength].iov_base = &buffer;
newVec[headerLength].iov_len = sizeof(buffer);
ret = TEMP_FAILURE_RETRY(writev(sock, newVec, 2));
if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
atomic_fetch_add_explicit(&droppedSecurity, snapshot,
memory_order_relaxed);
}
}
snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
if (snapshot && __android_log_is_loggable_len(ANDROID_LOG_INFO,
"liblog",
strlen("liblog"),
ANDROID_LOG_VERBOSE)) {
android_log_event_int_t buffer;
header.id = LOG_ID_EVENTS;
buffer.header.tag = htole32(LIBLOG_LOG_TAG);
buffer.payload.type = EVENT_TYPE_INT;
buffer.payload.data = htole32(snapshot);
newVec[headerLength].iov_base = &buffer;
newVec[headerLength].iov_len = sizeof(buffer);
ret = TEMP_FAILURE_RETRY(writev(sock, newVec, 2));
if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
atomic_fetch_add_explicit(&dropped, snapshot,
memory_order_relaxed);
}
}
}
header.id = logId;
for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
newVec[i].iov_base = vec[i - headerLength].iov_base;
payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
if (newVec[i].iov_len) {
++i;
}
if (TEMP_FAILURE_RETRY(connect(sock, (struct sockaddr*)&un,
sizeof(struct sockaddr_un))) < 0) {
ret = -errno;
switch (ret) {
case -ENOTCONN:
case -ECONNREFUSED:
case -ENOENT:
i = atomic_exchange(&logdLoggerWrite.context.sock, ret);
/* FALLTHRU */
default:
break;
}
close(sock);
} else {
ret = atomic_exchange(&logdLoggerWrite.context.sock, sock);
if ((ret >= 0) && (ret != sock)) {
close(ret);
}
ret = 0;
}
}
}
return ret;
}
static void __logdClose(int negative_errno) {
int sock = atomic_exchange(&logdLoggerWrite.context.sock, negative_errno);
if (sock >= 0) {
close(sock);
}
}
static void logdClose() {
__logdClose(-EBADF);
}
static int logdAvailable(log_id_t logId) {
if (logId >= LOG_ID_MAX || logId == LOG_ID_KERNEL) {
return -EINVAL;
}
if (atomic_load(&logdLoggerWrite.context.sock) < 0) {
if (access("/dev/socket/logdw", W_OK) == 0) {
return 0;
}
return -EBADF;
}
return 1;
}
static int logdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec,
size_t nr) {
ssize_t ret;
int sock;
static const unsigned headerLength = 1;
struct iovec newVec[nr + headerLength];
android_log_header_t header;
size_t i, payloadSize;
static atomic_int_fast32_t dropped;
static atomic_int_fast32_t droppedSecurity;
sock = atomic_load(&logdLoggerWrite.context.sock);
if (sock < 0) switch (sock) {
case -ENOTCONN:
case -ECONNREFUSED:
case -ENOENT:
break;
default:
return -EBADF;
}
/* logd, after initialization and priv drop */
if (__android_log_uid() == AID_LOGD) {
/*
* The write below could be lost, but will never block.
*
* ENOTCONN occurs if logd has died.
* ENOENT occurs if logd is not running and socket is missing.
* ECONNREFUSED occurs if we can not reconnect to logd.
* EAGAIN occurs if logd is overloaded.
* ignore log messages we send to ourself (logd).
* Such log messages are often generated by libraries we depend on
* which use standard Android logging.
*/
if (sock < 0) {
ret = sock;
} else {
ret = TEMP_FAILURE_RETRY(writev(sock, newVec, i));
if (ret < 0) {
ret = -errno;
}
return 0;
}
/*
* struct {
* // what we provide to socket
* android_log_header_t header;
* // caller provides
* union {
* struct {
* char prio;
* char payload[];
* } string;
* struct {
* uint32_t tag
* char payload[];
* } binary;
* };
* };
*/
header.tid = gettid();
header.realtime.tv_sec = ts->tv_sec;
header.realtime.tv_nsec = ts->tv_nsec;
newVec[0].iov_base = (unsigned char*)&header;
newVec[0].iov_len = sizeof(header);
if (sock >= 0) {
int32_t snapshot =
atomic_exchange_explicit(&droppedSecurity, 0, memory_order_relaxed);
if (snapshot) {
android_log_event_int_t buffer;
header.id = LOG_ID_SECURITY;
buffer.header.tag = htole32(LIBLOG_LOG_TAG);
buffer.payload.type = EVENT_TYPE_INT;
buffer.payload.data = htole32(snapshot);
newVec[headerLength].iov_base = &buffer;
newVec[headerLength].iov_len = sizeof(buffer);
ret = TEMP_FAILURE_RETRY(writev(sock, newVec, 2));
if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
atomic_fetch_add_explicit(&droppedSecurity, snapshot,
memory_order_relaxed);
}
}
switch(ret) {
snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);
if (snapshot &&
__android_log_is_loggable_len(ANDROID_LOG_INFO, "liblog",
strlen("liblog"), ANDROID_LOG_VERBOSE)) {
android_log_event_int_t buffer;
header.id = LOG_ID_EVENTS;
buffer.header.tag = htole32(LIBLOG_LOG_TAG);
buffer.payload.type = EVENT_TYPE_INT;
buffer.payload.data = htole32(snapshot);
newVec[headerLength].iov_base = &buffer;
newVec[headerLength].iov_len = sizeof(buffer);
ret = TEMP_FAILURE_RETRY(writev(sock, newVec, 2));
if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {
atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed);
}
}
}
header.id = logId;
for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
newVec[i].iov_base = vec[i - headerLength].iov_base;
payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
if (newVec[i].iov_len) {
++i;
}
break;
}
}
/*
* The write below could be lost, but will never block.
*
* ENOTCONN occurs if logd has died.
* ENOENT occurs if logd is not running and socket is missing.
* ECONNREFUSED occurs if we can not reconnect to logd.
* EAGAIN occurs if logd is overloaded.
*/
if (sock < 0) {
ret = sock;
} else {
ret = TEMP_FAILURE_RETRY(writev(sock, newVec, i));
if (ret < 0) {
ret = -errno;
}
}
switch (ret) {
case -ENOTCONN:
case -ECONNREFUSED:
case -ENOENT:
if (__android_log_trylock()) {
return ret; /* in a signal handler? try again when less stressed */
}
__logdClose(ret);
ret = logdOpen();
__android_log_unlock();
if (__android_log_trylock()) {
return ret; /* in a signal handler? try again when less stressed */
}
__logdClose(ret);
ret = logdOpen();
__android_log_unlock();
if (ret < 0) {
return ret;
}
if (ret < 0) {
return ret;
}
ret = TEMP_FAILURE_RETRY(writev(
atomic_load(&logdLoggerWrite.context.sock), newVec, i));
if (ret < 0) {
ret = -errno;
}
/* FALLTHRU */
ret = TEMP_FAILURE_RETRY(
writev(atomic_load(&logdLoggerWrite.context.sock), newVec, i));
if (ret < 0) {
ret = -errno;
}
/* FALLTHRU */
default:
break;
}
break;
}
if (ret > (ssize_t)sizeof(header)) {
ret -= sizeof(header);
} else if (ret == -EAGAIN) {
atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
if (logId == LOG_ID_SECURITY) {
atomic_fetch_add_explicit(&droppedSecurity, 1,
memory_order_relaxed);
}
if (ret > (ssize_t)sizeof(header)) {
ret -= sizeof(header);
} else if (ret == -EAGAIN) {
atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);
if (logId == LOG_ID_SECURITY) {
atomic_fetch_add_explicit(&droppedSecurity, 1, memory_order_relaxed);
}
}
return ret;
return ret;
}

View File

@ -30,25 +30,25 @@ __BEGIN_DECLS
/* Union, sock or fd of zero is not allowed unless static initialized */
union android_log_context {
void *private;
void* private;
atomic_int sock;
atomic_int fd;
struct listnode *node;
struct listnode* node;
atomic_uintptr_t atomic_pointer;
};
struct android_log_transport_write {
struct listnode node;
const char *name; /* human name to describe the transport */
unsigned logMask; /* mask cache of available() success */
const char* name; /* human name to describe the transport */
unsigned logMask; /* mask cache of available() success */
union android_log_context context; /* Initialized by static allocation */
int (*available)(log_id_t logId); /* Does not cause resources to be taken */
int (*open)(); /* can be called multiple times, reusing current resources */
void (*close)(); /* free up resources */
/* write log to transport, returns number of bytes propagated, or -errno */
int (*write)(log_id_t logId, struct timespec *ts,
struct iovec *vec, size_t nr);
int (*write)(log_id_t logId, struct timespec* ts, struct iovec* vec,
size_t nr);
};
struct android_log_logger_list;
@ -57,45 +57,44 @@ struct android_log_logger;
struct android_log_transport_read {
struct listnode node;
const char *name; /* human name to describe the transport */
const char* name; /* human name to describe the transport */
/* Does not cause resources to be taken */
int (*available)(log_id_t logId);
int (*version)(struct android_log_logger *logger,
struct android_log_transport_context *transp);
int (*version)(struct android_log_logger* logger,
struct android_log_transport_context* transp);
/* Release resources taken by the following interfaces */
void (*close)(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp);
void (*close)(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp);
/*
* Expect all to instantiate open automagically on any call,
* so we do not have an explicit open call.
*/
int (*read)(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp,
struct log_msg *log_msg);
int (*read)(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp,
struct log_msg* log_msg);
/* Must only be called if not ANDROID_LOG_NONBLOCK (blocking) */
int (*poll)(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp);
int (*poll)(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp);
int (*clear)(struct android_log_logger *logger,
struct android_log_transport_context *transp);
ssize_t (*setSize)(struct android_log_logger *logger,
struct android_log_transport_context *transp,
size_t size);
ssize_t (*getSize)(struct android_log_logger *logger,
struct android_log_transport_context *transp);
ssize_t (*getReadableSize)(struct android_log_logger *logger,
struct android_log_transport_context *transp);
int (*clear)(struct android_log_logger* logger,
struct android_log_transport_context* transp);
ssize_t (*setSize)(struct android_log_logger* logger,
struct android_log_transport_context* transp, size_t size);
ssize_t (*getSize)(struct android_log_logger* logger,
struct android_log_transport_context* transp);
ssize_t (*getReadableSize)(struct android_log_logger* logger,
struct android_log_transport_context* transp);
ssize_t (*getPrune)(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp,
char *buf, size_t len);
ssize_t (*setPrune)(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp,
char *buf, size_t len);
ssize_t (*getStats)(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp,
char *buf, size_t len);
ssize_t (*getPrune)(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp, char* buf,
size_t len);
ssize_t (*setPrune)(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp, char* buf,
size_t len);
ssize_t (*getStats)(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp, char* buf,
size_t len);
};
struct android_log_logger_list {
@ -110,7 +109,7 @@ struct android_log_logger_list {
struct android_log_logger {
struct listnode node;
struct android_log_logger_list *parent;
struct android_log_logger_list* parent;
log_id_t logId;
};
@ -118,34 +117,32 @@ struct android_log_logger {
struct android_log_transport_context {
struct listnode node;
union android_log_context context; /* zero init per-transport context */
struct android_log_logger_list *parent;
struct android_log_logger_list* parent;
struct android_log_transport_read *transport;
struct android_log_transport_read* transport;
unsigned logMask; /* mask of requested log buffers */
int ret; /* return value associated with following data */
struct log_msg logMsg; /* peek at upcoming data, valid if logMsg.len != 0 */
};
/* assumes caller has structures read-locked, single threaded, or fenced */
#define transport_context_for_each(transp, logger_list) \
for ((transp) = node_to_item((logger_list)->transport.next, \
struct android_log_transport_context, \
node); \
((transp) != node_to_item(&(logger_list)->transport, \
struct android_log_transport_context, \
node)) && \
((transp)->parent == (logger_list)); \
(transp) = node_to_item((transp)->node.next, \
struct android_log_transport_context, node))
#define transport_context_for_each(transp, logger_list) \
for ((transp) = node_to_item((logger_list)->transport.next, \
struct android_log_transport_context, node); \
((transp) != node_to_item(&(logger_list)->transport, \
struct android_log_transport_context, node)) && \
((transp)->parent == (logger_list)); \
(transp) = node_to_item((transp)->node.next, \
struct android_log_transport_context, node))
#define logger_for_each(logp, logger_list) \
for ((logp) = node_to_item((logger_list)->logger.next, \
for ((logp) = node_to_item((logger_list)->logger.next, \
struct android_log_logger, node); \
((logp) != node_to_item(&(logger_list)->logger, \
((logp) != node_to_item(&(logger_list)->logger, \
struct android_log_logger, node)) && \
((logp)->parent == (logger_list)); \
(logp) = node_to_item((logp)->node.next, \
struct android_log_logger, node))
((logp)->parent == (logger_list)); \
(logp) = \
node_to_item((logp)->node.next, struct android_log_logger, node))
/*
* Global list of log readers.
@ -168,28 +165,28 @@ LIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock;
#endif
/* Must be called with logger_list_rdlock() or logger_list_wrlock() held */
#define logger_list_for_each(logger_list) \
for ((logger_list) = node_to_item(&__android_log_readers, \
struct android_log_logger_list, \
node); \
(logger_list) != node_to_item(&__android_log_readers, \
struct android_log_logger_list, \
node) && \
(logger_list) != node_to_item((logger_list)->node.next, \
struct android_log_logger_list, \
node); \
(logger_list) = node_to_item((logger_list)->node.next, \
struct android_log_logger_list, \
node))
#define logger_list_for_each(logger_list) \
for ((logger_list) = node_to_item(&__android_log_readers, \
struct android_log_logger_list, node); \
(logger_list) != node_to_item(&__android_log_readers, \
struct android_log_logger_list, node) && \
(logger_list) != node_to_item((logger_list)->node.next, \
struct android_log_logger_list, node); \
(logger_list) = node_to_item((logger_list)->node.next, \
struct android_log_logger_list, node))
/* OS specific dribs and drabs */
#if defined(_WIN32)
#include <private/android_filesystem_config.h>
typedef uint32_t uid_t;
static inline uid_t __android_log_uid() { return AID_SYSTEM; }
static inline uid_t __android_log_uid() {
return AID_SYSTEM;
}
#else
static inline uid_t __android_log_uid() { return getuid(); }
static inline uid_t __android_log_uid() {
return getuid();
}
#endif
LIBLOG_HIDDEN void __android_log_lock();

View File

@ -28,29 +28,26 @@
static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
LIBLOG_HIDDEN void __android_log_lock()
{
LIBLOG_HIDDEN void __android_log_lock() {
#if !defined(_WIN32)
/*
* If we trigger a signal handler in the middle of locked activity and the
* signal handler logs a message, we could get into a deadlock state.
*/
pthread_mutex_lock(&log_init_lock);
/*
* If we trigger a signal handler in the middle of locked activity and the
* signal handler logs a message, we could get into a deadlock state.
*/
pthread_mutex_lock(&log_init_lock);
#endif
}
LIBLOG_HIDDEN int __android_log_trylock()
{
LIBLOG_HIDDEN int __android_log_trylock() {
#if !defined(_WIN32)
return pthread_mutex_trylock(&log_init_lock);
return pthread_mutex_trylock(&log_init_lock);
#else
return 0;
return 0;
#endif
}
LIBLOG_HIDDEN void __android_log_unlock()
{
LIBLOG_HIDDEN void __android_log_unlock() {
#if !defined(_WIN32)
pthread_mutex_unlock(&log_init_lock);
pthread_mutex_unlock(&log_init_lock);
#endif
}

View File

@ -21,44 +21,44 @@
#include "log_portability.h"
/* In the future, we would like to make this list extensible */
static const char *LOG_NAME[LOG_ID_MAX] = {
[LOG_ID_MAIN] = "main",
[LOG_ID_RADIO] = "radio",
[LOG_ID_EVENTS] = "events",
[LOG_ID_SYSTEM] = "system",
[LOG_ID_CRASH] = "crash",
[LOG_ID_SECURITY] = "security",
[LOG_ID_KERNEL] = "kernel",
static const char* LOG_NAME[LOG_ID_MAX] = {
/* clang-format off */
[LOG_ID_MAIN] = "main",
[LOG_ID_RADIO] = "radio",
[LOG_ID_EVENTS] = "events",
[LOG_ID_SYSTEM] = "system",
[LOG_ID_CRASH] = "crash",
[LOG_ID_SECURITY] = "security",
[LOG_ID_KERNEL] = "kernel",
/* clang-format on */
};
LIBLOG_ABI_PUBLIC const char *android_log_id_to_name(log_id_t log_id)
{
if (log_id >= LOG_ID_MAX) {
log_id = LOG_ID_MAIN;
}
return LOG_NAME[log_id];
LIBLOG_ABI_PUBLIC const char* android_log_id_to_name(log_id_t log_id) {
if (log_id >= LOG_ID_MAX) {
log_id = LOG_ID_MAIN;
}
return LOG_NAME[log_id];
}
LIBLOG_ABI_PUBLIC log_id_t android_name_to_log_id(const char *logName)
{
const char *b;
int ret;
LIBLOG_ABI_PUBLIC log_id_t android_name_to_log_id(const char* logName) {
const char* b;
int ret;
if (!logName) {
return -1; /* NB: log_id_t is unsigned */
}
b = strrchr(logName, '/');
if (!b) {
b = logName;
} else {
++b;
}
if (!logName) {
return -1; /* NB: log_id_t is unsigned */
}
b = strrchr(logName, '/');
if (!b) {
b = logName;
} else {
++b;
}
for(ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) {
const char *l = LOG_NAME[ret];
if (l && !strcmp(b, l)) {
return ret;
}
for (ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) {
const char* l = LOG_NAME[ret];
if (l && !strcmp(b, l)) {
return ret;
}
return -1; /* should never happen */
}
return -1; /* should never happen */
}

View File

@ -33,135 +33,128 @@
/* android_logger_alloc unimplemented, no use case */
/* android_logger_free not exported */
static void android_logger_free(struct logger *logger)
{
struct android_log_logger *logger_internal =
(struct android_log_logger *)logger;
static void android_logger_free(struct logger* logger) {
struct android_log_logger* logger_internal =
(struct android_log_logger*)logger;
if (!logger_internal) {
return;
}
if (!logger_internal) {
return;
}
list_remove(&logger_internal->node);
list_remove(&logger_internal->node);
free(logger_internal);
free(logger_internal);
}
/* android_logger_alloc unimplemented, no use case */
/* method for getting the associated sublog id */
LIBLOG_ABI_PUBLIC log_id_t android_logger_get_id(struct logger *logger)
{
return ((struct android_log_logger *)logger)->logId;
LIBLOG_ABI_PUBLIC log_id_t android_logger_get_id(struct logger* logger) {
return ((struct android_log_logger*)logger)->logId;
}
static int init_transport_context(struct android_log_logger_list *logger_list)
{
struct android_log_transport_read *transport;
struct listnode *node;
static int init_transport_context(struct android_log_logger_list* logger_list) {
struct android_log_transport_read* transport;
struct listnode* node;
if (!logger_list) {
return -EINVAL;
}
if (!logger_list) {
return -EINVAL;
}
if (list_empty(&logger_list->logger)) {
return -EINVAL;
}
if (list_empty(&logger_list->logger)) {
return -EINVAL;
}
if (!list_empty(&logger_list->transport)) {
return 0;
}
__android_log_lock();
/* mini __write_to_log_initialize() to populate transports */
if (list_empty(&__android_log_transport_read) &&
list_empty(&__android_log_persist_read)) {
__android_log_config_read();
}
__android_log_unlock();
node = (logger_list->mode & ANDROID_LOG_PSTORE) ?
&__android_log_persist_read : &__android_log_transport_read;
read_transport_for_each(transport, node) {
struct android_log_transport_context *transp;
struct android_log_logger *logger;
unsigned logMask = 0;
logger_for_each(logger, logger_list) {
log_id_t logId = logger->logId;
if ((logId == LOG_ID_SECURITY) &&
(__android_log_uid() != AID_SYSTEM)) {
continue;
}
if (transport->read &&
(!transport->available ||
(transport->available(logId) >= 0))) {
logMask |= 1 << logId;
}
}
if (!logMask) {
continue;
}
transp = calloc(1, sizeof(*transp));
if (!transp) {
return -ENOMEM;
}
transp->parent = logger_list;
transp->transport = transport;
transp->logMask = logMask;
transp->ret = 1;
list_add_tail(&logger_list->transport, &transp->node);
}
if (list_empty(&logger_list->transport)) {
return -ENODEV;
}
if (!list_empty(&logger_list->transport)) {
return 0;
}
__android_log_lock();
/* mini __write_to_log_initialize() to populate transports */
if (list_empty(&__android_log_transport_read) &&
list_empty(&__android_log_persist_read)) {
__android_log_config_read();
}
__android_log_unlock();
node = (logger_list->mode & ANDROID_LOG_PSTORE)
? &__android_log_persist_read
: &__android_log_transport_read;
read_transport_for_each(transport, node) {
struct android_log_transport_context* transp;
struct android_log_logger* logger;
unsigned logMask = 0;
logger_for_each(logger, logger_list) {
log_id_t logId = logger->logId;
if ((logId == LOG_ID_SECURITY) && (__android_log_uid() != AID_SYSTEM)) {
continue;
}
if (transport->read &&
(!transport->available || (transport->available(logId) >= 0))) {
logMask |= 1 << logId;
}
}
if (!logMask) {
continue;
}
transp = calloc(1, sizeof(*transp));
if (!transp) {
return -ENOMEM;
}
transp->parent = logger_list;
transp->transport = transport;
transp->logMask = logMask;
transp->ret = 1;
list_add_tail(&logger_list->transport, &transp->node);
}
if (list_empty(&logger_list->transport)) {
return -ENODEV;
}
return 0;
}
#define LOGGER_FUNCTION(logger, def, func, args...) \
ssize_t ret = -EINVAL; \
struct android_log_transport_context *transp; \
struct android_log_logger *logger_internal = \
(struct android_log_logger *)(logger); \
\
if (!logger_internal) { \
return ret; \
} \
ret = init_transport_context(logger_internal->parent); \
if (ret < 0) { \
return ret; \
} \
\
ret = (def); \
transport_context_for_each(transp, logger_internal->parent) { \
if ((transp->logMask & (1 << logger_internal->logId)) && \
transp->transport && transp->transport->func) { \
ssize_t retval = (transp->transport->func)(logger_internal, \
transp, ## args); \
if ((ret >= 0) || (ret == (def))) { \
ret = retval; \
} \
} \
} \
return ret
#define LOGGER_FUNCTION(logger, def, func, args...) \
ssize_t ret = -EINVAL; \
struct android_log_transport_context* transp; \
struct android_log_logger* logger_internal = \
(struct android_log_logger*)(logger); \
\
if (!logger_internal) { \
return ret; \
} \
ret = init_transport_context(logger_internal->parent); \
if (ret < 0) { \
return ret; \
} \
\
ret = (def); \
transport_context_for_each(transp, logger_internal->parent) { \
if ((transp->logMask & (1 << logger_internal->logId)) && \
transp->transport && transp->transport->func) { \
ssize_t retval = \
(transp->transport->func)(logger_internal, transp, ##args); \
if ((ret >= 0) || (ret == (def))) { \
ret = retval; \
} \
} \
} \
return ret
LIBLOG_ABI_PUBLIC int android_logger_clear(struct logger *logger)
{
LOGGER_FUNCTION(logger, -ENODEV, clear);
LIBLOG_ABI_PUBLIC int android_logger_clear(struct logger* logger) {
LOGGER_FUNCTION(logger, -ENODEV, clear);
}
/* returns the total size of the log's ring buffer */
LIBLOG_ABI_PUBLIC long android_logger_get_log_size(struct logger *logger)
{
LOGGER_FUNCTION(logger, -ENODEV, getSize);
LIBLOG_ABI_PUBLIC long android_logger_get_log_size(struct logger* logger) {
LOGGER_FUNCTION(logger, -ENODEV, getSize);
}
LIBLOG_ABI_PUBLIC int android_logger_set_log_size(struct logger *logger,
unsigned long size)
{
LOGGER_FUNCTION(logger, -ENODEV, setSize, size);
LIBLOG_ABI_PUBLIC int android_logger_set_log_size(struct logger* logger,
unsigned long size) {
LOGGER_FUNCTION(logger, -ENODEV, setSize, size);
}
/*
@ -169,376 +162,338 @@ LIBLOG_ABI_PUBLIC int android_logger_set_log_size(struct logger *logger,
* log consumed)
*/
LIBLOG_ABI_PUBLIC long android_logger_get_log_readable_size(
struct logger *logger)
{
LOGGER_FUNCTION(logger, -ENODEV, getReadableSize);
struct logger* logger) {
LOGGER_FUNCTION(logger, -ENODEV, getReadableSize);
}
/*
* returns the logger version
*/
LIBLOG_ABI_PUBLIC int android_logger_get_log_version(struct logger *logger)
{
LOGGER_FUNCTION(logger, 4, version);
LIBLOG_ABI_PUBLIC int android_logger_get_log_version(struct logger* logger) {
LOGGER_FUNCTION(logger, 4, version);
}
#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...) \
struct android_log_transport_context *transp; \
struct android_log_logger_list *logger_list_internal = \
(struct android_log_logger_list *)(logger_list); \
\
ssize_t ret = init_transport_context(logger_list_internal); \
if (ret < 0) { \
return ret; \
} \
\
ret = (def); \
transport_context_for_each(transp, logger_list_internal) { \
if (transp->transport && (transp->transport->func)) { \
ssize_t retval = (transp->transport->func)(logger_list_internal, \
transp, ## args); \
if ((ret >= 0) || (ret == (def))) { \
ret = retval; \
} \
} \
} \
return ret
#define LOGGER_LIST_FUNCTION(logger_list, def, func, args...) \
struct android_log_transport_context* transp; \
struct android_log_logger_list* logger_list_internal = \
(struct android_log_logger_list*)(logger_list); \
\
ssize_t ret = init_transport_context(logger_list_internal); \
if (ret < 0) { \
return ret; \
} \
\
ret = (def); \
transport_context_for_each(transp, logger_list_internal) { \
if (transp->transport && (transp->transport->func)) { \
ssize_t retval = \
(transp->transport->func)(logger_list_internal, transp, ##args); \
if ((ret >= 0) || (ret == (def))) { \
ret = retval; \
} \
} \
} \
return ret
/*
* returns statistics
*/
LIBLOG_ABI_PUBLIC ssize_t android_logger_get_statistics(
struct logger_list *logger_list,
char *buf, size_t len)
{
LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getStats, buf, len);
struct logger_list* logger_list, char* buf, size_t len) {
LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getStats, buf, len);
}
LIBLOG_ABI_PUBLIC ssize_t android_logger_get_prune_list(
struct logger_list *logger_list,
char *buf, size_t len)
{
LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getPrune, buf, len);
struct logger_list* logger_list, char* buf, size_t len) {
LOGGER_LIST_FUNCTION(logger_list, -ENODEV, getPrune, buf, len);
}
LIBLOG_ABI_PUBLIC int android_logger_set_prune_list(
struct logger_list *logger_list,
char *buf, size_t len)
{
LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);
struct logger_list* logger_list, char* buf, size_t len) {
LOGGER_LIST_FUNCTION(logger_list, -ENODEV, setPrune, buf, len);
}
LIBLOG_HIDDEN struct listnode __android_log_readers =
{ &__android_log_readers, &__android_log_readers };
LIBLOG_HIDDEN struct listnode __android_log_readers = { &__android_log_readers,
&__android_log_readers };
#if !defined(_WIN32)
LIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock =
PTHREAD_RWLOCK_INITIALIZER;
#endif
LIBLOG_ABI_PUBLIC struct logger_list *android_logger_list_alloc(
int mode,
unsigned int tail,
pid_t pid)
{
struct android_log_logger_list *logger_list;
LIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_alloc(
int mode, unsigned int tail, pid_t pid) {
struct android_log_logger_list* logger_list;
logger_list = calloc(1, sizeof(*logger_list));
if (!logger_list) {
return NULL;
}
logger_list = calloc(1, sizeof(*logger_list));
if (!logger_list) {
return NULL;
}
list_init(&logger_list->logger);
list_init(&logger_list->transport);
logger_list->mode = mode;
logger_list->tail = tail;
logger_list->pid = pid;
list_init(&logger_list->logger);
list_init(&logger_list->transport);
logger_list->mode = mode;
logger_list->tail = tail;
logger_list->pid = pid;
logger_list_wrlock();
list_add_tail(&__android_log_readers, &logger_list->node);
logger_list_unlock();
logger_list_wrlock();
list_add_tail(&__android_log_readers, &logger_list->node);
logger_list_unlock();
return (struct logger_list *)logger_list;
return (struct logger_list*)logger_list;
}
LIBLOG_ABI_PUBLIC struct logger_list *android_logger_list_alloc_time(
int mode,
log_time start,
pid_t pid)
{
struct android_log_logger_list *logger_list;
LIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_alloc_time(
int mode, log_time start, pid_t pid) {
struct android_log_logger_list* logger_list;
logger_list = calloc(1, sizeof(*logger_list));
if (!logger_list) {
return NULL;
}
logger_list = calloc(1, sizeof(*logger_list));
if (!logger_list) {
return NULL;
}
list_init(&logger_list->logger);
list_init(&logger_list->transport);
logger_list->mode = mode;
logger_list->start = start;
logger_list->pid = pid;
list_init(&logger_list->logger);
list_init(&logger_list->transport);
logger_list->mode = mode;
logger_list->start = start;
logger_list->pid = pid;
logger_list_wrlock();
list_add_tail(&__android_log_readers, &logger_list->node);
logger_list_unlock();
logger_list_wrlock();
list_add_tail(&__android_log_readers, &logger_list->node);
logger_list_unlock();
return (struct logger_list *)logger_list;
return (struct logger_list*)logger_list;
}
/* android_logger_list_register unimplemented, no use case */
/* android_logger_list_unregister unimplemented, no use case */
/* Open the named log and add it to the logger list */
LIBLOG_ABI_PUBLIC struct logger *android_logger_open(
struct logger_list *logger_list,
log_id_t logId)
{
struct android_log_logger_list *logger_list_internal =
(struct android_log_logger_list *)logger_list;
struct android_log_logger *logger;
LIBLOG_ABI_PUBLIC struct logger* android_logger_open(
struct logger_list* logger_list, log_id_t logId) {
struct android_log_logger_list* logger_list_internal =
(struct android_log_logger_list*)logger_list;
struct android_log_logger* logger;
if (!logger_list_internal || (logId >= LOG_ID_MAX)) {
goto err;
if (!logger_list_internal || (logId >= LOG_ID_MAX)) {
goto err;
}
logger_for_each(logger, logger_list_internal) {
if (logger->logId == logId) {
goto ok;
}
}
logger_for_each(logger, logger_list_internal) {
if (logger->logId == logId) {
goto ok;
}
}
logger = calloc(1, sizeof(*logger));
if (!logger) {
goto err;
}
logger = calloc(1, sizeof(*logger));
if (!logger) {
goto err;
}
logger->logId = logId;
list_add_tail(&logger_list_internal->logger, &logger->node);
logger->parent = logger_list_internal;
logger->logId = logId;
list_add_tail(&logger_list_internal->logger, &logger->node);
logger->parent = logger_list_internal;
/* Reset known transports to re-evaluate, we just added one */
while (!list_empty(&logger_list_internal->transport)) {
struct listnode* node = list_head(&logger_list_internal->transport);
struct android_log_transport_context* transp =
node_to_item(node, struct android_log_transport_context, node);
/* Reset known transports to re-evaluate, we just added one */
while (!list_empty(&logger_list_internal->transport)) {
struct listnode *node = list_head(&logger_list_internal->transport);
struct android_log_transport_context *transp =
node_to_item(node, struct android_log_transport_context, node);
list_remove(&transp->node);
free(transp);
}
goto ok;
list_remove(&transp->node);
free(transp);
}
goto ok;
err:
logger = NULL;
logger = NULL;
ok:
return (struct logger *)logger;
return (struct logger*)logger;
}
/* Open the single named log and make it part of a new logger list */
LIBLOG_ABI_PUBLIC struct logger_list *android_logger_list_open(
log_id_t logId,
int mode,
unsigned int tail,
pid_t pid)
{
struct logger_list *logger_list =
android_logger_list_alloc(mode, tail, pid);
LIBLOG_ABI_PUBLIC struct logger_list* android_logger_list_open(
log_id_t logId, int mode, unsigned int tail, pid_t pid) {
struct logger_list* logger_list = android_logger_list_alloc(mode, tail, pid);
if (!logger_list) {
return NULL;
}
if (!logger_list) {
return NULL;
}
if (!android_logger_open(logger_list, logId)) {
android_logger_list_free(logger_list);
return NULL;
}
if (!android_logger_open(logger_list, logId)) {
android_logger_list_free(logger_list);
return NULL;
}
return logger_list;
return logger_list;
}
/* Validate log_msg packet, read function has already been null checked */
static int android_transport_read(struct android_log_logger_list *logger_list,
struct android_log_transport_context *transp,
struct log_msg *log_msg)
{
int ret = (*transp->transport->read)(logger_list, transp, log_msg);
static int android_transport_read(struct android_log_logger_list* logger_list,
struct android_log_transport_context* transp,
struct log_msg* log_msg) {
int ret = (*transp->transport->read)(logger_list, transp, log_msg);
if (ret > (int)sizeof(*log_msg)) {
ret = sizeof(*log_msg);
if (ret > (int)sizeof(*log_msg)) {
ret = sizeof(*log_msg);
}
transp->ret = ret;
/* propagate errors, or make sure len & hdr_size members visible */
if (ret < (int)(sizeof(log_msg->entry.len) + sizeof(log_msg->entry.hdr_size))) {
if (ret >= (int)sizeof(log_msg->entry.len)) {
log_msg->entry.len = 0;
}
transp->ret = ret;
/* propagate errors, or make sure len & hdr_size members visible */
if (ret < (int)(sizeof(log_msg->entry.len) +
sizeof(log_msg->entry.hdr_size))) {
if (ret >= (int)sizeof(log_msg->entry.len)) {
log_msg->entry.len = 0;
}
return ret;
}
/* hdr_size correction (logger_entry -> logger_entry_v2+ conversion) */
if (log_msg->entry_v2.hdr_size == 0) {
log_msg->entry_v2.hdr_size = sizeof(struct logger_entry);
}
if ((log_msg->entry_v2.hdr_size < sizeof(log_msg->entry_v1)) ||
(log_msg->entry_v2.hdr_size > sizeof(log_msg->entry))) {
return -EINVAL;
}
/* len validation */
if (ret <= log_msg->entry_v2.hdr_size) {
log_msg->entry.len = 0;
} else {
log_msg->entry.len = ret - log_msg->entry_v2.hdr_size;
}
return ret;
}
/* hdr_size correction (logger_entry -> logger_entry_v2+ conversion) */
if (log_msg->entry_v2.hdr_size == 0) {
log_msg->entry_v2.hdr_size = sizeof(struct logger_entry);
}
if ((log_msg->entry_v2.hdr_size < sizeof(log_msg->entry_v1)) ||
(log_msg->entry_v2.hdr_size > sizeof(log_msg->entry))) {
return -EINVAL;
}
/* len validation */
if (ret <= log_msg->entry_v2.hdr_size) {
log_msg->entry.len = 0;
} else {
log_msg->entry.len = ret - log_msg->entry_v2.hdr_size;
}
return ret;
}
/* Read from the selected logs */
LIBLOG_ABI_PUBLIC int android_logger_list_read(struct logger_list *logger_list,
struct log_msg *log_msg)
{
struct android_log_transport_context *transp;
struct android_log_logger_list *logger_list_internal =
(struct android_log_logger_list *)logger_list;
LIBLOG_ABI_PUBLIC int android_logger_list_read(struct logger_list* logger_list,
struct log_msg* log_msg) {
struct android_log_transport_context* transp;
struct android_log_logger_list* logger_list_internal =
(struct android_log_logger_list*)logger_list;
int ret = init_transport_context(logger_list_internal);
if (ret < 0) {
return ret;
}
int ret = init_transport_context(logger_list_internal);
if (ret < 0) {
return ret;
}
/* at least one transport */
transp = node_to_item(logger_list_internal->transport.next,
struct android_log_transport_context, node);
/* at least one transport */
transp = node_to_item(logger_list_internal->transport.next,
struct android_log_transport_context, node);
/* more than one transport? */
if (transp->node.next != &logger_list_internal->transport) {
/* Poll and merge sort the entries if from multiple transports */
struct android_log_transport_context *oldest = NULL;
int ret;
int polled = 0;
do {
if (polled) {
sched_yield();
/* more than one transport? */
if (transp->node.next != &logger_list_internal->transport) {
/* Poll and merge sort the entries if from multiple transports */
struct android_log_transport_context* oldest = NULL;
int ret;
int polled = 0;
do {
if (polled) {
sched_yield();
}
ret = -1000;
polled = 0;
do {
int retval = transp->ret;
if ((retval > 0) && !transp->logMsg.entry.len) {
if (!transp->transport->read) {
retval = transp->ret = 0;
} else if ((logger_list_internal->mode & ANDROID_LOG_NONBLOCK) ||
!transp->transport->poll) {
retval = android_transport_read(logger_list_internal, transp,
&transp->logMsg);
} else {
int pollval =
(*transp->transport->poll)(logger_list_internal, transp);
if (pollval <= 0) {
sched_yield();
pollval = (*transp->transport->poll)(logger_list_internal, transp);
}
ret = -1000;
polled = 0;
do {
int retval = transp->ret;
if ((retval > 0) && !transp->logMsg.entry.len) {
if (!transp->transport->read) {
retval = transp->ret = 0;
} else if ((logger_list_internal->mode &
ANDROID_LOG_NONBLOCK) ||
!transp->transport->poll) {
retval = android_transport_read(
logger_list_internal,
transp,
&transp->logMsg);
} else {
int pollval = (*transp->transport->poll)(
logger_list_internal, transp);
if (pollval <= 0) {
sched_yield();
pollval = (*transp->transport->poll)(
logger_list_internal, transp);
}
polled = 1;
if (pollval < 0) {
if ((pollval == -EINTR) || (pollval == -EAGAIN)) {
return -EAGAIN;
}
retval = transp->ret = pollval;
} else if (pollval > 0) {
retval = android_transport_read(
logger_list_internal,
transp,
&transp->logMsg);
}
}
}
if (ret < retval) {
ret = retval;
}
if ((transp->ret > 0) && transp->logMsg.entry.len &&
(!oldest ||
(oldest->logMsg.entry.sec >
transp->logMsg.entry.sec) ||
((oldest->logMsg.entry.sec ==
transp->logMsg.entry.sec) &&
(oldest->logMsg.entry.nsec >
transp->logMsg.entry.nsec)))) {
oldest = transp;
}
transp = node_to_item(transp->node.next,
polled = 1;
if (pollval < 0) {
if ((pollval == -EINTR) || (pollval == -EAGAIN)) {
return -EAGAIN;
}
retval = transp->ret = pollval;
} else if (pollval > 0) {
retval = android_transport_read(logger_list_internal, transp,
&transp->logMsg);
}
}
}
if (ret < retval) {
ret = retval;
}
if ((transp->ret > 0) && transp->logMsg.entry.len &&
(!oldest || (oldest->logMsg.entry.sec > transp->logMsg.entry.sec) ||
((oldest->logMsg.entry.sec == transp->logMsg.entry.sec) &&
(oldest->logMsg.entry.nsec > transp->logMsg.entry.nsec)))) {
oldest = transp;
}
transp = node_to_item(transp->node.next,
struct android_log_transport_context, node);
} while (transp != node_to_item(&logger_list_internal->transport,
struct android_log_transport_context,
node);
} while (transp != node_to_item(
&logger_list_internal->transport,
struct android_log_transport_context,
node));
if (!oldest &&
(logger_list_internal->mode & ANDROID_LOG_NONBLOCK)) {
return (ret < 0) ? ret : -EAGAIN;
}
transp = node_to_item(logger_list_internal->transport.next,
struct android_log_transport_context, node);
} while (!oldest && (ret > 0));
if (!oldest) {
return ret;
}
// ret is a positive value less than sizeof(struct log_msg)
ret = oldest->ret;
if (ret < oldest->logMsg.entry.hdr_size) {
// zero truncated header fields.
memset(log_msg, 0,
(oldest->logMsg.entry.hdr_size > sizeof(oldest->logMsg) ?
sizeof(oldest->logMsg) :
oldest->logMsg.entry.hdr_size));
}
memcpy(log_msg, &oldest->logMsg, ret);
oldest->logMsg.entry.len = 0; /* Mark it as copied */
return ret;
node));
if (!oldest && (logger_list_internal->mode & ANDROID_LOG_NONBLOCK)) {
return (ret < 0) ? ret : -EAGAIN;
}
transp = node_to_item(logger_list_internal->transport.next,
struct android_log_transport_context, node);
} while (!oldest && (ret > 0));
if (!oldest) {
return ret;
}
// ret is a positive value less than sizeof(struct log_msg)
ret = oldest->ret;
if (ret < oldest->logMsg.entry.hdr_size) {
// zero truncated header fields.
memset(log_msg, 0,
(oldest->logMsg.entry.hdr_size > sizeof(oldest->logMsg)
? sizeof(oldest->logMsg)
: oldest->logMsg.entry.hdr_size));
}
memcpy(log_msg, &oldest->logMsg, ret);
oldest->logMsg.entry.len = 0; /* Mark it as copied */
return ret;
}
/* if only one, no need to copy into transport_context and merge-sort */
return android_transport_read(logger_list_internal, transp, log_msg);
/* if only one, no need to copy into transport_context and merge-sort */
return android_transport_read(logger_list_internal, transp, log_msg);
}
/* Close all the logs */
LIBLOG_ABI_PUBLIC void android_logger_list_free(struct logger_list *logger_list)
{
struct android_log_logger_list *logger_list_internal =
(struct android_log_logger_list *)logger_list;
LIBLOG_ABI_PUBLIC void android_logger_list_free(struct logger_list* logger_list) {
struct android_log_logger_list* logger_list_internal =
(struct android_log_logger_list*)logger_list;
if (logger_list_internal == NULL) {
return;
if (logger_list_internal == NULL) {
return;
}
logger_list_wrlock();
list_remove(&logger_list_internal->node);
logger_list_unlock();
while (!list_empty(&logger_list_internal->transport)) {
struct listnode* node = list_head(&logger_list_internal->transport);
struct android_log_transport_context* transp =
node_to_item(node, struct android_log_transport_context, node);
if (transp->transport && transp->transport->close) {
(*transp->transport->close)(logger_list_internal, transp);
}
list_remove(&transp->node);
free(transp);
}
logger_list_wrlock();
list_remove(&logger_list_internal->node);
logger_list_unlock();
while (!list_empty(&logger_list_internal->logger)) {
struct listnode* node = list_head(&logger_list_internal->logger);
struct android_log_logger* logger =
node_to_item(node, struct android_log_logger, node);
android_logger_free((struct logger*)logger);
}
while (!list_empty(&logger_list_internal->transport)) {
struct listnode *node = list_head(&logger_list_internal->transport);
struct android_log_transport_context *transp =
node_to_item(node, struct android_log_transport_context, node);
if (transp->transport && transp->transport->close) {
(*transp->transport->close)(logger_list_internal, transp);
}
list_remove(&transp->node);
free(transp);
}
while (!list_empty(&logger_list_internal->logger)) {
struct listnode *node = list_head(&logger_list_internal->logger);
struct android_log_logger *logger =
node_to_item(node, struct android_log_logger, node);
android_logger_free((struct logger *)logger);
}
free(logger_list_internal);
free(logger_list_internal);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -36,155 +36,149 @@
static int pmsgOpen();
static void pmsgClose();
static int pmsgAvailable(log_id_t logId);
static int pmsgWrite(log_id_t logId, struct timespec *ts,
struct iovec *vec, size_t nr);
static int pmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec,
size_t nr);
LIBLOG_HIDDEN struct android_log_transport_write pmsgLoggerWrite = {
.node = { &pmsgLoggerWrite.node, &pmsgLoggerWrite.node },
.context.fd = -1,
.name = "pmsg",
.available = pmsgAvailable,
.open = pmsgOpen,
.close = pmsgClose,
.write = pmsgWrite,
.node = { &pmsgLoggerWrite.node, &pmsgLoggerWrite.node },
.context.fd = -1,
.name = "pmsg",
.available = pmsgAvailable,
.open = pmsgOpen,
.close = pmsgClose,
.write = pmsgWrite,
};
static int pmsgOpen()
{
int fd = atomic_load(&pmsgLoggerWrite.context.fd);
if (fd < 0) {
int i;
static int pmsgOpen() {
int fd = atomic_load(&pmsgLoggerWrite.context.fd);
if (fd < 0) {
int i;
fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
i = atomic_exchange(&pmsgLoggerWrite.context.fd, fd);
if ((i >= 0) && (i != fd)) {
close(i);
}
fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC));
i = atomic_exchange(&pmsgLoggerWrite.context.fd, fd);
if ((i >= 0) && (i != fd)) {
close(i);
}
}
return fd;
return fd;
}
static void pmsgClose()
{
int fd = atomic_exchange(&pmsgLoggerWrite.context.fd, -1);
if (fd >= 0) {
close(fd);
}
static void pmsgClose() {
int fd = atomic_exchange(&pmsgLoggerWrite.context.fd, -1);
if (fd >= 0) {
close(fd);
}
}
static int pmsgAvailable(log_id_t logId)
{
if (logId > LOG_ID_SECURITY) {
return -EINVAL;
static int pmsgAvailable(log_id_t logId) {
if (logId > LOG_ID_SECURITY) {
return -EINVAL;
}
if ((logId != LOG_ID_SECURITY) && (logId != LOG_ID_EVENTS) &&
!__android_log_is_debuggable()) {
return -EINVAL;
}
if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
if (access("/dev/pmsg0", W_OK) == 0) {
return 0;
}
if ((logId != LOG_ID_SECURITY) &&
(logId != LOG_ID_EVENTS) &&
!__android_log_is_debuggable()) {
return -EINVAL;
}
if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
if (access("/dev/pmsg0", W_OK) == 0) {
return 0;
}
return -EBADF;
}
return 1;
return -EBADF;
}
return 1;
}
/*
* Extract a 4-byte value from a byte stream.
*/
static inline uint32_t get4LE(const uint8_t* src)
{
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
static inline uint32_t get4LE(const uint8_t* src) {
return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
}
static int pmsgWrite(log_id_t logId, struct timespec *ts,
struct iovec *vec, size_t nr)
{
static const unsigned headerLength = 2;
struct iovec newVec[nr + headerLength];
android_log_header_t header;
android_pmsg_log_header_t pmsgHeader;
size_t i, payloadSize;
ssize_t ret;
static int pmsgWrite(log_id_t logId, struct timespec* ts, struct iovec* vec,
size_t nr) {
static const unsigned headerLength = 2;
struct iovec newVec[nr + headerLength];
android_log_header_t header;
android_pmsg_log_header_t pmsgHeader;
size_t i, payloadSize;
ssize_t ret;
if ((logId == LOG_ID_EVENTS) && !__android_log_is_debuggable()) {
if (vec[0].iov_len < 4) {
return -EINVAL;
}
if (SNET_EVENT_LOG_TAG != get4LE(vec[0].iov_base)) {
return -EPERM;
}
if ((logId == LOG_ID_EVENTS) && !__android_log_is_debuggable()) {
if (vec[0].iov_len < 4) {
return -EINVAL;
}
if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
return -EBADF;
if (SNET_EVENT_LOG_TAG != get4LE(vec[0].iov_base)) {
return -EPERM;
}
}
/*
* struct {
* // what we provide to pstore
* android_pmsg_log_header_t pmsgHeader;
* // what we provide to file
* android_log_header_t header;
* // caller provides
* union {
* struct {
* char prio;
* char payload[];
* } string;
* struct {
* uint32_t tag
* char payload[];
* } binary;
* };
* };
*/
if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
return -EBADF;
}
pmsgHeader.magic = LOGGER_MAGIC;
pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header);
pmsgHeader.uid = __android_log_uid();
pmsgHeader.pid = getpid();
/*
* struct {
* // what we provide to pstore
* android_pmsg_log_header_t pmsgHeader;
* // what we provide to file
* android_log_header_t header;
* // caller provides
* union {
* struct {
* char prio;
* char payload[];
* } string;
* struct {
* uint32_t tag
* char payload[];
* } binary;
* };
* };
*/
header.id = logId;
header.tid = gettid();
header.realtime.tv_sec = ts->tv_sec;
header.realtime.tv_nsec = ts->tv_nsec;
pmsgHeader.magic = LOGGER_MAGIC;
pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header);
pmsgHeader.uid = __android_log_uid();
pmsgHeader.pid = getpid();
newVec[0].iov_base = (unsigned char *)&pmsgHeader;
newVec[0].iov_len = sizeof(pmsgHeader);
newVec[1].iov_base = (unsigned char *)&header;
newVec[1].iov_len = sizeof(header);
header.id = logId;
header.tid = gettid();
header.realtime.tv_sec = ts->tv_sec;
header.realtime.tv_nsec = ts->tv_nsec;
for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
newVec[i].iov_base = vec[i - headerLength].iov_base;
payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
newVec[0].iov_base = (unsigned char*)&pmsgHeader;
newVec[0].iov_len = sizeof(pmsgHeader);
newVec[1].iov_base = (unsigned char*)&header;
newVec[1].iov_len = sizeof(header);
if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
if (newVec[i].iov_len) {
++i;
}
payloadSize = LOGGER_ENTRY_MAX_PAYLOAD;
break;
}
for (payloadSize = 0, i = headerLength; i < nr + headerLength; i++) {
newVec[i].iov_base = vec[i - headerLength].iov_base;
payloadSize += newVec[i].iov_len = vec[i - headerLength].iov_len;
if (payloadSize > LOGGER_ENTRY_MAX_PAYLOAD) {
newVec[i].iov_len -= payloadSize - LOGGER_ENTRY_MAX_PAYLOAD;
if (newVec[i].iov_len) {
++i;
}
payloadSize = LOGGER_ENTRY_MAX_PAYLOAD;
break;
}
pmsgHeader.len += payloadSize;
}
pmsgHeader.len += payloadSize;
ret = TEMP_FAILURE_RETRY(writev(atomic_load(&pmsgLoggerWrite.context.fd),
newVec, i));
if (ret < 0) {
ret = errno ? -errno : -ENOTCONN;
}
ret = TEMP_FAILURE_RETRY(
writev(atomic_load(&pmsgLoggerWrite.context.fd), newVec, i));
if (ret < 0) {
ret = errno ? -errno : -ENOTCONN;
}
if (ret > (ssize_t)(sizeof(header) + sizeof(pmsgHeader))) {
ret -= sizeof(header) - sizeof(pmsgHeader);
}
if (ret > (ssize_t)(sizeof(header) + sizeof(pmsgHeader))) {
ret -= sizeof(header) - sizeof(pmsgHeader);
}
return ret;
return ret;
}
/*
@ -197,116 +191,116 @@ static int pmsgWrite(log_id_t logId, struct timespec *ts,
* Will hijack the header.realtime.tv_nsec field for a sequence number in usec.
*/
static inline const char *strnrchr(const char *buf, size_t len, char c) {
const char *cp = buf + len;
while ((--cp > buf) && (*cp != c));
if (cp <= buf) {
return buf + len;
}
return cp;
static inline const char* strnrchr(const char* buf, size_t len, char c) {
const char* cp = buf + len;
while ((--cp > buf) && (*cp != c))
;
if (cp <= buf) {
return buf + len;
}
return cp;
}
/* Write a buffer as filename references (tag = <basedir>:<basename>) */
LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write(
log_id_t logId,
char prio,
const char *filename,
const char *buf, size_t len) {
bool weOpened;
size_t length, packet_len;
const char *tag;
char *cp, *slash;
struct timespec ts;
struct iovec vec[3];
LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write(log_id_t logId,
char prio,
const char* filename,
const char* buf,
size_t len) {
bool weOpened;
size_t length, packet_len;
const char* tag;
char *cp, *slash;
struct timespec ts;
struct iovec vec[3];
/* Make sure the logId value is not a bad idea */
if ((logId == LOG_ID_KERNEL) || /* Verbotten */
(logId == LOG_ID_EVENTS) || /* Do not support binary content */
(logId == LOG_ID_SECURITY) || /* Bad idea to allow */
((unsigned)logId >= 32)) { /* fit within logMask on arch32 */
return -EINVAL;
}
/* Make sure the logId value is not a bad idea */
if ((logId == LOG_ID_KERNEL) || /* Verbotten */
(logId == LOG_ID_EVENTS) || /* Do not support binary content */
(logId == LOG_ID_SECURITY) || /* Bad idea to allow */
((unsigned)logId >= 32)) { /* fit within logMask on arch32 */
return -EINVAL;
}
clock_gettime(android_log_clockid(), &ts);
clock_gettime(android_log_clockid(), &ts);
cp = strdup(filename);
if (!cp) {
return -ENOMEM;
}
cp = strdup(filename);
if (!cp) {
return -ENOMEM;
}
tag = cp;
tag = cp;
slash = strrchr(cp, '/');
if (slash) {
*slash = ':';
slash = strrchr(cp, '/');
if (slash) {
*slash = ':';
slash = strrchr(cp, '/');
if (slash) {
tag = slash + 1;
}
tag = slash + 1;
}
}
length = strlen(tag) + 1;
packet_len = LOGGER_ENTRY_MAX_PAYLOAD - sizeof(char) - length;
vec[0].iov_base = &prio;
vec[0].iov_len = sizeof(char);
vec[1].iov_base = (unsigned char*)tag;
vec[1].iov_len = length;
weOpened = false;
for (ts.tv_nsec = 0, length = len; length;
ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) {
ssize_t ret;
size_t transfer;
if ((ts.tv_nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=
ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) {
len -= length;
break;
}
length = strlen(tag) + 1;
packet_len = LOGGER_ENTRY_MAX_PAYLOAD - sizeof(char) - length;
vec[0].iov_base = &prio;
vec[0].iov_len = sizeof(char);
vec[1].iov_base = (unsigned char *)tag;
vec[1].iov_len = length;
weOpened = false;
for (ts.tv_nsec = 0, length = len;
length;
ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) {
ssize_t ret;
size_t transfer;
if ((ts.tv_nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >=
ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE) {
len -= length;
break;
}
transfer = length;
if (transfer > packet_len) {
transfer = strnrchr(buf, packet_len - 1, '\n') - buf;
if ((transfer < length) && (buf[transfer] == '\n')) {
++transfer;
}
}
vec[2].iov_base = (unsigned char *)buf;
vec[2].iov_len = transfer;
if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
if (!weOpened) { /* Impossible for weOpened = true here */
__android_log_lock();
}
weOpened = atomic_load(&pmsgLoggerWrite.context.fd) < 0;
if (!weOpened) {
__android_log_unlock();
} else if (pmsgOpen() < 0) {
__android_log_unlock();
free(cp);
return -EBADF;
}
}
ret = pmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0]));
if (ret <= 0) {
if (weOpened) {
pmsgClose();
__android_log_unlock();
}
free(cp);
return ret ? ret : (len - length);
}
length -= transfer;
buf += transfer;
transfer = length;
if (transfer > packet_len) {
transfer = strnrchr(buf, packet_len - 1, '\n') - buf;
if ((transfer < length) && (buf[transfer] == '\n')) {
++transfer;
}
}
if (weOpened) {
vec[2].iov_base = (unsigned char*)buf;
vec[2].iov_len = transfer;
if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) {
if (!weOpened) { /* Impossible for weOpened = true here */
__android_log_lock();
}
weOpened = atomic_load(&pmsgLoggerWrite.context.fd) < 0;
if (!weOpened) {
__android_log_unlock();
} else if (pmsgOpen() < 0) {
__android_log_unlock();
free(cp);
return -EBADF;
}
}
ret = pmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0]));
if (ret <= 0) {
if (weOpened) {
pmsgClose();
__android_log_unlock();
}
free(cp);
return ret ? ret : (len - length);
}
free(cp);
return len;
length -= transfer;
buf += transfer;
}
if (weOpened) {
pmsgClose();
__android_log_unlock();
}
free(cp);
return len;
}

File diff suppressed because it is too large Load Diff

View File

@ -45,175 +45,168 @@
static int stderrOpen();
static void stderrClose();
static int stderrAvailable(log_id_t logId);
static int stderrWrite(log_id_t logId, struct timespec* ts,
struct iovec* vec, size_t nr);
static int stderrWrite(log_id_t logId, struct timespec* ts, struct iovec* vec,
size_t nr);
struct stderrContext {
AndroidLogFormat* logformat;
AndroidLogFormat* logformat;
#if defined(__ANDROID__)
EventTagMap* eventTagMap;
EventTagMap* eventTagMap;
#endif
};
LIBLOG_HIDDEN struct android_log_transport_write stderrLoggerWrite = {
.node = { &stderrLoggerWrite.node, &stderrLoggerWrite.node },
.context.private = NULL,
.name = "stderr",
.available = stderrAvailable,
.open = stderrOpen,
.close = stderrClose,
.write = stderrWrite,
.node = { &stderrLoggerWrite.node, &stderrLoggerWrite.node },
.context.private = NULL,
.name = "stderr",
.available = stderrAvailable,
.open = stderrOpen,
.close = stderrClose,
.write = stderrWrite,
};
static int stderrOpen()
{
struct stderrContext* ctx;
const char* envStr;
bool setFormat;
static int stderrOpen() {
struct stderrContext* ctx;
const char* envStr;
bool setFormat;
if (!stderr || (fileno(stderr) < 0)) {
return -EBADF;
}
if (stderrLoggerWrite.context.private) {
return fileno(stderr);
}
ctx = calloc(1, sizeof(struct stderrContext));
if (!ctx) {
return -ENOMEM;
}
ctx->logformat = android_log_format_new();
if (!ctx->logformat) {
free(ctx);
return -ENOMEM;
}
envStr = getenv("ANDROID_PRINTF_LOG");
setFormat = false;
if (envStr) {
char* formats = strdup(envStr);
char* sv = NULL;
char* arg = formats;
while (!!(arg = strtok_r(arg, ",:; \t\n\r\f", &sv))) {
AndroidLogPrintFormat format = android_log_formatFromString(arg);
arg = NULL;
if (format == FORMAT_OFF) {
continue;
}
if (android_log_setPrintFormat(ctx->logformat, format) <= 0) {
continue;
}
setFormat = true;
}
free(formats);
}
if (!setFormat) {
AndroidLogPrintFormat format = android_log_formatFromString(
"threadtime");
android_log_setPrintFormat(ctx->logformat, format);
}
envStr = getenv("ANDROID_LOG_TAGS");
if (envStr) {
android_log_addFilterString(ctx->logformat, envStr);
}
stderrLoggerWrite.context.private = ctx;
if (!stderr || (fileno(stderr) < 0)) {
return -EBADF;
}
if (stderrLoggerWrite.context.private) {
return fileno(stderr);
}
ctx = calloc(1, sizeof(struct stderrContext));
if (!ctx) {
return -ENOMEM;
}
ctx->logformat = android_log_format_new();
if (!ctx->logformat) {
free(ctx);
return -ENOMEM;
}
envStr = getenv("ANDROID_PRINTF_LOG");
setFormat = false;
if (envStr) {
char* formats = strdup(envStr);
char* sv = NULL;
char* arg = formats;
while (!!(arg = strtok_r(arg, ",:; \t\n\r\f", &sv))) {
AndroidLogPrintFormat format = android_log_formatFromString(arg);
arg = NULL;
if (format == FORMAT_OFF) {
continue;
}
if (android_log_setPrintFormat(ctx->logformat, format) <= 0) {
continue;
}
setFormat = true;
}
free(formats);
}
if (!setFormat) {
AndroidLogPrintFormat format = android_log_formatFromString("threadtime");
android_log_setPrintFormat(ctx->logformat, format);
}
envStr = getenv("ANDROID_LOG_TAGS");
if (envStr) {
android_log_addFilterString(ctx->logformat, envStr);
}
stderrLoggerWrite.context.private = ctx;
return fileno(stderr);
}
static void stderrClose()
{
struct stderrContext* ctx = stderrLoggerWrite.context.private;
static void stderrClose() {
struct stderrContext* ctx = stderrLoggerWrite.context.private;
if (ctx) {
stderrLoggerWrite.context.private = NULL;
if (ctx->logformat) {
android_log_format_free(ctx->logformat);
ctx->logformat = NULL;
}
if (ctx) {
stderrLoggerWrite.context.private = NULL;
if (ctx->logformat) {
android_log_format_free(ctx->logformat);
ctx->logformat = NULL;
}
#if defined(__ANDROID__)
if (ctx->eventTagMap) {
android_closeEventTagMap(ctx->eventTagMap);
ctx->eventTagMap = NULL;
}
if (ctx->eventTagMap) {
android_closeEventTagMap(ctx->eventTagMap);
ctx->eventTagMap = NULL;
}
#endif
}
}
}
static int stderrAvailable(log_id_t logId)
{
if ((logId >= LOG_ID_MAX) || (logId == LOG_ID_KERNEL)) {
return -EINVAL;
}
return 1;
static int stderrAvailable(log_id_t logId) {
if ((logId >= LOG_ID_MAX) || (logId == LOG_ID_KERNEL)) {
return -EINVAL;
}
return 1;
}
static int stderrWrite(log_id_t logId, struct timespec* ts,
struct iovec* vec, size_t nr)
{
struct log_msg log_msg;
AndroidLogEntry entry;
char binaryMsgBuf[1024];
int err;
size_t i;
struct stderrContext* ctx = stderrLoggerWrite.context.private;
static int stderrWrite(log_id_t logId, struct timespec* ts, struct iovec* vec,
size_t nr) {
struct log_msg log_msg;
AndroidLogEntry entry;
char binaryMsgBuf[1024];
int err;
size_t i;
struct stderrContext* ctx = stderrLoggerWrite.context.private;
if (!ctx) return -EBADF;
if (!vec || !nr) return -EINVAL;
if (!ctx) return -EBADF;
if (!vec || !nr) return -EINVAL;
log_msg.entry.len = 0;
log_msg.entry.hdr_size = sizeof(log_msg.entry);
log_msg.entry.pid = getpid();
log_msg.entry.len = 0;
log_msg.entry.hdr_size = sizeof(log_msg.entry);
log_msg.entry.pid = getpid();
#ifdef __BIONIC__
log_msg.entry.tid = gettid();
log_msg.entry.tid = gettid();
#else
log_msg.entry.tid = getpid();
log_msg.entry.tid = getpid();
#endif
log_msg.entry.sec = ts->tv_sec;
log_msg.entry.nsec = ts->tv_nsec;
log_msg.entry.lid = logId;
log_msg.entry.uid = __android_log_uid();
log_msg.entry.sec = ts->tv_sec;
log_msg.entry.nsec = ts->tv_nsec;
log_msg.entry.lid = logId;
log_msg.entry.uid = __android_log_uid();
for (i = 0; i < nr; ++i) {
size_t len = vec[i].iov_len;
if ((log_msg.entry.len + len) > LOGGER_ENTRY_MAX_PAYLOAD) {
len = LOGGER_ENTRY_MAX_PAYLOAD - log_msg.entry.len;
}
if (!len) continue;
memcpy(log_msg.entry.msg + log_msg.entry.len, vec[i].iov_base, len);
log_msg.entry.len += len;
for (i = 0; i < nr; ++i) {
size_t len = vec[i].iov_len;
if ((log_msg.entry.len + len) > LOGGER_ENTRY_MAX_PAYLOAD) {
len = LOGGER_ENTRY_MAX_PAYLOAD - log_msg.entry.len;
}
if (!len) continue;
memcpy(log_msg.entry.msg + log_msg.entry.len, vec[i].iov_base, len);
log_msg.entry.len += len;
}
if ((logId == LOG_ID_EVENTS) || (logId == LOG_ID_SECURITY)) {
if ((logId == LOG_ID_EVENTS) || (logId == LOG_ID_SECURITY)) {
#if defined(__ANDROID__)
if (!ctx->eventTagMap) {
ctx->eventTagMap = android_openEventTagMap(NULL);
}
if (!ctx->eventTagMap) {
ctx->eventTagMap = android_openEventTagMap(NULL);
}
#endif
err = android_log_processBinaryLogBuffer(&log_msg.entry_v1,
&entry,
err = android_log_processBinaryLogBuffer(&log_msg.entry_v1, &entry,
#if defined(__ANDROID__)
ctx->eventTagMap,
ctx->eventTagMap,
#else
NULL,
NULL,
#endif
binaryMsgBuf,
sizeof(binaryMsgBuf));
} else {
err = android_log_processLogBuffer(&log_msg.entry_v1, &entry);
}
binaryMsgBuf, sizeof(binaryMsgBuf));
} else {
err = android_log_processLogBuffer(&log_msg.entry_v1, &entry);
}
/* print known truncated data, in essence logcat --debug */
if ((err < 0) && !entry.message) return -EINVAL;
/* print known truncated data, in essence logcat --debug */
if ((err < 0) && !entry.message) return -EINVAL;
if (!android_log_shouldPrintLine(ctx->logformat, entry.tag, entry.priority)) {
return log_msg.entry.len;
}
err = android_log_printLogLine(ctx->logformat, fileno(stderr), &entry);
if (err < 0) return errno ? -errno : -EINVAL;
if (!android_log_shouldPrintLine(ctx->logformat, entry.tag, entry.priority)) {
return log_msg.entry.len;
}
err = android_log_printLogLine(ctx->logformat, fileno(stderr), &entry);
if (err < 0) return errno ? -errno : -EINVAL;
return log_msg.entry.len;
}

View File

@ -22,8 +22,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <map>
#include <string>
#include <vector>
static uint64_t gBytesProcessed;
@ -32,21 +32,21 @@ static uint64_t gBenchmarkTotalTimeNsSquared;
static uint64_t gBenchmarkNum;
static uint64_t gBenchmarkStartTimeNs;
typedef std::vector< ::testing::Benchmark* > BenchmarkList;
typedef std::vector< ::testing::Benchmark*> BenchmarkList;
static BenchmarkList* gBenchmarks;
static int Round(int n) {
int base = 1;
while (base*10 < n) {
while (base * 10 < n) {
base *= 10;
}
if (n < 2*base) {
return 2*base;
if (n < 2 * base) {
return 2 * base;
}
if (n < 5*base) {
return 5*base;
if (n < 5 * base) {
return 5 * base;
}
return 10*base;
return 10 * base;
}
static uint64_t NanoTime() {
@ -58,20 +58,19 @@ static uint64_t NanoTime() {
namespace testing {
int PrettyPrintInt(char* str, int len, unsigned int arg)
{
if (arg >= (1<<30) && arg % (1<<30) == 0) {
return snprintf(str, len, "%uGi", arg/(1<<30));
} else if (arg >= (1<<20) && arg % (1<<20) == 0) {
return snprintf(str, len, "%uMi", arg/(1<<20));
} else if (arg >= (1<<10) && arg % (1<<10) == 0) {
return snprintf(str, len, "%uKi", arg/(1<<10));
int PrettyPrintInt(char* str, int len, unsigned int arg) {
if (arg >= (1 << 30) && arg % (1 << 30) == 0) {
return snprintf(str, len, "%uGi", arg / (1 << 30));
} else if (arg >= (1 << 20) && arg % (1 << 20) == 0) {
return snprintf(str, len, "%uMi", arg / (1 << 20));
} else if (arg >= (1 << 10) && arg % (1 << 10) == 0) {
return snprintf(str, len, "%uKi", arg / (1 << 10));
} else if (arg >= 1000000000 && arg % 1000000000 == 0) {
return snprintf(str, len, "%uG", arg/1000000000);
return snprintf(str, len, "%uG", arg / 1000000000);
} else if (arg >= 1000000 && arg % 1000000 == 0) {
return snprintf(str, len, "%uM", arg/1000000);
return snprintf(str, len, "%uM", arg / 1000000);
} else if (arg >= 1000 && arg % 1000 == 0) {
return snprintf(str, len, "%uK", arg/1000);
return snprintf(str, len, "%uK", arg / 1000);
} else {
return snprintf(str, len, "%u", arg);
}
@ -86,7 +85,8 @@ bool ShouldRun(Benchmark* b, int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
regex_t re;
if (regcomp(&re, argv[i], 0) != 0) {
fprintf(stderr, "couldn't compile \"%s\" as a regular expression!\n", argv[i]);
fprintf(stderr, "couldn't compile \"%s\" as a regular expression!\n",
argv[i]);
exit(EXIT_FAILURE);
}
int match = regexec(&re, b->Name(), 0, NULL, 0);
@ -111,9 +111,8 @@ void RunRepeatedly(Benchmark* b, int iterations) {
uint64_t StartTimeNs = NanoTime();
b->RunFn(iterations);
// Catch us if we fail to log anything.
if ((gBenchmarkTotalTimeNs == 0)
&& (StartTimeNs != 0)
&& (gBenchmarkStartTimeNs == 0)) {
if ((gBenchmarkTotalTimeNs == 0) && (StartTimeNs != 0) &&
(gBenchmarkStartTimeNs == 0)) {
gBenchmarkTotalTimeNs = NanoTime() - StartTimeNs;
}
}
@ -126,12 +125,13 @@ void Run(Benchmark* b) {
s = NanoTime() - s;
while (s < 2e9 && gBenchmarkTotalTimeNs < 1e9 && iterations < 1e9) {
unsigned last = iterations;
if (gBenchmarkTotalTimeNs/iterations == 0) {
if (gBenchmarkTotalTimeNs / iterations == 0) {
iterations = 1e9;
} else {
iterations = 1e9 / (gBenchmarkTotalTimeNs/iterations);
iterations = 1e9 / (gBenchmarkTotalTimeNs / iterations);
}
iterations = std::max(last + 1, std::min(iterations + iterations/2, 100*last));
iterations =
std::max(last + 1, std::min(iterations + iterations / 2, 100 * last));
iterations = Round(iterations);
s = NanoTime();
RunRepeatedly(b, iterations);
@ -141,30 +141,30 @@ void Run(Benchmark* b) {
char throughput[100];
throughput[0] = '\0';
if (gBenchmarkTotalTimeNs > 0 && gBytesProcessed > 0) {
double mib_processed = static_cast<double>(gBytesProcessed)/1e6;
double seconds = static_cast<double>(gBenchmarkTotalTimeNs)/1e9;
snprintf(throughput, sizeof(throughput), " %8.2f MiB/s", mib_processed/seconds);
double mib_processed = static_cast<double>(gBytesProcessed) / 1e6;
double seconds = static_cast<double>(gBenchmarkTotalTimeNs) / 1e9;
snprintf(throughput, sizeof(throughput), " %8.2f MiB/s",
mib_processed / seconds);
}
char full_name[100];
snprintf(full_name, sizeof(full_name), "%s%s%s", b->Name(),
b->ArgName() ? "/" : "",
b->ArgName() ? b->ArgName() : "");
b->ArgName() ? "/" : "", b->ArgName() ? b->ArgName() : "");
uint64_t mean = gBenchmarkTotalTimeNs / iterations;
uint64_t sdev = 0;
if (gBenchmarkNum == iterations) {
mean = gBenchmarkTotalTimeNs / gBenchmarkNum;
uint64_t nXvariance = gBenchmarkTotalTimeNsSquared * gBenchmarkNum
- (gBenchmarkTotalTimeNs * gBenchmarkTotalTimeNs);
uint64_t nXvariance = gBenchmarkTotalTimeNsSquared * gBenchmarkNum -
(gBenchmarkTotalTimeNs * gBenchmarkTotalTimeNs);
sdev = (sqrt((double)nXvariance) / gBenchmarkNum / gBenchmarkNum) + 0.5;
}
if (mean > (10000 * sdev)) {
printf("%-25s %10" PRIu64 " %10" PRIu64 "%s\n", full_name,
static_cast<uint64_t>(iterations), mean, throughput);
static_cast<uint64_t>(iterations), mean, throughput);
} else {
printf("%-25s %10" PRIu64 " %10" PRIu64 "(\317\203%" PRIu64 ")%s\n", full_name,
static_cast<uint64_t>(iterations), mean, sdev, throughput);
printf("%-25s %10" PRIu64 " %10" PRIu64 "(\317\203%" PRIu64 ")%s\n",
full_name, static_cast<uint64_t>(iterations), mean, sdev, throughput);
}
fflush(stdout);
}

View File

@ -21,29 +21,29 @@
TEST(libc, __pstore_append) {
#ifdef __ANDROID__
FILE *fp;
ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "a")));
static const char message[] = "libc.__pstore_append\n";
ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp));
int fflushReturn = fflush(fp);
int fflushErrno = fflushReturn ? errno : 0;
ASSERT_EQ(0, fflushReturn);
ASSERT_EQ(0, fflushErrno);
int fcloseReturn = fclose(fp);
int fcloseErrno = fcloseReturn ? errno : 0;
ASSERT_EQ(0, fcloseReturn);
ASSERT_EQ(0, fcloseErrno);
if ((fcloseErrno == ENOMEM) || (fflushErrno == ENOMEM)) {
fprintf(stderr,
"Kernel does not have space allocated to pmsg pstore driver configured\n"
);
}
if (!fcloseReturn && !fcloseErrno && !fflushReturn && !fflushReturn) {
fprintf(stderr,
"Reboot, ensure string libc.__pstore_append is in /sys/fs/pstore/pmsg-ramoops-0\n"
);
}
FILE* fp;
ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "a")));
static const char message[] = "libc.__pstore_append\n";
ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp));
int fflushReturn = fflush(fp);
int fflushErrno = fflushReturn ? errno : 0;
ASSERT_EQ(0, fflushReturn);
ASSERT_EQ(0, fflushErrno);
int fcloseReturn = fclose(fp);
int fcloseErrno = fcloseReturn ? errno : 0;
ASSERT_EQ(0, fcloseReturn);
ASSERT_EQ(0, fcloseErrno);
if ((fcloseErrno == ENOMEM) || (fflushErrno == ENOMEM)) {
fprintf(stderr,
"Kernel does not have space allocated to pmsg pstore driver "
"configured\n");
}
if (!fcloseReturn && !fcloseErrno && !fflushReturn && !fflushReturn) {
fprintf(stderr,
"Reboot, ensure string libc.__pstore_append is in "
"/sys/fs/pstore/pmsg-ramoops-0\n");
}
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,81 +27,76 @@
// include file API purity. We do however want to allow the _option_ that
// log/log_id.h could include this file, or related content, in the future.
#ifndef __android_LogPriority_defined
# define ANDROID_LOG_INFO 4
#define ANDROID_LOG_INFO 4
#endif
TEST(liblog, log_id) {
int count = 0;
int count = 0;
for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
log_id_t id = static_cast<log_id_t>(i);
const char *name = android_log_id_to_name(id);
if (id != android_name_to_log_id(name)) {
continue;
}
++count;
fprintf(stderr, "log buffer %s\r", name);
for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
log_id_t id = static_cast<log_id_t>(i);
const char* name = android_log_id_to_name(id);
if (id != android_name_to_log_id(name)) {
continue;
}
ASSERT_EQ(LOG_ID_MAX, count);
++count;
fprintf(stderr, "log buffer %s\r", name);
}
ASSERT_EQ(LOG_ID_MAX, count);
}
TEST(liblog, __android_log_buf_print) {
EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_print",
"radio"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
"TEST__android_log_buf_print",
"system"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_buf_print",
"main"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_print", "radio"));
usleep(1000);
EXPECT_LT(0,
__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
"TEST__android_log_buf_print", "system"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_buf_print", "main"));
usleep(1000);
}
TEST(liblog, __android_log_buf_write) {
EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_write",
"radio"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
"TEST__android_log_buf_write",
"system"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_buf_write",
"main"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
"TEST__android_log_buf_write", "radio"));
usleep(1000);
EXPECT_LT(0,
__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
"TEST__android_log_buf_write", "system"));
usleep(1000);
EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_buf_write", "main"));
usleep(1000);
}
static void* ConcurrentPrintFn(void *arg) {
int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_print", "Concurrent %" PRIuPTR,
reinterpret_cast<uintptr_t>(arg));
return reinterpret_cast<void*>(ret);
static void* ConcurrentPrintFn(void* arg) {
int ret = __android_log_buf_print(
LOG_ID_MAIN, ANDROID_LOG_INFO, "TEST__android_log_print",
"Concurrent %" PRIuPTR, reinterpret_cast<uintptr_t>(arg));
return reinterpret_cast<void*>(ret);
}
#define NUM_CONCURRENT 64
#define _concurrent_name(a,n) a##__concurrent##n
#define concurrent_name(a,n) _concurrent_name(a,n)
#define _concurrent_name(a, n) a##__concurrent##n
#define concurrent_name(a, n) _concurrent_name(a, n)
TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
pthread_t t[NUM_CONCURRENT];
int i;
for (i=0; i < NUM_CONCURRENT; i++) {
ASSERT_EQ(0, pthread_create(&t[i], NULL,
ConcurrentPrintFn,
reinterpret_cast<void *>(i)));
pthread_t t[NUM_CONCURRENT];
int i;
for (i = 0; i < NUM_CONCURRENT; i++) {
ASSERT_EQ(0, pthread_create(&t[i], NULL, ConcurrentPrintFn,
reinterpret_cast<void*>(i)));
}
int ret = 0;
for (i = 0; i < NUM_CONCURRENT; i++) {
void* result;
ASSERT_EQ(0, pthread_join(t[i], &result));
int this_result = reinterpret_cast<uintptr_t>(result);
if ((0 == ret) && (0 != this_result)) {
ret = this_result;
}
int ret = 0;
for (i=0; i < NUM_CONCURRENT; i++) {
void* result;
ASSERT_EQ(0, pthread_join(t[i], &result));
int this_result = reinterpret_cast<uintptr_t>(result);
if ((0 == ret) && (0 != this_result)) {
ret = this_result;
}
}
ASSERT_LT(0, ret);
}
ASSERT_LT(0, ret);
}

View File

@ -27,91 +27,93 @@
#include <log/log_radio.h>
TEST(liblog, RLOG) {
static const char content[] = "log_radio.h";
static const char content_false[] = "log_radio.h false";
static const char content[] = "log_radio.h";
static const char content_false[] = "log_radio.h false";
// ratelimit content to 10/s to keep away from spam filters
// do not send identical content together to keep away from spam filters
// ratelimit content to 10/s to keep away from spam filters
// do not send identical content together to keep away from spam filters
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGV"
RLOGV(content);
usleep(100000);
RLOGV(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGD"
RLOGD(content);
usleep(100000);
RLOGD(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGI"
RLOGI(content);
usleep(100000);
RLOGI(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGW"
RLOGW(content);
usleep(100000);
RLOGW(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGE"
RLOGE(content);
usleep(100000);
RLOGE(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGV"
RLOGV_IF(true, content);
usleep(100000);
RLOGV_IF(false, content_false);
usleep(100000);
RLOGV_IF(true, content);
usleep(100000);
RLOGV_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGD"
RLOGD_IF(true, content);
usleep(100000);
RLOGD_IF(false, content_false);
usleep(100000);
RLOGD_IF(true, content);
usleep(100000);
RLOGD_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGI"
RLOGI_IF(true, content);
usleep(100000);
RLOGI_IF(false, content_false);
usleep(100000);
RLOGI_IF(true, content);
usleep(100000);
RLOGI_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGW"
RLOGW_IF(true, content);
usleep(100000);
RLOGW_IF(false, content_false);
usleep(100000);
RLOGW_IF(true, content);
usleep(100000);
RLOGW_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__RLOGE"
RLOGE_IF(true, content);
usleep(100000);
RLOGE_IF(false, content_false);
RLOGE_IF(true, content);
usleep(100000);
RLOGE_IF(false, content_false);
#ifdef __ANDROID__
// give time for content to long-path through logger
sleep(1);
// give time for content to long-path through logger
sleep(1);
std::string buf = android::base::StringPrintf(
"logcat -b radio --pid=%u -d -s"
" TEST__RLOGV TEST__RLOGD TEST__RLOGI TEST__RLOGW TEST__RLOGE",
(unsigned)getpid());
FILE* fp = popen(buf.c_str(), "r");
int count = 0;
int count_false = 0;
if (fp) {
if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
pclose(fp);
for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos; ++pos) {
++count;
}
for (size_t pos = 0; (pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
++count_false;
}
std::string buf = android::base::StringPrintf(
"logcat -b radio --pid=%u -d -s"
" TEST__RLOGV TEST__RLOGD TEST__RLOGI TEST__RLOGW TEST__RLOGE",
(unsigned)getpid());
FILE* fp = popen(buf.c_str(), "r");
int count = 0;
int count_false = 0;
if (fp) {
if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
pclose(fp);
for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos;
++pos) {
++count;
}
EXPECT_EQ(0, count_false);
for (size_t pos = 0;
(pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
++count_false;
}
}
EXPECT_EQ(0, count_false);
#if LOG_NDEBUG
ASSERT_EQ(8, count);
ASSERT_EQ(8, count);
#else
ASSERT_EQ(10, count);
ASSERT_EQ(10, count);
#endif
#else
GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
#endif
}

View File

@ -20,8 +20,8 @@
#include <string>
#include <android/log.h> // minimal logging API
#include <android-base/stringprintf.h>
#include <android/log.h> // minimal logging API
#include <gtest/gtest.h>
// Test the APIs in this standalone include file
#include <log/log_read.h>
@ -29,90 +29,90 @@
TEST(liblog, __android_log_write__android_logger_list_read) {
#ifdef __ANDROID__
pid_t pid = getpid();
pid_t pid = getpid();
struct logger_list *logger_list;
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
struct logger_list* logger_list;
ASSERT_TRUE(
NULL !=
(logger_list = android_logger_list_open(
LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
std::string buf = android::base::StringPrintf("pid=%u ts=%ld.%09ld",
pid, ts.tv_sec, ts.tv_nsec);
static const char tag[] = "liblog.__android_log_write__android_logger_list_read";
static const char prio = ANDROID_LOG_DEBUG;
ASSERT_LT(0, __android_log_write(prio, tag, buf.c_str()));
usleep(1000000);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
std::string buf = android::base::StringPrintf("pid=%u ts=%ld.%09ld", pid,
ts.tv_sec, ts.tv_nsec);
static const char tag[] =
"liblog.__android_log_write__android_logger_list_read";
static const char prio = ANDROID_LOG_DEBUG;
ASSERT_LT(0, __android_log_write(prio, tag, buf.c_str()));
usleep(1000000);
buf = std::string(&prio, sizeof(prio)) +
tag +
std::string("", 1) +
buf +
std::string("", 1);
buf = std::string(&prio, sizeof(prio)) + tag + std::string("", 1) + buf +
std::string("", 1);
int count = 0;
int count = 0;
for (;;) {
log_msg log_msg;
if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
for (;;) {
log_msg log_msg;
if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
EXPECT_EQ(log_msg.entry.pid, pid);
// There may be a future where we leak "liblog" tagged LOG_ID_EVENT
// binary messages through so that logger losses can be correlated?
EXPECT_EQ(log_msg.id(), LOG_ID_MAIN);
EXPECT_EQ(log_msg.entry.pid, pid);
// There may be a future where we leak "liblog" tagged LOG_ID_EVENT
// binary messages through so that logger losses can be correlated?
EXPECT_EQ(log_msg.id(), LOG_ID_MAIN);
if (log_msg.entry.len != buf.length()) continue;
if (log_msg.entry.len != buf.length()) continue;
if (buf != std::string(log_msg.msg(), log_msg.entry.len)) continue;
if (buf != std::string(log_msg.msg(), log_msg.entry.len)) continue;
++count;
}
android_logger_list_close(logger_list);
++count;
}
android_logger_list_close(logger_list);
EXPECT_EQ(1, count);
EXPECT_EQ(1, count);
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
TEST(liblog, android_logger_get_) {
#ifdef __ANDROID__
// This test assumes the log buffers are filled with noise from
// normal operations. It will fail if done immediately after a
// logcat -c.
struct logger_list * logger_list = android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
// This test assumes the log buffers are filled with noise from
// normal operations. It will fail if done immediately after a
// logcat -c.
struct logger_list* logger_list =
android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
log_id_t id = static_cast<log_id_t>(i);
const char *name = android_log_id_to_name(id);
if (id != android_name_to_log_id(name)) {
continue;
}
fprintf(stderr, "log buffer %s\r", name);
struct logger * logger;
EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
EXPECT_EQ(id, android_logger_get_id(logger));
ssize_t get_log_size = android_logger_get_log_size(logger);
/* security buffer is allowed to be denied */
if (strcmp("security", name)) {
EXPECT_LT(0, get_log_size);
/* crash buffer is allowed to be empty, that is actually healthy! */
EXPECT_LE((strcmp("crash", name)) != 0,
android_logger_get_log_readable_size(logger));
} else {
EXPECT_NE(0, get_log_size);
if (get_log_size < 0) {
EXPECT_GT(0, android_logger_get_log_readable_size(logger));
} else {
EXPECT_LE(0, android_logger_get_log_readable_size(logger));
}
}
EXPECT_LT(0, android_logger_get_log_version(logger));
for (int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
log_id_t id = static_cast<log_id_t>(i);
const char* name = android_log_id_to_name(id);
if (id != android_name_to_log_id(name)) {
continue;
}
fprintf(stderr, "log buffer %s\r", name);
struct logger* logger;
EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
EXPECT_EQ(id, android_logger_get_id(logger));
ssize_t get_log_size = android_logger_get_log_size(logger);
/* security buffer is allowed to be denied */
if (strcmp("security", name)) {
EXPECT_LT(0, get_log_size);
/* crash buffer is allowed to be empty, that is actually healthy! */
EXPECT_LE((strcmp("crash", name)) != 0,
android_logger_get_log_readable_size(logger));
} else {
EXPECT_NE(0, get_log_size);
if (get_log_size < 0) {
EXPECT_GT(0, android_logger_get_log_readable_size(logger));
} else {
EXPECT_LE(0, android_logger_get_log_readable_size(logger));
}
}
EXPECT_LT(0, android_logger_get_log_version(logger));
}
android_logger_list_close(logger_list);
android_logger_list_close(logger_list);
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}

View File

@ -27,91 +27,93 @@
#include <log/log_system.h>
TEST(liblog, SLOG) {
static const char content[] = "log_system.h";
static const char content_false[] = "log_system.h false";
static const char content[] = "log_system.h";
static const char content_false[] = "log_system.h false";
// ratelimit content to 10/s to keep away from spam filters
// do not send identical content together to keep away from spam filters
// ratelimit content to 10/s to keep away from spam filters
// do not send identical content together to keep away from spam filters
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGV"
SLOGV(content);
usleep(100000);
SLOGV(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGD"
SLOGD(content);
usleep(100000);
SLOGD(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGI"
SLOGI(content);
usleep(100000);
SLOGI(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGW"
SLOGW(content);
usleep(100000);
SLOGW(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGE"
SLOGE(content);
usleep(100000);
SLOGE(content);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGV"
SLOGV_IF(true, content);
usleep(100000);
SLOGV_IF(false, content_false);
usleep(100000);
SLOGV_IF(true, content);
usleep(100000);
SLOGV_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGD"
SLOGD_IF(true, content);
usleep(100000);
SLOGD_IF(false, content_false);
usleep(100000);
SLOGD_IF(true, content);
usleep(100000);
SLOGD_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGI"
SLOGI_IF(true, content);
usleep(100000);
SLOGI_IF(false, content_false);
usleep(100000);
SLOGI_IF(true, content);
usleep(100000);
SLOGI_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGW"
SLOGW_IF(true, content);
usleep(100000);
SLOGW_IF(false, content_false);
usleep(100000);
SLOGW_IF(true, content);
usleep(100000);
SLOGW_IF(false, content_false);
usleep(100000);
#undef LOG_TAG
#define LOG_TAG "TEST__SLOGE"
SLOGE_IF(true, content);
usleep(100000);
SLOGE_IF(false, content_false);
SLOGE_IF(true, content);
usleep(100000);
SLOGE_IF(false, content_false);
#ifdef __ANDROID__
// give time for content to long-path through logger
sleep(1);
// give time for content to long-path through logger
sleep(1);
std::string buf = android::base::StringPrintf(
"logcat -b system --pid=%u -d -s"
" TEST__SLOGV TEST__SLOGD TEST__SLOGI TEST__SLOGW TEST__SLOGE",
(unsigned)getpid());
FILE* fp = popen(buf.c_str(), "r");
int count = 0;
int count_false = 0;
if (fp) {
if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
pclose(fp);
for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos; ++pos) {
++count;
}
for (size_t pos = 0; (pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
++count_false;
}
std::string buf = android::base::StringPrintf(
"logcat -b system --pid=%u -d -s"
" TEST__SLOGV TEST__SLOGD TEST__SLOGI TEST__SLOGW TEST__SLOGE",
(unsigned)getpid());
FILE* fp = popen(buf.c_str(), "r");
int count = 0;
int count_false = 0;
if (fp) {
if (!android::base::ReadFdToString(fileno(fp), &buf)) buf = "";
pclose(fp);
for (size_t pos = 0; (pos = buf.find(content, pos)) != std::string::npos;
++pos) {
++count;
}
EXPECT_EQ(0, count_false);
for (size_t pos = 0;
(pos = buf.find(content_false, pos)) != std::string::npos; ++pos) {
++count_false;
}
}
EXPECT_EQ(0, count_false);
#if LOG_NDEBUG
ASSERT_EQ(8, count);
ASSERT_EQ(8, count);
#else
ASSERT_EQ(10, count);
ASSERT_EQ(10, count);
#endif
#else
GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
GTEST_LOG_(INFO) << "This test does not test end-to-end.\n";
#endif
}

View File

@ -22,16 +22,16 @@
TEST(liblog, log_time) {
#ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
log_time(CLOCK_MONOTONIC);
log_time(CLOCK_MONOTONIC);
EXPECT_EQ(log_time, log_time::EPOCH);
EXPECT_EQ(log_time, log_time::EPOCH);
#endif
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
log_time tl(ts);
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
log_time tl(ts);
EXPECT_EQ(tl, ts);
EXPECT_GE(tl, ts);
EXPECT_LE(tl, ts);
EXPECT_EQ(tl, ts);
EXPECT_GE(tl, ts);
EXPECT_LE(tl, ts);
}

View File

@ -22,58 +22,52 @@
#include "log_portability.h"
LIBLOG_ABI_PUBLIC int readv(int fd, struct iovec *vecs, int count)
{
int total = 0;
LIBLOG_ABI_PUBLIC int readv(int fd, struct iovec* vecs, int count) {
int total = 0;
for ( ; count > 0; count--, vecs++ ) {
char* buf = vecs->iov_base;
int len = vecs->iov_len;
for (; count > 0; count--, vecs++) {
char* buf = vecs->iov_base;
int len = vecs->iov_len;
while (len > 0) {
int ret = read( fd, buf, len );
if (ret < 0) {
if (total == 0)
total = -1;
goto Exit;
}
if (ret == 0)
goto Exit;
while (len > 0) {
int ret = read(fd, buf, len);
if (ret < 0) {
if (total == 0) total = -1;
goto Exit;
}
if (ret == 0) goto Exit;
total += ret;
buf += ret;
len -= ret;
}
total += ret;
buf += ret;
len -= ret;
}
}
Exit:
return total;
return total;
}
LIBLOG_ABI_PUBLIC int writev(int fd, const struct iovec *vecs, int count)
{
int total = 0;
LIBLOG_ABI_PUBLIC int writev(int fd, const struct iovec* vecs, int count) {
int total = 0;
for ( ; count > 0; count--, vecs++ ) {
const char* buf = vecs->iov_base;
int len = vecs->iov_len;
for (; count > 0; count--, vecs++) {
const char* buf = vecs->iov_base;
int len = vecs->iov_len;
while (len > 0) {
int ret = write( fd, buf, len );
if (ret < 0) {
if (total == 0)
total = -1;
goto Exit;
}
if (ret == 0)
goto Exit;
while (len > 0) {
int ret = write(fd, buf, len);
if (ret < 0) {
if (total == 0) total = -1;
goto Exit;
}
if (ret == 0) goto Exit;
total += ret;
buf += ret;
len -= ret;
}
total += ret;
buf += ret;
len -= ret;
}
}
Exit:
return total;
return total;
}
#endif