liblog: specify clang format
Switch coding style to match SideEffects: None Test: compile Bug: 27405083 Change-Id: Id426d5c5e3b18f2ceec22b31bbc9781aabf6bcca
This commit is contained in:
parent
c1b3c8ef26
commit
2ed51d708e
|
@ -0,0 +1,9 @@
|
|||
BasedOnStyle: Google
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
|
||||
CommentPragmas: NOLINT:.*
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
PenaltyExcessCharacter: 32
|
||||
|
||||
Cpp11BracedListStyle: false
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
131
liblog/logger.h
131
liblog/logger.h
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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
2901
liblog/logprint.c
2901
liblog/logprint.c
File diff suppressed because it is too large
Load Diff
1056
liblog/pmsg_reader.c
1056
liblog/pmsg_reader.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
74
liblog/uio.c
74
liblog/uio.c
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue