summaryrefslogtreecommitdiff
path: root/liblog/logger_read.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'liblog/logger_read.cpp')
-rw-r--r--liblog/logger_read.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/liblog/logger_read.cpp b/liblog/logger_read.cpp
new file mode 100644
index 000000000..4937042eb
--- /dev/null
+++ b/liblog/logger_read.cpp
@@ -0,0 +1,149 @@
+/*
+** Copyright 2013-2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "log/log_read.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <android/log.h>
+
+#include "logd_reader.h"
+#include "logger.h"
+#include "pmsg_reader.h"
+
+/* method for getting the associated sublog id */
+log_id_t android_logger_get_id(struct logger* logger) {
+ return static_cast<log_id_t>(reinterpret_cast<uintptr_t>(logger) & LOGGER_LOG_ID_MASK);
+}
+
+static struct logger_list* android_logger_list_alloc_internal(int mode, unsigned int tail,
+ log_time start, pid_t pid) {
+ auto* logger_list = static_cast<struct logger_list*>(calloc(1, sizeof(struct logger_list)));
+ if (!logger_list) {
+ return nullptr;
+ }
+
+ logger_list->mode = mode;
+ logger_list->start = start;
+ logger_list->tail = tail;
+ logger_list->pid = pid;
+
+ return logger_list;
+}
+
+struct logger_list* android_logger_list_alloc(int mode, unsigned int tail, pid_t pid) {
+ return android_logger_list_alloc_internal(mode, tail, log_time(0, 0), pid);
+}
+
+struct logger_list* android_logger_list_alloc_time(int mode, log_time start, pid_t pid) {
+ return android_logger_list_alloc_internal(mode, 0, start, pid);
+}
+
+/* Open the named log and add it to the logger list */
+struct logger* android_logger_open(struct logger_list* logger_list, log_id_t logId) {
+ if (!logger_list || (logId >= LOG_ID_MAX)) {
+ return nullptr;
+ }
+
+ logger_list->log_mask |= 1 << logId;
+
+ uintptr_t logger = logId;
+ logger |= (logger_list->mode & ANDROID_LOG_PSTORE) ? LOGGER_PMSG : LOGGER_LOGD;
+ return reinterpret_cast<struct logger*>(logger);
+}
+
+/* Open the single named log and make it part of a new logger list */
+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 (!android_logger_open(logger_list, logId)) {
+ android_logger_list_free(logger_list);
+ return NULL;
+ }
+
+ return logger_list;
+}
+
+int android_logger_list_read(struct logger_list* logger_list, struct log_msg* log_msg) {
+ if (logger_list == nullptr || logger_list->log_mask == 0) {
+ return -EINVAL;
+ }
+
+ int ret = 0;
+
+#ifdef __ANDROID__
+ if (logger_list->mode & ANDROID_LOG_PSTORE) {
+ ret = PmsgRead(logger_list, log_msg);
+ } else {
+ ret = LogdRead(logger_list, log_msg);
+ }
+#endif
+
+ if (ret <= 0) {
+ return ret;
+ }
+
+ if (ret > LOGGER_ENTRY_MAX_LEN) {
+ ret = LOGGER_ENTRY_MAX_LEN;
+ }
+
+ if (ret < static_cast<int>(sizeof(log_msg->entry))) {
+ return -EINVAL;
+ }
+
+ if (log_msg->entry.hdr_size < sizeof(log_msg->entry) ||
+ log_msg->entry.hdr_size >= LOGGER_ENTRY_MAX_LEN - sizeof(log_msg->entry)) {
+ return -EINVAL;
+ }
+
+ if (log_msg->entry.len > ret - log_msg->entry.hdr_size) {
+ return -EINVAL;
+ }
+
+ log_msg->buf[log_msg->entry.len + log_msg->entry.hdr_size] = '\0';
+
+ return ret;
+}
+
+/* Close all the logs */
+void android_logger_list_free(struct logger_list* logger_list) {
+ if (logger_list == NULL) {
+ return;
+ }
+
+#ifdef __ANDROID__
+ if (logger_list->mode & ANDROID_LOG_PSTORE) {
+ PmsgClose(logger_list);
+ } else {
+ LogdClose(logger_list);
+ }
+#endif
+
+ free(logger_list);
+}