1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef _LIBLOG_LOGGER_H__ 18 #define _LIBLOG_LOGGER_H__ 19 20 #include <stdatomic.h> 21 #include <stdbool.h> 22 23 #include <cutils/list.h> 24 #include <log/log.h> 25 #include <log/uio.h> 26 27 #include "log_portability.h" 28 29 __BEGIN_DECLS 30 31 /* Union, sock or fd of zero is not allowed unless static initialized */ 32 union android_log_context { 33 void* priv; 34 atomic_int sock; 35 atomic_int fd; 36 struct listnode* node; 37 atomic_uintptr_t atomic_pointer; 38 }; 39 40 struct android_log_transport_write { 41 struct listnode node; 42 const char* name; /* human name to describe the transport */ 43 unsigned logMask; /* mask cache of available() success */ 44 union android_log_context context; /* Initialized by static allocation */ 45 46 int (*available)(log_id_t logId); /* Does not cause resources to be taken */ 47 int (*open)(); /* can be called multiple times, reusing current resources */ 48 void (*close)(); /* free up resources */ 49 /* write log to transport, returns number of bytes propagated, or -errno */ 50 int (*write)(log_id_t logId, struct timespec* ts, struct iovec* vec, 51 size_t nr); 52 }; 53 54 struct android_log_logger_list; 55 struct android_log_transport_context; 56 struct android_log_logger; 57 58 struct android_log_transport_read { 59 struct listnode node; 60 const char* name; /* human name to describe the transport */ 61 62 /* Does not cause resources to be taken */ 63 int (*available)(log_id_t logId); 64 int (*version)(struct android_log_logger* logger, 65 struct android_log_transport_context* transp); 66 /* Release resources taken by the following interfaces */ 67 void (*close)(struct android_log_logger_list* logger_list, 68 struct android_log_transport_context* transp); 69 /* 70 * Expect all to instantiate open automagically on any call, 71 * so we do not have an explicit open call. 72 */ 73 int (*read)(struct android_log_logger_list* logger_list, 74 struct android_log_transport_context* transp, 75 struct log_msg* log_msg); 76 /* Must only be called if not ANDROID_LOG_NONBLOCK (blocking) */ 77 int (*poll)(struct android_log_logger_list* logger_list, 78 struct android_log_transport_context* transp); 79 80 int (*clear)(struct android_log_logger* logger, 81 struct android_log_transport_context* transp); 82 ssize_t (*setSize)(struct android_log_logger* logger, 83 struct android_log_transport_context* transp, size_t size); 84 ssize_t (*getSize)(struct android_log_logger* logger, 85 struct android_log_transport_context* transp); 86 ssize_t (*getReadableSize)(struct android_log_logger* logger, 87 struct android_log_transport_context* transp); 88 89 ssize_t (*getPrune)(struct android_log_logger_list* logger_list, 90 struct android_log_transport_context* transp, char* buf, 91 size_t len); 92 ssize_t (*setPrune)(struct android_log_logger_list* logger_list, 93 struct android_log_transport_context* transp, char* buf, 94 size_t len); 95 ssize_t (*getStats)(struct android_log_logger_list* logger_list, 96 struct android_log_transport_context* transp, char* buf, 97 size_t len); 98 }; 99 100 struct android_log_logger_list { 101 struct listnode node; 102 struct listnode logger; 103 struct listnode transport; 104 int mode; 105 unsigned int tail; 106 log_time start; 107 pid_t pid; 108 }; 109 110 struct android_log_logger { 111 struct listnode node; 112 struct android_log_logger_list* parent; 113 114 log_id_t logId; 115 }; 116 117 struct android_log_transport_context { 118 struct listnode node; 119 union android_log_context context; /* zero init per-transport context */ 120 struct android_log_logger_list* parent; 121 122 struct android_log_transport_read* transport; 123 unsigned logMask; /* mask of requested log buffers */ 124 int ret; /* return value associated with following data */ 125 struct log_msg logMsg; /* peek at upcoming data, valid if logMsg.len != 0 */ 126 }; 127 128 /* assumes caller has structures read-locked, single threaded, or fenced */ 129 #define transport_context_for_each(transp, logger_list) \ 130 for ((transp) = node_to_item((logger_list)->transport.next, \ 131 struct android_log_transport_context, node); \ 132 ((transp) != node_to_item(&(logger_list)->transport, \ 133 struct android_log_transport_context, node)) && \ 134 ((transp)->parent == (logger_list)); \ 135 (transp) = node_to_item((transp)->node.next, \ 136 struct android_log_transport_context, node)) 137 138 #define logger_for_each(logp, logger_list) \ 139 for ((logp) = node_to_item((logger_list)->logger.next, \ 140 struct android_log_logger, node); \ 141 ((logp) != node_to_item(&(logger_list)->logger, \ 142 struct android_log_logger, node)) && \ 143 ((logp)->parent == (logger_list)); \ 144 (logp) = \ 145 node_to_item((logp)->node.next, struct android_log_logger, node)) 146 147 /* 148 * Global list of log readers. 149 * 150 * Usage case: search out transport contexts for all readers 151 */ 152 153 LIBLOG_HIDDEN struct listnode __android_log_readers; 154 155 #if defined(_WIN32) 156 #define logger_list_rdlock() 157 #define logger_list_wrlock() 158 #define logger_list_unlock() 159 #else 160 LIBLOG_HIDDEN pthread_rwlock_t __android_log_readers_lock; 161 162 #define logger_list_rdlock() pthread_rwlock_rdlock(&__android_log_readers_lock) 163 #define logger_list_wrlock() pthread_rwlock_wrlock(&__android_log_readers_lock) 164 #define logger_list_unlock() pthread_rwlock_unlock(&__android_log_readers_lock) 165 #endif 166 167 /* Must be called with logger_list_rdlock() or logger_list_wrlock() held */ 168 #define logger_list_for_each(logger_list) \ 169 for ((logger_list) = node_to_item(&__android_log_readers, \ 170 struct android_log_logger_list, node); \ 171 (logger_list) != node_to_item(&__android_log_readers, \ 172 struct android_log_logger_list, node) && \ 173 (logger_list) != node_to_item((logger_list)->node.next, \ 174 struct android_log_logger_list, node); \ 175 (logger_list) = node_to_item((logger_list)->node.next, \ 176 struct android_log_logger_list, node)) 177 178 /* OS specific dribs and drabs */ 179 180 #if defined(_WIN32) 181 #include <private/android_filesystem_config.h> 182 typedef uint32_t uid_t; 183 static inline uid_t __android_log_uid() { 184 return AID_SYSTEM; 185 } 186 #else 187 static inline uid_t __android_log_uid() { 188 return getuid(); 189 } 190 #endif 191 192 LIBLOG_HIDDEN void __android_log_lock(); 193 LIBLOG_HIDDEN int __android_log_trylock(); 194 LIBLOG_HIDDEN void __android_log_unlock(); 195 196 LIBLOG_HIDDEN int __android_log_transport; 197 198 __END_DECLS 199 200 #endif /* _LIBLOG_LOGGER_H__ */ 201