diff options
author | Mark Salyzyn <salyzyn@google.com> | 2017-03-09 08:09:43 -0800 |
---|---|---|
committer | Mark Salyzyn <salyzyn@google.com> | 2017-03-09 09:36:19 -0800 |
commit | 2ed51d708eda64516ec79ac6397f690de38f0075 (patch) | |
tree | 9ea938a4ee0461c443dc99e197827fc36ecd643b | |
parent | c1b3c8ef2629eac2a73aa4a95bf43a66edf4cd0f (diff) | |
download | core-2ed51d708eda64516ec79ac6397f690de38f0075.tar.gz core-2ed51d708eda64516ec79ac6397f690de38f0075.tar.bz2 core-2ed51d708eda64516ec79ac6397f690de38f0075.zip |
liblog: specify clang format
Switch coding style to match
SideEffects: None
Test: compile
Bug: 27405083
Change-Id: Id426d5c5e3b18f2ceec22b31bbc9781aabf6bcca
52 files changed, 10347 insertions, 10634 deletions
diff --git a/liblog/.clang-format b/liblog/.clang-format new file mode 100644 index 000000000..9db87a8f5 --- /dev/null +++ b/liblog/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: Google +AllowShortFunctionsOnASingleLine: false + +CommentPragmas: NOLINT:.* +DerivePointerAlignment: false +PointerAlignment: Left +PenaltyExcessCharacter: 32 + +Cpp11BracedListStyle: false diff --git a/liblog/config_read.c b/liblog/config_read.c index b9a281b30..718b77991 100644 --- a/liblog/config_read.c +++ b/liblog/config_read.c @@ -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); + } } diff --git a/liblog/config_read.h b/liblog/config_read.h index 892e80dca..7b29fa4c2 100644 --- a/liblog/config_read.h +++ b/liblog/config_read.h @@ -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_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(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) LIBLOG_HIDDEN void __android_log_config_read(); LIBLOG_HIDDEN void __android_log_config_read_close(); diff --git a/liblog/config_write.c b/liblog/config_write.c index 6a6c2205d..22570709f 100644 --- a/liblog/config_write.c +++ b/liblog/config_write.c @@ -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); + } } diff --git a/liblog/config_write.h b/liblog/config_write.h index 882541130..db1a08314 100644 --- a/liblog/config_write.h +++ b/liblog/config_write.h @@ -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_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(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) LIBLOG_HIDDEN void __android_log_config_write(); LIBLOG_HIDDEN void __android_log_config_write_close(); diff --git a/liblog/event_tag_map.cpp b/liblog/event_tag_map.cpp index 42f0f3715..bdad2c2e6 100644 --- a/liblog/event_tag_map.cpp +++ b/liblog/event_tag_map.cpp @@ -31,9 +31,9 @@ #include <unordered_map> #include <log/event_tag_map.h> +#include <private/android_logger.h> #include <utils/FastStrcmp.h> #include <utils/RWLock.h> -#include <private/android_logger.h> #include "log_portability.h" #include "logd_reader.h" @@ -41,184 +41,192 @@ #define OUT_TAG "EventTagMap" class MapString { -private: - const std::string* alloc; // HAS-AN - const std::experimental::string_view str; // HAS-A - -public: - operator const std::experimental::string_view() const { return str; } - - const char* data() const { return str.data(); } - size_t length() const { return str.length(); } - - bool operator== (const MapString& rval) const { - if (length() != rval.length()) return false; - if (length() == 0) return true; - return fastcmp<strncmp>(data(), rval.data(), length()) == 0; - } - bool operator!= (const MapString& rval) const { - return !(*this == rval); - } - - MapString(const char* str, size_t len) : alloc(NULL), str(str, len) { } - explicit MapString(const std::string& str) : - alloc(new std::string(str)), - str(alloc->data(), alloc->length()) { } - MapString(MapString &&rval) : - alloc(rval.alloc), - str(rval.data(), rval.length()) { - rval.alloc = NULL; - } - explicit MapString(const MapString &rval) : - alloc(rval.alloc ? new std::string(*rval.alloc) : NULL), - str(alloc ? alloc->data() : rval.data(), rval.length()) { } - - ~MapString() { if (alloc) delete alloc; } + private: + const std::string* alloc; // HAS-AN + const std::experimental::string_view str; // HAS-A + + public: + operator const std::experimental::string_view() const { + return str; + } + + const char* data() const { + return str.data(); + } + size_t length() const { + return str.length(); + } + + bool operator==(const MapString& rval) const { + if (length() != rval.length()) return false; + if (length() == 0) return true; + return fastcmp<strncmp>(data(), rval.data(), length()) == 0; + } + bool operator!=(const MapString& rval) const { + return !(*this == rval); + } + + MapString(const char* str, size_t len) : alloc(NULL), str(str, len) { + } + explicit MapString(const std::string& str) + : alloc(new std::string(str)), str(alloc->data(), alloc->length()) { + } + MapString(MapString&& rval) + : alloc(rval.alloc), str(rval.data(), rval.length()) { + rval.alloc = NULL; + } + explicit MapString(const MapString& rval) + : alloc(rval.alloc ? new std::string(*rval.alloc) : NULL), + str(alloc ? alloc->data() : rval.data(), rval.length()) { + } + + ~MapString() { + if (alloc) delete alloc; + } }; // Hash for MapString -template <> struct std::hash<MapString> - : public std::unary_function<const MapString&, size_t> { - size_t operator()(const MapString& __t) const noexcept { - if (!__t.length()) return 0; - return std::hash<std::experimental::string_view>()(std::experimental::string_view(__t)); - } +template <> +struct std::hash<MapString> + : public std::unary_function<const MapString&, size_t> { + size_t operator()(const MapString& __t) const noexcept { + if (!__t.length()) return 0; + return std::hash<std::experimental::string_view>()( + std::experimental::string_view(__t)); + } }; typedef std::pair<MapString, MapString> TagFmt; -template <> struct std::hash<TagFmt> - : public std::unary_function<const TagFmt&, size_t> { - size_t operator()(const TagFmt& __t) const noexcept { - // Tag is typically unique. Will cost us an extra 100ns for the - // unordered_map lookup if we instead did a hash that combined - // both of tag and fmt members, e.g.: - // - // return std::hash<MapString>()(__t.first) ^ - // std::hash<MapString>()(__t.second); - return std::hash<MapString>()(__t.first); - } +template <> +struct std::hash<TagFmt> : public std::unary_function<const TagFmt&, size_t> { + size_t operator()(const TagFmt& __t) const noexcept { + // Tag is typically unique. Will cost us an extra 100ns for the + // unordered_map lookup if we instead did a hash that combined + // both of tag and fmt members, e.g.: + // + // return std::hash<MapString>()(__t.first) ^ + // std::hash<MapString>()(__t.second); + return std::hash<MapString>()(__t.first); + } }; // Map struct EventTagMap { -# define NUM_MAPS 2 - // memory-mapped source file; we get strings from here - void* mapAddr[NUM_MAPS]; - size_t mapLen[NUM_MAPS]; - -private: - std::unordered_map<uint32_t, TagFmt> Idx2TagFmt; - std::unordered_map<TagFmt, uint32_t> TagFmt2Idx; - std::unordered_map<MapString, uint32_t> Tag2Idx; - // protect unordered sets - android::RWLock rwlock; - -public: - EventTagMap() { - memset(mapAddr, 0, sizeof(mapAddr)); - memset(mapLen, 0, sizeof(mapLen)); +#define NUM_MAPS 2 + // memory-mapped source file; we get strings from here + void* mapAddr[NUM_MAPS]; + size_t mapLen[NUM_MAPS]; + + private: + std::unordered_map<uint32_t, TagFmt> Idx2TagFmt; + std::unordered_map<TagFmt, uint32_t> TagFmt2Idx; + std::unordered_map<MapString, uint32_t> Tag2Idx; + // protect unordered sets + android::RWLock rwlock; + + public: + EventTagMap() { + memset(mapAddr, 0, sizeof(mapAddr)); + memset(mapLen, 0, sizeof(mapLen)); + } + + ~EventTagMap() { + Idx2TagFmt.clear(); + TagFmt2Idx.clear(); + Tag2Idx.clear(); + for (size_t which = 0; which < NUM_MAPS; ++which) { + if (mapAddr[which]) { + munmap(mapAddr[which], mapLen[which]); + mapAddr[which] = 0; + } } + } - ~EventTagMap() { - Idx2TagFmt.clear(); - TagFmt2Idx.clear(); - Tag2Idx.clear(); - for (size_t which = 0; which < NUM_MAPS; ++which) { - if (mapAddr[which]) { - munmap(mapAddr[which], mapLen[which]); - mapAddr[which] = 0; - } - } - } - - bool emplaceUnique(uint32_t tag, const TagFmt& tagfmt, bool verbose = false); - const TagFmt* find(uint32_t tag) const; - int find(TagFmt&& tagfmt) const; - int find(MapString&& tag) const; + bool emplaceUnique(uint32_t tag, const TagFmt& tagfmt, bool verbose = false); + const TagFmt* find(uint32_t tag) const; + int find(TagFmt&& tagfmt) const; + int find(MapString&& tag) const; }; -bool EventTagMap::emplaceUnique(uint32_t tag, const TagFmt& tagfmt, bool verbose) { - bool ret = true; - static const char errorFormat[] = OUT_TAG ": duplicate tag entries %" PRIu32 - ":%.*s:%.*s and %" PRIu32 - ":%.*s:%.*s)\n"; - android::RWLock::AutoWLock writeLock(rwlock); - { - std::unordered_map<uint32_t, TagFmt>::const_iterator it; - it = Idx2TagFmt.find(tag); - if (it != Idx2TagFmt.end()) { - if (verbose) { - fprintf(stderr, errorFormat, - it->first, - (int)it->second.first.length(), it->second.first.data(), - (int)it->second.second.length(), it->second.second.data(), - tag, - (int)tagfmt.first.length(), tagfmt.first.data(), - (int)tagfmt.second.length(), tagfmt.second.data()); - } - ret = false; - } else { - Idx2TagFmt.emplace(std::make_pair(tag, tagfmt)); - } +bool EventTagMap::emplaceUnique(uint32_t tag, const TagFmt& tagfmt, + bool verbose) { + bool ret = true; + static const char errorFormat[] = + OUT_TAG ": duplicate tag entries %" PRIu32 ":%.*s:%.*s and %" PRIu32 + ":%.*s:%.*s)\n"; + android::RWLock::AutoWLock writeLock(rwlock); + { + std::unordered_map<uint32_t, TagFmt>::const_iterator it; + it = Idx2TagFmt.find(tag); + if (it != Idx2TagFmt.end()) { + if (verbose) { + fprintf(stderr, errorFormat, it->first, (int)it->second.first.length(), + it->second.first.data(), (int)it->second.second.length(), + it->second.second.data(), tag, (int)tagfmt.first.length(), + tagfmt.first.data(), (int)tagfmt.second.length(), + tagfmt.second.data()); + } + ret = false; + } else { + Idx2TagFmt.emplace(std::make_pair(tag, tagfmt)); } + } - { - std::unordered_map<TagFmt, uint32_t>::const_iterator it; - it = TagFmt2Idx.find(tagfmt); - if (it != TagFmt2Idx.end()) { - if (verbose) { - fprintf(stderr, errorFormat, - it->second, - (int)it->first.first.length(), it->first.first.data(), - (int)it->first.second.length(), it->first.second.data(), - tag, - (int)tagfmt.first.length(), tagfmt.first.data(), - (int)tagfmt.second.length(), tagfmt.second.data()); - } - ret = false; - } else { - TagFmt2Idx.emplace(std::make_pair(tagfmt, tag)); - } + { + std::unordered_map<TagFmt, uint32_t>::const_iterator it; + it = TagFmt2Idx.find(tagfmt); + if (it != TagFmt2Idx.end()) { + if (verbose) { + fprintf(stderr, errorFormat, it->second, (int)it->first.first.length(), + it->first.first.data(), (int)it->first.second.length(), + it->first.second.data(), tag, (int)tagfmt.first.length(), + tagfmt.first.data(), (int)tagfmt.second.length(), + tagfmt.second.data()); + } + ret = false; + } else { + TagFmt2Idx.emplace(std::make_pair(tagfmt, tag)); } + } - { - std::unordered_map<MapString, uint32_t>::const_iterator it; - it = Tag2Idx.find(tagfmt.first); - if (!tagfmt.second.length() && (it != Tag2Idx.end())) { - Tag2Idx.erase(it); - it = Tag2Idx.end(); - } - if (it == Tag2Idx.end()) { - Tag2Idx.emplace(std::make_pair(tagfmt.first, tag)); - } + { + std::unordered_map<MapString, uint32_t>::const_iterator it; + it = Tag2Idx.find(tagfmt.first); + if (!tagfmt.second.length() && (it != Tag2Idx.end())) { + Tag2Idx.erase(it); + it = Tag2Idx.end(); } + if (it == Tag2Idx.end()) { + Tag2Idx.emplace(std::make_pair(tagfmt.first, tag)); + } + } - return ret; + return ret; } const TagFmt* EventTagMap::find(uint32_t tag) const { - std::unordered_map<uint32_t, TagFmt>::const_iterator it; - android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); - it = Idx2TagFmt.find(tag); - if (it == Idx2TagFmt.end()) return NULL; - return &(it->second); + std::unordered_map<uint32_t, TagFmt>::const_iterator it; + android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); + it = Idx2TagFmt.find(tag); + if (it == Idx2TagFmt.end()) return NULL; + return &(it->second); } int EventTagMap::find(TagFmt&& tagfmt) const { - std::unordered_map<TagFmt, uint32_t>::const_iterator it; - android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); - it = TagFmt2Idx.find(std::move(tagfmt)); - if (it == TagFmt2Idx.end()) return -1; - return it->second; + std::unordered_map<TagFmt, uint32_t>::const_iterator it; + android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); + it = TagFmt2Idx.find(std::move(tagfmt)); + if (it == TagFmt2Idx.end()) return -1; + return it->second; } int EventTagMap::find(MapString&& tag) const { - std::unordered_map<MapString, uint32_t>::const_iterator it; - android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); - it = Tag2Idx.find(std::move(tag)); - if (it == Tag2Idx.end()) return -1; - return it->second; + std::unordered_map<MapString, uint32_t>::const_iterator it; + android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock)); + it = Tag2Idx.find(std::move(tag)); + if (it == Tag2Idx.end()) return -1; + return it->second; } // Scan one tag line. @@ -234,158 +242,158 @@ int EventTagMap::find(MapString&& tag) const { // // Returns 0 on success, nonzero on failure. static int scanTagLine(EventTagMap* map, char** pData, int lineNum) { - char* cp; - unsigned long val = strtoul(*pData, &cp, 10); - if (cp == *pData) { - if (lineNum) { - fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n", - lineNum); - } - errno = EINVAL; - return -1; - } - - uint32_t tagIndex = val; - if (tagIndex != val) { - if (lineNum) { - fprintf(stderr, OUT_TAG ": tag number too large on line %d\n", - lineNum); - } - errno = ERANGE; - return -1; - } - - while ((*++cp != '\n') && isspace(*cp)) { + char* cp; + unsigned long val = strtoul(*pData, &cp, 10); + if (cp == *pData) { + if (lineNum) { + fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n", lineNum); } + errno = EINVAL; + return -1; + } - if (*cp == '\n') { - if (lineNum) { - fprintf(stderr, OUT_TAG ": missing tag string on line %d\n", - lineNum); - } - errno = EINVAL; - return -1; + uint32_t tagIndex = val; + if (tagIndex != val) { + if (lineNum) { + fprintf(stderr, OUT_TAG ": tag number too large on line %d\n", lineNum); } + errno = ERANGE; + return -1; + } - const char* tag = cp; - // Determine whether "c" is a valid tag char. - while (isalnum(*++cp) || (*cp == '_')) { } - size_t tagLen = cp - tag; + while ((*++cp != '\n') && isspace(*cp)) { + } - if (!isspace(*cp)) { - if (lineNum) { - fprintf(stderr, OUT_TAG ": invalid tag chars on line %d\n", - lineNum); - } - errno = EINVAL; - return -1; + if (*cp == '\n') { + if (lineNum) { + fprintf(stderr, OUT_TAG ": missing tag string on line %d\n", lineNum); } + errno = EINVAL; + return -1; + } - while (isspace(*cp) && (*cp != '\n')) ++cp; - const char* fmt = NULL; - size_t fmtLen = 0; - if (*cp != '#') { - fmt = cp; - while ((*cp != '\n') && (*cp != '#')) ++cp; - while ((cp > fmt) && isspace(*(cp - 1))) --cp; - fmtLen = cp - fmt; - } + const char* tag = cp; + // Determine whether "c" is a valid tag char. + while (isalnum(*++cp) || (*cp == '_')) { + } + size_t tagLen = cp - tag; - // KISS Only report identicals if they are global - // Ideally we want to check if there are identicals - // recorded for the same uid, but recording that - // unused detail in our database is too burdensome. - bool verbose = true; - while ((*cp != '#') && (*cp != '\n')) ++cp; - if (*cp == '#') { - do { - ++cp; - } while (isspace(*cp) && (*cp != '\n')); - verbose = !!fastcmp<strncmp>(cp, "uid=", strlen("uid=")); + if (!isspace(*cp)) { + if (lineNum) { + fprintf(stderr, OUT_TAG ": invalid tag chars on line %d\n", lineNum); } - - while (*cp != '\n') ++cp; + errno = EINVAL; + return -1; + } + + while (isspace(*cp) && (*cp != '\n')) ++cp; + const char* fmt = NULL; + size_t fmtLen = 0; + if (*cp != '#') { + fmt = cp; + while ((*cp != '\n') && (*cp != '#')) ++cp; + while ((cp > fmt) && isspace(*(cp - 1))) --cp; + fmtLen = cp - fmt; + } + + // KISS Only report identicals if they are global + // Ideally we want to check if there are identicals + // recorded for the same uid, but recording that + // unused detail in our database is too burdensome. + bool verbose = true; + while ((*cp != '#') && (*cp != '\n')) ++cp; + if (*cp == '#') { + do { + ++cp; + } while (isspace(*cp) && (*cp != '\n')); + verbose = !!fastcmp<strncmp>(cp, "uid=", strlen("uid=")); + } + + while (*cp != '\n') ++cp; #ifdef DEBUG - fprintf(stderr, "%d: %p: %.*s\n", lineNum, tag, (int)(cp - *pData), *pData); + fprintf(stderr, "%d: %p: %.*s\n", lineNum, tag, (int)(cp - *pData), *pData); #endif - *pData = cp; - - if (lineNum) { - if (map->emplaceUnique(tagIndex, TagFmt(std::make_pair( - MapString(tag, tagLen), MapString(fmt, fmtLen))), verbose)) { - return 0; - } - } else { - // cache - if (map->emplaceUnique(tagIndex, TagFmt(std::make_pair( - MapString(std::string(tag, tagLen)), - MapString(std::string(fmt, fmtLen)))))) { - return 0; - } + *pData = cp; + + if (lineNum) { + if (map->emplaceUnique(tagIndex, + TagFmt(std::make_pair(MapString(tag, tagLen), + MapString(fmt, fmtLen))), + verbose)) { + return 0; } - errno = EMLINK; - return -1; + } else { + // cache + if (map->emplaceUnique( + tagIndex, + TagFmt(std::make_pair(MapString(std::string(tag, tagLen)), + MapString(std::string(fmt, fmtLen)))))) { + return 0; + } + } + errno = EMLINK; + return -1; } static const char* eventTagFiles[NUM_MAPS] = { - EVENT_TAG_MAP_FILE, - "/dev/event-log-tags", + EVENT_TAG_MAP_FILE, "/dev/event-log-tags", }; // Parse the tags out of the file. static int parseMapLines(EventTagMap* map, size_t which) { - char* cp = static_cast<char*>(map->mapAddr[which]); - size_t len = map->mapLen[which]; - char* endp = cp + len; + char* cp = static_cast<char*>(map->mapAddr[which]); + size_t len = map->mapLen[which]; + char* endp = cp + len; - // insist on EOL at EOF; simplifies parsing and null-termination - if (!len || (*(endp - 1) != '\n')) { + // insist on EOL at EOF; simplifies parsing and null-termination + if (!len || (*(endp - 1) != '\n')) { #ifdef DEBUG - fprintf(stderr, OUT_TAG ": map file %zu[%zu] missing EOL on last line\n", - which, len); + fprintf(stderr, OUT_TAG ": map file %zu[%zu] missing EOL on last line\n", + which, len); #endif - if (which) { // do not propagate errors for other files - return 0; - } - errno = EINVAL; - return -1; + if (which) { // do not propagate errors for other files + return 0; } + errno = EINVAL; + return -1; + } - bool lineStart = true; - int lineNum = 1; - while (cp < endp) { - if (*cp == '\n') { - lineStart = true; - lineNum++; - } else if (lineStart) { - if (*cp == '#') { - // comment; just scan to end - lineStart = false; - } else if (isdigit(*cp)) { - // looks like a tag; scan it out - if (scanTagLine(map, &cp, lineNum) != 0) { - if (!which || (errno != EMLINK)) { - return -1; - } - } - lineNum++; // we eat the '\n' - // leave lineStart==true - } else if (isspace(*cp)) { - // looks like leading whitespace; keep scanning - } else { - fprintf(stderr, - OUT_TAG ": unexpected chars (0x%02x) in tag number on line %d\n", - *cp, lineNum); - errno = EINVAL; - return -1; - } - } else { - // this is a blank or comment line + bool lineStart = true; + int lineNum = 1; + while (cp < endp) { + if (*cp == '\n') { + lineStart = true; + lineNum++; + } else if (lineStart) { + if (*cp == '#') { + // comment; just scan to end + lineStart = false; + } else if (isdigit(*cp)) { + // looks like a tag; scan it out + if (scanTagLine(map, &cp, lineNum) != 0) { + if (!which || (errno != EMLINK)) { + return -1; + } } - cp++; + lineNum++; // we eat the '\n' + // leave lineStart==true + } else if (isspace(*cp)) { + // looks like leading whitespace; keep scanning + } else { + fprintf(stderr, + OUT_TAG + ": unexpected chars (0x%02x) in tag number on line %d\n", + *cp, lineNum); + errno = EINVAL; + return -1; + } + } else { + // this is a blank or comment line } + cp++; + } - return 0; + return 0; } // Open the map file and allocate a structure to manage it. @@ -393,159 +401,155 @@ static int parseMapLines(EventTagMap* map, size_t which) { // We create a private mapping because we want to terminate the log tag // strings with '\0'. LIBLOG_ABI_PUBLIC EventTagMap* android_openEventTagMap(const char* fileName) { - EventTagMap* newTagMap; - off_t end[NUM_MAPS]; - int save_errno, fd[NUM_MAPS]; - size_t which; + EventTagMap* newTagMap; + off_t end[NUM_MAPS]; + int save_errno, fd[NUM_MAPS]; + size_t which; - memset(fd, -1, sizeof(fd)); - memset(end, 0, sizeof(end)); + memset(fd, -1, sizeof(fd)); + memset(end, 0, sizeof(end)); - for (which = 0; which < NUM_MAPS; ++which) { - const char* tagfile = fileName ? fileName : eventTagFiles[which]; + for (which = 0; which < NUM_MAPS; ++which) { + const char* tagfile = fileName ? fileName : eventTagFiles[which]; - fd[which] = open(tagfile, O_RDONLY | O_CLOEXEC); - if (fd[which] < 0) { - if (!which) { - save_errno = errno; - fprintf(stderr, OUT_TAG ": unable to open map '%s': %s\n", - tagfile, strerror(save_errno)); - goto fail_errno; - } - continue; - } - end[which] = lseek(fd[which], 0L, SEEK_END); + fd[which] = open(tagfile, O_RDONLY | O_CLOEXEC); + if (fd[which] < 0) { + if (!which) { save_errno = errno; - (void)lseek(fd[which], 0L, SEEK_SET); - if (!which && (end[0] < 0)) { - fprintf(stderr, OUT_TAG ": unable to seek map '%s' %s\n", - tagfile, strerror(save_errno)); - goto fail_close; - } - if (fileName) break; // Only allow one as specified + fprintf(stderr, OUT_TAG ": unable to open map '%s': %s\n", tagfile, + strerror(save_errno)); + goto fail_errno; + } + continue; } - - newTagMap = new EventTagMap; - if (newTagMap == NULL) { - save_errno = errno; - goto fail_close; + end[which] = lseek(fd[which], 0L, SEEK_END); + save_errno = errno; + (void)lseek(fd[which], 0L, SEEK_SET); + if (!which && (end[0] < 0)) { + fprintf(stderr, OUT_TAG ": unable to seek map '%s' %s\n", tagfile, + strerror(save_errno)); + goto fail_close; } + if (fileName) break; // Only allow one as specified + } + + newTagMap = new EventTagMap; + if (newTagMap == NULL) { + save_errno = errno; + goto fail_close; + } + + for (which = 0; which < NUM_MAPS; ++which) { + if (fd[which] >= 0) { + newTagMap->mapAddr[which] = + mmap(NULL, end[which], which ? PROT_READ : PROT_READ | PROT_WRITE, + which ? MAP_SHARED : MAP_PRIVATE, fd[which], 0); + save_errno = errno; + close(fd[which]); + fd[which] = -1; + if ((newTagMap->mapAddr[which] != MAP_FAILED) && + (newTagMap->mapAddr[which] != NULL)) { + newTagMap->mapLen[which] = end[which]; + } else if (!which) { + const char* tagfile = fileName ? fileName : eventTagFiles[which]; - for (which = 0; which < NUM_MAPS; ++which) { - if (fd[which] >= 0) { - newTagMap->mapAddr[which] = mmap(NULL, end[which], - which ? - PROT_READ : - PROT_READ | PROT_WRITE, - which ? - MAP_SHARED : - MAP_PRIVATE, - fd[which], 0); - save_errno = errno; - close(fd[which]); - fd[which] = -1; - if ((newTagMap->mapAddr[which] != MAP_FAILED) && - (newTagMap->mapAddr[which] != NULL)) { - newTagMap->mapLen[which] = end[which]; - } else if (!which) { - const char* tagfile = fileName ? fileName : eventTagFiles[which]; - - fprintf(stderr, OUT_TAG ": mmap(%s) failed: %s\n", - tagfile, strerror(save_errno)); - goto fail_unmap; - } - } + fprintf(stderr, OUT_TAG ": mmap(%s) failed: %s\n", tagfile, + strerror(save_errno)); + goto fail_unmap; + } } + } - for (which = 0; which < NUM_MAPS; ++which) { - if (parseMapLines(newTagMap, which) != 0) { - delete newTagMap; - return NULL; - } + for (which = 0; which < NUM_MAPS; ++which) { + if (parseMapLines(newTagMap, which) != 0) { + delete newTagMap; + return NULL; } + } - return newTagMap; + return newTagMap; fail_unmap: - save_errno = EINVAL; - delete newTagMap; + save_errno = EINVAL; + delete newTagMap; fail_close: - for (which = 0; which < NUM_MAPS; ++which) close(fd[which]); + for (which = 0; which < NUM_MAPS; ++which) close(fd[which]); fail_errno: - errno = save_errno; - return NULL; + errno = save_errno; + return NULL; } // Close the map. LIBLOG_ABI_PUBLIC void android_closeEventTagMap(EventTagMap* map) { - if (map) delete map; + if (map) delete map; } // Cache miss, go to logd to acquire a public reference. // Because we lack access to a SHARED PUBLIC /dev/event-log-tags file map? static const TagFmt* __getEventTag(EventTagMap* map, unsigned int tag) { - // call event tag service to arrange for a new tag - char *buf = NULL; - // Can not use android::base::StringPrintf, asprintf + free instead. - static const char command_template[] = "getEventTag id=%u"; - int ret = asprintf(&buf, command_template, tag); - if (ret > 0) { - // Add some buffer margin for an estimate of the full return content. - char *cp; - size_t size = ret - strlen(command_template) + - strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); - if (size > (size_t)ret) { - cp = static_cast<char*>(realloc(buf, size)); - if (cp) { - buf = cp; - } else { - size = ret; - } - } else { - size = ret; - } - // Ask event log tag service for an existing entry - if (__send_log_msg(buf, size) >= 0) { - buf[size - 1] = '\0'; - unsigned long val = strtoul(buf, &cp, 10); // return size - if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK - ++cp; - if (!scanTagLine(map, &cp, 0)) { - free(buf); - return map->find(tag); - } - } + // call event tag service to arrange for a new tag + char* buf = NULL; + // Can not use android::base::StringPrintf, asprintf + free instead. + static const char command_template[] = "getEventTag id=%u"; + int ret = asprintf(&buf, command_template, tag); + if (ret > 0) { + // Add some buffer margin for an estimate of the full return content. + char* cp; + size_t size = + ret - strlen(command_template) + + strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); + if (size > (size_t)ret) { + cp = static_cast<char*>(realloc(buf, size)); + if (cp) { + buf = cp; + } else { + size = ret; + } + } else { + size = ret; + } + // Ask event log tag service for an existing entry + if (__send_log_msg(buf, size) >= 0) { + buf[size - 1] = '\0'; + unsigned long val = strtoul(buf, &cp, 10); // return size + if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK + ++cp; + if (!scanTagLine(map, &cp, 0)) { + free(buf); + return map->find(tag); } - free(buf); + } } - return NULL; + free(buf); + } + return NULL; } // Look up an entry in the map. LIBLOG_ABI_PUBLIC const char* android_lookupEventTag_len(const EventTagMap* map, - size_t *len, + size_t* len, unsigned int tag) { - if (len) *len = 0; - const TagFmt* str = map->find(tag); - if (!str) { - str = __getEventTag(const_cast<EventTagMap*>(map), tag); - } - if (!str) return NULL; - if (len) *len = str->first.length(); - return str->first.data(); + if (len) *len = 0; + const TagFmt* str = map->find(tag); + if (!str) { + str = __getEventTag(const_cast<EventTagMap*>(map), tag); + } + if (!str) return NULL; + if (len) *len = str->first.length(); + return str->first.data(); } // Look up an entry in the map. LIBLOG_ABI_PUBLIC const char* android_lookupEventFormat_len( - const EventTagMap* map, size_t *len, unsigned int tag) { - if (len) *len = 0; - const TagFmt* str = map->find(tag); - if (!str) { - str = __getEventTag(const_cast<EventTagMap*>(map), tag); - } - if (!str) return NULL; - if (len) *len = str->second.length(); - return str->second.data(); + const EventTagMap* map, size_t* len, unsigned int tag) { + if (len) *len = 0; + const TagFmt* str = map->find(tag); + if (!str) { + str = __getEventTag(const_cast<EventTagMap*>(map), tag); + } + if (!str) return NULL; + if (len) *len = str->second.length(); + return str->second.data(); } // This function is deprecated and replaced with android_lookupEventTag_len @@ -554,84 +558,84 @@ LIBLOG_ABI_PUBLIC const char* android_lookupEventFormat_len( // deprecating this function everywhere, we save 100s of MB of memory space. LIBLOG_ABI_PUBLIC const char* android_lookupEventTag(const EventTagMap* map, unsigned int tag) { - size_t len; - const char* tagStr = android_lookupEventTag_len(map, &len, tag); - - if (!tagStr) return tagStr; - char* cp = const_cast<char*>(tagStr); - cp += len; - if (*cp) *cp = '\0'; // Trigger copy on write :-( and why deprecated. - return tagStr; + size_t len; + const char* tagStr = android_lookupEventTag_len(map, &len, tag); + + if (!tagStr) return tagStr; + char* cp = const_cast<char*>(tagStr); + cp += len; + if (*cp) *cp = '\0'; // Trigger copy on write :-( and why deprecated. + return tagStr; } // Look up tagname, generate one if necessary, and return a tag LIBLOG_ABI_PUBLIC int android_lookupEventTagNum(EventTagMap* map, const char* tagname, - const char* format, - int prio) { - size_t len = strlen(tagname); - if (!len) { - errno = EINVAL; - return -1; - } - - if ((prio != ANDROID_LOG_UNKNOWN) && (prio < ANDROID_LOG_SILENT) && - !__android_log_is_loggable_len(prio, tagname, len, - __android_log_is_debuggable() ? - ANDROID_LOG_VERBOSE : - ANDROID_LOG_DEBUG)) { - errno = EPERM; - return -1; + const char* format, int prio) { + size_t len = strlen(tagname); + if (!len) { + errno = EINVAL; + return -1; + } + + if ((prio != ANDROID_LOG_UNKNOWN) && (prio < ANDROID_LOG_SILENT) && + !__android_log_is_loggable_len(prio, tagname, len, + __android_log_is_debuggable() + ? ANDROID_LOG_VERBOSE + : ANDROID_LOG_DEBUG)) { + errno = EPERM; + return -1; + } + + if (!format) format = ""; + ssize_t fmtLen = strlen(format); + int ret = map->find(TagFmt( + std::make_pair(MapString(tagname, len), MapString(format, fmtLen)))); + if (ret != -1) return ret; + + // call event tag service to arrange for a new tag + char* buf = NULL; + // Can not use android::base::StringPrintf, asprintf + free instead. + static const char command_template[] = "getEventTag name=%s format=\"%s\""; + ret = asprintf(&buf, command_template, tagname, format); + if (ret > 0) { + // Add some buffer margin for an estimate of the full return content. + char* cp; + size_t size = + ret - strlen(command_template) + + strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); + if (size > (size_t)ret) { + cp = static_cast<char*>(realloc(buf, size)); + if (cp) { + buf = cp; + } else { + size = ret; + } + } else { + size = ret; } - - if (!format) format=""; - ssize_t fmtLen = strlen(format); - int ret = map->find(TagFmt(std::make_pair(MapString(tagname, len), - MapString(format, fmtLen)))); - if (ret != -1) return ret; - - // call event tag service to arrange for a new tag - char *buf = NULL; - // Can not use android::base::StringPrintf, asprintf + free instead. - static const char command_template[] = "getEventTag name=%s format=\"%s\""; - ret = asprintf(&buf, command_template, tagname, format); - if (ret > 0) { - // Add some buffer margin for an estimate of the full return content. - char *cp; - size_t size = ret - strlen(command_template) + - strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?"); - if (size > (size_t)ret) { - cp = static_cast<char*>(realloc(buf, size)); - if (cp) { - buf = cp; - } else { - size = ret; - } - } else { - size = ret; - } - // Ask event log tag service for an allocation - if (__send_log_msg(buf, size) >= 0) { - buf[size - 1] = '\0'; - unsigned long val = strtoul(buf, &cp, 10); // return size - if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK - val = strtoul(cp + 1, &cp, 10); // allocated tag number - if ((val > 0) && (val < UINT32_MAX) && (*cp == '\t')) { - free(buf); - ret = val; - // cache - map->emplaceUnique(ret, TagFmt(std::make_pair( - MapString(std::string(tagname, len)), - MapString(std::string(format, fmtLen))))); - return ret; - } - } + // Ask event log tag service for an allocation + if (__send_log_msg(buf, size) >= 0) { + buf[size - 1] = '\0'; + unsigned long val = strtoul(buf, &cp, 10); // return size + if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK + val = strtoul(cp + 1, &cp, 10); // allocated tag number + if ((val > 0) && (val < UINT32_MAX) && (*cp == '\t')) { + free(buf); + ret = val; + // cache + map->emplaceUnique(ret, TagFmt(std::make_pair( + MapString(std::string(tagname, len)), + MapString(std::string(format, fmtLen))))); + return ret; } - free(buf); + } } + free(buf); + } - // Hail Mary - ret = map->find(MapString(tagname, len)); - if (ret == -1) errno = ESRCH; - return ret; + // Hail Mary + ret = map->find(MapString(tagname, len)); + if (ret == -1) errno = ESRCH; + return ret; } diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c index 1d7a157ae..ae7a33412 100644 --- a/liblog/fake_log_device.c +++ b/liblog/fake_log_device.c @@ -37,9 +37,9 @@ #include "fake_log_device.h" #include "log_portability.h" -#define kMaxTagLen 16 /* from the long-dead utils/Log.cpp */ +#define kMaxTagLen 16 /* from the long-dead utils/Log.cpp */ -#define kTagSetSize 16 /* arbitrary */ +#define kTagSetSize 16 /* arbitrary */ #if 0 #define TRACE(...) printf("fake_log_device: " __VA_ARGS__) @@ -49,45 +49,43 @@ /* from the long-dead utils/Log.cpp */ typedef enum { - FORMAT_OFF = 0, - FORMAT_BRIEF, - FORMAT_PROCESS, - FORMAT_TAG, - FORMAT_THREAD, - FORMAT_RAW, - FORMAT_TIME, - FORMAT_THREADTIME, - FORMAT_LONG + FORMAT_OFF = 0, + FORMAT_BRIEF, + FORMAT_PROCESS, + FORMAT_TAG, + FORMAT_THREAD, + FORMAT_RAW, + FORMAT_TIME, + FORMAT_THREADTIME, + FORMAT_LONG } LogFormat; - /* * Log driver state. */ typedef struct LogState { - /* the fake fd that's seen by the user */ - int fakeFd; + /* the fake fd that's seen by the user */ + int fakeFd; - /* a printable name for this fake device */ - char debugName[sizeof("/dev/log/security")]; + /* a printable name for this fake device */ + char debugName[sizeof("/dev/log/security")]; - /* nonzero if this is a binary log */ - int isBinary; + /* nonzero if this is a binary log */ + int isBinary; - /* global minimum priority */ - int globalMinPriority; + /* global minimum priority */ + int globalMinPriority; - /* output format */ - LogFormat outputFormat; + /* output format */ + LogFormat outputFormat; - /* tags and priorities */ - struct { - char tag[kMaxTagLen]; - int minPriority; - } tagSet[kTagSetSize]; + /* tags and priorities */ + struct { + char tag[kMaxTagLen]; + int minPriority; + } tagSet[kTagSetSize]; } LogState; - #if !defined(_WIN32) /* * Locking. Since we're emulating a device, we need to be prepared @@ -97,28 +95,25 @@ typedef struct LogState { */ static pthread_mutex_t fakeLogDeviceLock = PTHREAD_MUTEX_INITIALIZER; -static void 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(&fakeLogDeviceLock); +static void 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(&fakeLogDeviceLock); } -static void unlock() -{ - pthread_mutex_unlock(&fakeLogDeviceLock); +static void unlock() { + pthread_mutex_unlock(&fakeLogDeviceLock); } -#else // !defined(_WIN32) +#else // !defined(_WIN32) #define lock() ((void)0) #define unlock() ((void)0) #endif // !defined(_WIN32) - /* * File descriptor management. */ @@ -130,45 +125,42 @@ static LogState openLogTable[MAX_OPEN_LOGS]; * Allocate an fd and associate a new LogState with it. * The fd is available via the fakeFd field of the return value. */ -static LogState *createLogState() -{ - size_t i; - - for (i = 0; i < (sizeof(openLogTable) / sizeof(openLogTable[0])); i++) { - if (openLogTable[i].fakeFd == 0) { - openLogTable[i].fakeFd = FAKE_FD_BASE + i; - return &openLogTable[i]; - } +static LogState* createLogState() { + size_t i; + + for (i = 0; i < (sizeof(openLogTable) / sizeof(openLogTable[0])); i++) { + if (openLogTable[i].fakeFd == 0) { + openLogTable[i].fakeFd = FAKE_FD_BASE + i; + return &openLogTable[i]; } - return NULL; + } + return NULL; } /* * Translate an fd to a LogState. */ -static LogState *fdToLogState(int fd) -{ - if (fd >= FAKE_FD_BASE && fd < FAKE_FD_BASE + MAX_OPEN_LOGS) { - return &openLogTable[fd - FAKE_FD_BASE]; - } - return NULL; +static LogState* fdToLogState(int fd) { + if (fd >= FAKE_FD_BASE && fd < FAKE_FD_BASE + MAX_OPEN_LOGS) { + return &openLogTable[fd - FAKE_FD_BASE]; + } + return NULL; } /* * Unregister the fake fd and free the memory it pointed to. */ -static void deleteFakeFd(int fd) -{ - LogState *ls; +static void deleteFakeFd(int fd) { + LogState* ls; - lock(); + lock(); - ls = fdToLogState(fd); - if (ls != NULL) { - memset(&openLogTable[fd - FAKE_FD_BASE], 0, sizeof(openLogTable[0])); - } + ls = fdToLogState(fd); + if (ls != NULL) { + memset(&openLogTable[fd - FAKE_FD_BASE], 0, sizeof(openLogTable[0])); + } - unlock(); + unlock(); } /* @@ -184,145 +176,154 @@ static void deleteFakeFd(int fd) * We also want to check ANDROID_PRINTF_LOG to determine how the output * will look. */ -static void configureInitialState(const char* pathName, LogState* logState) -{ - static const int kDevLogLen = sizeof("/dev/log/") - 1; - - strncpy(logState->debugName, pathName, sizeof(logState->debugName)); - logState->debugName[sizeof(logState->debugName) - 1] = '\0'; - - /* identify binary logs */ - if (!strcmp(pathName + kDevLogLen, "events") || - !strcmp(pathName + kDevLogLen, "security")) { - logState->isBinary = 1; - } - - /* global min priority defaults to "info" level */ - logState->globalMinPriority = ANDROID_LOG_INFO; - - /* - * This is based on the the long-dead utils/Log.cpp code. - */ - const char* tags = getenv("ANDROID_LOG_TAGS"); - TRACE("Found ANDROID_LOG_TAGS='%s'\n", tags); - if (tags != NULL) { - int entry = 0; - - while (*tags != '\0') { - char tagName[kMaxTagLen]; - int i, minPrio; - - while (isspace(*tags)) - tags++; - - i = 0; - while (*tags != '\0' && !isspace(*tags) && *tags != ':' && - i < kMaxTagLen) { - tagName[i++] = *tags++; - } - if (i == kMaxTagLen) { - TRACE("ERROR: env tag too long (%d chars max)\n", kMaxTagLen-1); - return; - } - tagName[i] = '\0'; - - /* default priority, if there's no ":" part; also zero out '*' */ +static void configureInitialState(const char* pathName, LogState* logState) { + static const int kDevLogLen = sizeof("/dev/log/") - 1; + + strncpy(logState->debugName, pathName, sizeof(logState->debugName)); + logState->debugName[sizeof(logState->debugName) - 1] = '\0'; + + /* identify binary logs */ + if (!strcmp(pathName + kDevLogLen, "events") || + !strcmp(pathName + kDevLogLen, "security")) { + logState->isBinary = 1; + } + + /* global min priority defaults to "info" level */ + logState->globalMinPriority = ANDROID_LOG_INFO; + + /* + * This is based on the the long-dead utils/Log.cpp code. + */ + const char* tags = getenv("ANDROID_LOG_TAGS"); + TRACE("Found ANDROID_LOG_TAGS='%s'\n", tags); + if (tags != NULL) { + int entry = 0; + + while (*tags != '\0') { + char tagName[kMaxTagLen]; + int i, minPrio; + + while (isspace(*tags)) tags++; + + i = 0; + while (*tags != '\0' && !isspace(*tags) && *tags != ':' && + i < kMaxTagLen) { + tagName[i++] = *tags++; + } + if (i == kMaxTagLen) { + TRACE("ERROR: env tag too long (%d chars max)\n", kMaxTagLen - 1); + return; + } + tagName[i] = '\0'; + + /* default priority, if there's no ":" part; also zero out '*' */ + minPrio = ANDROID_LOG_VERBOSE; + if (tagName[0] == '*' && tagName[1] == '\0') { + minPrio = ANDROID_LOG_DEBUG; + tagName[0] = '\0'; + } + + if (*tags == ':') { + tags++; + if (*tags >= '0' && *tags <= '9') { + if (*tags >= ('0' + ANDROID_LOG_SILENT)) minPrio = ANDROID_LOG_VERBOSE; - if (tagName[0] == '*' && tagName[1] == '\0') { - minPrio = ANDROID_LOG_DEBUG; - tagName[0] = '\0'; - } - - if (*tags == ':') { - tags++; - if (*tags >= '0' && *tags <= '9') { - if (*tags >= ('0' + ANDROID_LOG_SILENT)) - minPrio = ANDROID_LOG_VERBOSE; - else - minPrio = *tags - '\0'; - } else { - switch (*tags) { - case 'v': minPrio = ANDROID_LOG_VERBOSE; break; - case 'd': minPrio = ANDROID_LOG_DEBUG; break; - case 'i': minPrio = ANDROID_LOG_INFO; break; - case 'w': minPrio = ANDROID_LOG_WARN; break; - case 'e': minPrio = ANDROID_LOG_ERROR; break; - case 'f': minPrio = ANDROID_LOG_FATAL; break; - case 's': minPrio = ANDROID_LOG_SILENT; break; - default: minPrio = ANDROID_LOG_DEFAULT; break; - } - } - - tags++; - if (*tags != '\0' && !isspace(*tags)) { - TRACE("ERROR: garbage in tag env; expected whitespace\n"); - TRACE(" env='%s'\n", tags); - return; - } - } - - if (tagName[0] == 0) { - logState->globalMinPriority = minPrio; - TRACE("+++ global min prio %d\n", logState->globalMinPriority); - } else { - logState->tagSet[entry].minPriority = minPrio; - strcpy(logState->tagSet[entry].tag, tagName); - TRACE("+++ entry %d: %s:%d\n", - entry, - logState->tagSet[entry].tag, - logState->tagSet[entry].minPriority); - entry++; - } + else + minPrio = *tags - '\0'; + } else { + switch (*tags) { + case 'v': + minPrio = ANDROID_LOG_VERBOSE; + break; + case 'd': + minPrio = ANDROID_LOG_DEBUG; + break; + case 'i': + minPrio = ANDROID_LOG_INFO; + break; + case 'w': + minPrio = ANDROID_LOG_WARN; + break; + case 'e': + minPrio = ANDROID_LOG_ERROR; + break; + case 'f': + minPrio = ANDROID_LOG_FATAL; + break; + case 's': + minPrio = ANDROID_LOG_SILENT; + break; + default: + minPrio = ANDROID_LOG_DEFAULT; + break; + } } - } - - /* - * Taken from the long-dead utils/Log.cpp - */ - const char* fstr = getenv("ANDROID_PRINTF_LOG"); - LogFormat format; - if (fstr == NULL) { - format = FORMAT_BRIEF; - } else { - if (strcmp(fstr, "brief") == 0) - format = FORMAT_BRIEF; - else if (strcmp(fstr, "process") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "tag") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "thread") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "raw") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "time") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "long") == 0) - format = FORMAT_PROCESS; - else - format = (LogFormat) atoi(fstr); // really?! + tags++; + if (*tags != '\0' && !isspace(*tags)) { + TRACE("ERROR: garbage in tag env; expected whitespace\n"); + TRACE(" env='%s'\n", tags); + return; + } + } + + if (tagName[0] == 0) { + logState->globalMinPriority = minPrio; + TRACE("+++ global min prio %d\n", logState->globalMinPriority); + } else { + logState->tagSet[entry].minPriority = minPrio; + strcpy(logState->tagSet[entry].tag, tagName); + TRACE("+++ entry %d: %s:%d\n", entry, logState->tagSet[entry].tag, + logState->tagSet[entry].minPriority); + entry++; + } } - - logState->outputFormat = format; + } + + /* + * Taken from the long-dead utils/Log.cpp + */ + const char* fstr = getenv("ANDROID_PRINTF_LOG"); + LogFormat format; + if (fstr == NULL) { + format = FORMAT_BRIEF; + } else { + if (strcmp(fstr, "brief") == 0) + format = FORMAT_BRIEF; + else if (strcmp(fstr, "process") == 0) + format = FORMAT_PROCESS; + else if (strcmp(fstr, "tag") == 0) + format = FORMAT_PROCESS; + else if (strcmp(fstr, "thread") == 0) + format = FORMAT_PROCESS; + else if (strcmp(fstr, "raw") == 0) + format = FORMAT_PROCESS; + else if (strcmp(fstr, "time") == 0) + format = FORMAT_PROCESS; + else if (strcmp(fstr, "long") == 0) + format = FORMAT_PROCESS; + else + format = (LogFormat)atoi(fstr); // really?! + } + + logState->outputFormat = format; } /* * Return a human-readable string for the priority level. Always returns * a valid string. */ -static const char* getPriorityString(int priority) -{ - /* the first character of each string should be unique */ - static const char* priorityStrings[] = { - "Verbose", "Debug", "Info", "Warn", "Error", "Assert" - }; - int idx; - - idx = (int)priority - (int)ANDROID_LOG_VERBOSE; - if (idx < 0 || - idx >= (int)(sizeof(priorityStrings) / sizeof(priorityStrings[0]))) - return "?unknown?"; - return priorityStrings[idx]; +static const char* getPriorityString(int priority) { + /* the first character of each string should be unique */ + static const char* priorityStrings[] = { "Verbose", "Debug", "Info", + "Warn", "Error", "Assert" }; + int idx; + + idx = (int)priority - (int)ANDROID_LOG_VERBOSE; + if (idx < 0 || + idx >= (int)(sizeof(priorityStrings) / sizeof(priorityStrings[0]))) + return "?unknown?"; + return priorityStrings[idx]; } #if defined(_WIN32) @@ -330,227 +331,229 @@ static const char* getPriorityString(int priority) * WIN32 does not have writev(). * Make up something to replace it. */ -static ssize_t fake_writev(int fd, const struct iovec *iov, int iovcnt) { - ssize_t result = 0; - const struct iovec* end = iov + iovcnt; - for (; iov < end; iov++) { - ssize_t w = write(fd, iov->iov_base, iov->iov_len); - if (w != (ssize_t) iov->iov_len) { - if (w < 0) - return w; - return result + w; - } - result += w; +static ssize_t fake_writev(int fd, const struct iovec* iov, int iovcnt) { + ssize_t result = 0; + const struct iovec* end = iov + iovcnt; + for (; iov < end; iov++) { + ssize_t w = write(fd, iov->iov_base, iov->iov_len); + if (w != (ssize_t)iov->iov_len) { + if (w < 0) return w; + return result + w; } - return result; + result += w; + } + return result; } #define writev fake_writev #endif - /* * Write a filtered log message to stderr. * * Log format parsing taken from the long-dead utils/Log.cpp. */ -static void showLog(LogState *state, - int logPrio, const char* tag, const char* msg) -{ +static void showLog(LogState* state, int logPrio, const char* tag, + const char* msg) { #if !defined(_WIN32) - struct tm tmBuf; + struct tm tmBuf; #endif - struct tm* ptm; - char timeBuf[32]; - char prefixBuf[128], suffixBuf[128]; - char priChar; - time_t when; + struct tm* ptm; + char timeBuf[32]; + char prefixBuf[128], suffixBuf[128]; + char priChar; + time_t when; #if !defined(_WIN32) - pid_t pid, tid; + pid_t pid, tid; #else - uint32_t pid, tid; + uint32_t pid, tid; #endif - TRACE("LOG %d: %s %s", logPrio, tag, msg); - - priChar = getPriorityString(logPrio)[0]; - when = time(NULL); - pid = tid = getpid(); // find gettid()? - - /* - * Get the current date/time in pretty form - * - * It's often useful when examining a log with "less" to jump to - * a specific point in the file by searching for the date/time stamp. - * For this reason it's very annoying to have regexp meta characters - * in the time stamp. Don't use forward slashes, parenthesis, - * brackets, asterisks, or other special chars here. - */ + TRACE("LOG %d: %s %s", logPrio, tag, msg); + + priChar = getPriorityString(logPrio)[0]; + when = time(NULL); + pid = tid = getpid(); // find gettid()? + +/* + * Get the current date/time in pretty form + * + * It's often useful when examining a log with "less" to jump to + * a specific point in the file by searching for the date/time stamp. + * For this reason it's very annoying to have regexp meta characters + * in the time stamp. Don't use forward slashes, parenthesis, + * brackets, asterisks, or other special chars here. + */ #if !defined(_WIN32) - ptm = localtime_r(&when, &tmBuf); + ptm = localtime_r(&when, &tmBuf); #else - ptm = localtime(&when); + ptm = localtime(&when); #endif - //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm); - strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); + // strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm); + strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - /* - * Construct a buffer containing the log header and log message. - */ - size_t prefixLen, suffixLen; + /* + * Construct a buffer containing the log header and log message. + */ + size_t prefixLen, suffixLen; - switch (state->outputFormat) { + switch (state->outputFormat) { case FORMAT_TAG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s: ", priChar, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; + prefixLen = + snprintf(prefixBuf, sizeof(prefixBuf), "%c/%-8s: ", priChar, tag); + strcpy(suffixBuf, "\n"); + suffixLen = 1; + break; case FORMAT_PROCESS: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d) ", priChar, pid); - suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), - " (%s)\n", tag); - break; + prefixLen = + snprintf(prefixBuf, sizeof(prefixBuf), "%c(%5d) ", priChar, pid); + suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), " (%s)\n", tag); + break; case FORMAT_THREAD: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d:%5d) ", priChar, pid, tid); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; + prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "%c(%5d:%5d) ", + priChar, pid, tid); + strcpy(suffixBuf, "\n"); + suffixLen = 1; + break; case FORMAT_RAW: - prefixBuf[0] = 0; prefixLen = 0; - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; + prefixBuf[0] = 0; + prefixLen = 0; + strcpy(suffixBuf, "\n"); + suffixLen = 1; + break; case FORMAT_TIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%s %-8s\n\t", timeBuf, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; + prefixLen = + snprintf(prefixBuf, sizeof(prefixBuf), "%s %-8s\n\t", timeBuf, tag); + strcpy(suffixBuf, "\n"); + suffixLen = 1; + break; case FORMAT_THREADTIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%s %5d %5d %c %-8s \n\t", timeBuf, pid, tid, priChar, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; + prefixLen = + snprintf(prefixBuf, sizeof(prefixBuf), "%s %5d %5d %c %-8s \n\t", + timeBuf, pid, tid, priChar, tag); + strcpy(suffixBuf, "\n"); + suffixLen = 1; + break; case FORMAT_LONG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "[ %s %5d:%5d %c/%-8s ]\n", - timeBuf, pid, tid, priChar, tag); - strcpy(suffixBuf, "\n\n"); suffixLen = 2; - break; + prefixLen = + snprintf(prefixBuf, sizeof(prefixBuf), "[ %s %5d:%5d %c/%-8s ]\n", + timeBuf, pid, tid, priChar, tag); + strcpy(suffixBuf, "\n\n"); + suffixLen = 2; + break; default: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s(%5d): ", priChar, tag, pid); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - } - - /* - * Figure out how many lines there will be. - */ - const char* end = msg + strlen(msg); - size_t numLines = 0; - const char* p = msg; - while (p < end) { - if (*p++ == '\n') numLines++; + prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), + "%c/%-8s(%5d): ", priChar, tag, pid); + strcpy(suffixBuf, "\n"); + suffixLen = 1; + break; + } + + /* + * Figure out how many lines there will be. + */ + const char* end = msg + strlen(msg); + size_t numLines = 0; + const char* p = msg; + while (p < end) { + if (*p++ == '\n') numLines++; + } + if (p > msg && *(p - 1) != '\n') { + numLines++; + } + + /* + * Create an array of iovecs large enough to write all of + * the lines with a prefix and a suffix. + */ + const size_t INLINE_VECS = 64; + const size_t MAX_LINES = ((size_t)~0) / (3 * sizeof(struct iovec*)); + struct iovec stackVec[INLINE_VECS]; + struct iovec* vec = stackVec; + size_t numVecs; + + if (numLines > MAX_LINES) numLines = MAX_LINES; + + numVecs = numLines * 3; // 3 iovecs per line. + if (numVecs > INLINE_VECS) { + vec = (struct iovec*)malloc(sizeof(struct iovec) * numVecs); + if (vec == NULL) { + msg = "LOG: write failed, no memory"; + numVecs = INLINE_VECS; + numLines = numVecs / 3; + vec = stackVec; } - if (p > msg && *(p-1) != '\n') { - numLines++; + } + + /* + * Fill in the iovec pointers. + */ + p = msg; + struct iovec* v = vec; + int totalLen = 0; + while (numLines > 0 && p < end) { + if (prefixLen > 0) { + v->iov_base = prefixBuf; + v->iov_len = prefixLen; + totalLen += prefixLen; + v++; } - - /* - * Create an array of iovecs large enough to write all of - * the lines with a prefix and a suffix. - */ - const size_t INLINE_VECS = 64; - const size_t MAX_LINES = ((size_t)~0)/(3*sizeof(struct iovec*)); - struct iovec stackVec[INLINE_VECS]; - struct iovec* vec = stackVec; - size_t numVecs; - - if (numLines > MAX_LINES) - numLines = MAX_LINES; - - numVecs = numLines * 3; // 3 iovecs per line. - if (numVecs > INLINE_VECS) { - vec = (struct iovec*)malloc(sizeof(struct iovec)*numVecs); - if (vec == NULL) { - msg = "LOG: write failed, no memory"; - numVecs = INLINE_VECS; - numLines = numVecs / 3; - vec = stackVec; - } + const char* start = p; + while (p < end && *p != '\n') { + p++; } - - /* - * Fill in the iovec pointers. - */ - p = msg; - struct iovec* v = vec; - int totalLen = 0; - while (numLines > 0 && p < end) { - if (prefixLen > 0) { - v->iov_base = prefixBuf; - v->iov_len = prefixLen; - totalLen += prefixLen; - v++; - } - const char* start = p; - while (p < end && *p != '\n') { - p++; - } - if ((p-start) > 0) { - v->iov_base = (void*)start; - v->iov_len = p-start; - totalLen += p-start; - v++; - } - if (*p == '\n') p++; - if (suffixLen > 0) { - v->iov_base = suffixBuf; - v->iov_len = suffixLen; - totalLen += suffixLen; - v++; - } - numLines -= 1; + if ((p - start) > 0) { + v->iov_base = (void*)start; + v->iov_len = p - start; + totalLen += p - start; + v++; } - - /* - * Write the entire message to the log file with a single writev() call. - * We need to use this rather than a collection of printf()s on a FILE* - * because of multi-threading and multi-process issues. - * - * If the file was not opened with O_APPEND, this will produce interleaved - * output when called on the same file from multiple processes. - * - * If the file descriptor is actually a network socket, the writev() - * call may return with a partial write. Putting the writev() call in - * a loop can result in interleaved data. This can be alleviated - * somewhat by wrapping the writev call in the Mutex. - */ - - for(;;) { - int cc = writev(fileno(stderr), vec, v-vec); - - if (cc == totalLen) break; - - if (cc < 0) { - if(errno == EINTR) continue; - - /* can't really log the failure; for now, throw out a stderr */ - fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); - break; - } else { - /* shouldn't happen when writing to file or tty */ - fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", cc, totalLen); - break; - } + if (*p == '\n') p++; + if (suffixLen > 0) { + v->iov_base = suffixBuf; + v->iov_len = suffixLen; + totalLen += suffixLen; + v++; } + numLines -= 1; + } + + /* + * Write the entire message to the log file with a single writev() call. + * We need to use this rather than a collection of printf()s on a FILE* + * because of multi-threading and multi-process issues. + * + * If the file was not opened with O_APPEND, this will produce interleaved + * output when called on the same file from multiple processes. + * + * If the file descriptor is actually a network socket, the writev() + * call may return with a partial write. Putting the writev() call in + * a loop can result in interleaved data. This can be alleviated + * somewhat by wrapping the writev call in the Mutex. + */ + + for (;;) { + int cc = writev(fileno(stderr), vec, v - vec); + + if (cc == totalLen) break; + + if (cc < 0) { + if (errno == EINTR) continue; + + /* can't really log the failure; for now, throw out a stderr */ + fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); + break; + } else { + /* shouldn't happen when writing to file or tty */ + fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", cc, totalLen); + break; + } + } - /* if we allocated storage for the iovecs, free it */ - if (vec != stackVec) - free(vec); + /* if we allocated storage for the iovecs, free it */ + if (vec != stackVec) free(vec); } - /* * Receive a log message. We happen to know that "vector" has three parts: * @@ -558,103 +561,98 @@ static void showLog(LogState *state, * tag (N bytes -- null-terminated ASCII string) * message (N bytes -- null-terminated ASCII string) */ -static ssize_t logWritev(int fd, const struct iovec* vector, int count) -{ - LogState* state; - - /* Make sure that no-one frees the LogState while we're using it. - * Also guarantees that only one thread is in showLog() at a given - * time (if it matters). - */ - lock(); - - state = fdToLogState(fd); - if (state == NULL) { - errno = EBADF; - goto error; +static ssize_t logWritev(int fd, const struct iovec* vector, int count) { + LogState* state; + + /* Make sure that no-one frees the LogState while we're using it. + * Also guarantees that only one thread is in showLog() at a given + * time (if it matters). + */ + lock(); + + state = fdToLogState(fd); + if (state == NULL) { + errno = EBADF; + goto error; + } + + if (state->isBinary) { + TRACE("%s: ignoring binary log\n", state->debugName); + goto bail; + } + + if (count != 3) { + TRACE("%s: writevLog with count=%d not expected\n", state->debugName, count); + goto error; + } + + /* pull out the three fields */ + int logPrio = *(const char*)vector[0].iov_base; + const char* tag = (const char*)vector[1].iov_base; + const char* msg = (const char*)vector[2].iov_base; + + /* see if this log tag is configured */ + int i; + int minPrio = state->globalMinPriority; + for (i = 0; i < kTagSetSize; i++) { + if (state->tagSet[i].minPriority == ANDROID_LOG_UNKNOWN) + break; /* reached end of configured values */ + + if (strcmp(state->tagSet[i].tag, tag) == 0) { + // TRACE("MATCH tag '%s'\n", tag); + minPrio = state->tagSet[i].minPriority; + break; } + } - if (state->isBinary) { - TRACE("%s: ignoring binary log\n", state->debugName); - goto bail; - } - - if (count != 3) { - TRACE("%s: writevLog with count=%d not expected\n", - state->debugName, count); - goto error; - } - - /* pull out the three fields */ - int logPrio = *(const char*)vector[0].iov_base; - const char* tag = (const char*) vector[1].iov_base; - const char* msg = (const char*) vector[2].iov_base; - - /* see if this log tag is configured */ - int i; - int minPrio = state->globalMinPriority; - for (i = 0; i < kTagSetSize; i++) { - if (state->tagSet[i].minPriority == ANDROID_LOG_UNKNOWN) - break; /* reached end of configured values */ - - if (strcmp(state->tagSet[i].tag, tag) == 0) { - //TRACE("MATCH tag '%s'\n", tag); - minPrio = state->tagSet[i].minPriority; - break; - } - } - - if (logPrio >= minPrio) { - showLog(state, logPrio, tag, msg); - } else { - //TRACE("+++ NOLOG(%d): %s %s", logPrio, tag, msg); - } + if (logPrio >= minPrio) { + showLog(state, logPrio, tag, msg); + } else { + // TRACE("+++ NOLOG(%d): %s %s", logPrio, tag, msg); + } bail: - unlock(); - int len = 0; - for (i = 0; i < count; ++i) { - len += vector[i].iov_len; - } - return len; + unlock(); + int len = 0; + for (i = 0; i < count; ++i) { + len += vector[i].iov_len; + } + return len; error: - unlock(); - return -1; + unlock(); + return -1; } /* * Free up our state and close the fake descriptor. */ -static int logClose(int fd) -{ - deleteFakeFd(fd); - return 0; +static int logClose(int fd) { + deleteFakeFd(fd); + return 0; } /* * Open a log output device and return a fake fd. */ -static int logOpen(const char* pathName, int flags __unused) -{ - LogState *logState; - int fd = -1; - - lock(); - - logState = createLogState(); - if (logState != NULL) { - configureInitialState(pathName, logState); - fd = logState->fakeFd; - } else { - errno = ENFILE; - } +static int logOpen(const char* pathName, int flags __unused) { + LogState* logState; + int fd = -1; - unlock(); + lock(); - return fd; -} + logState = createLogState(); + if (logState != NULL) { + configureInitialState(pathName, logState); + fd = logState->fakeFd; + } else { + errno = ENFILE; + } + + unlock(); + return fd; +} /* * Runtime redirection. If this binary is running in the simulator, @@ -662,38 +660,36 @@ static int logOpen(const char* pathName, int flags __unused) * outside of the simulator, write the log messages to stderr. */ -static int (*redirectOpen)(const char *pathName, int flags) = NULL; +static int (*redirectOpen)(const char* pathName, int flags) = NULL; static int (*redirectClose)(int fd) = NULL; -static ssize_t (*redirectWritev)(int fd, const struct iovec* vector, int count) - = NULL; - -static void setRedirects() -{ - const char *ws; - - /* Wrapsim sets this environment variable on children that it's - * created using its LD_PRELOAD wrapper. - */ - ws = getenv("ANDROID_WRAPSIM"); - if (ws != NULL && strcmp(ws, "1") == 0) { - /* We're running inside wrapsim, so we can just write to the device. */ - redirectOpen = (int (*)(const char *pathName, int flags))open; - redirectClose = close; - redirectWritev = writev; - } else { - /* There's no device to delegate to; handle the logging ourselves. */ - redirectOpen = logOpen; - redirectClose = logClose; - redirectWritev = logWritev; - } +static ssize_t (*redirectWritev)(int fd, const struct iovec* vector, + int count) = NULL; + +static void setRedirects() { + const char* ws; + + /* Wrapsim sets this environment variable on children that it's + * created using its LD_PRELOAD wrapper. + */ + ws = getenv("ANDROID_WRAPSIM"); + if (ws != NULL && strcmp(ws, "1") == 0) { + /* We're running inside wrapsim, so we can just write to the device. */ + redirectOpen = (int (*)(const char* pathName, int flags))open; + redirectClose = close; + redirectWritev = writev; + } else { + /* There's no device to delegate to; handle the logging ourselves. */ + redirectOpen = logOpen; + redirectClose = logClose; + redirectWritev = logWritev; + } } -LIBLOG_HIDDEN int fakeLogOpen(const char *pathName, int flags) -{ - if (redirectOpen == NULL) { - setRedirects(); - } - return redirectOpen(pathName, flags); +LIBLOG_HIDDEN int fakeLogOpen(const char* pathName, int flags) { + if (redirectOpen == NULL) { + setRedirects(); + } + return redirectOpen(pathName, flags); } /* @@ -707,43 +703,37 @@ LIBLOG_HIDDEN int fakeLogOpen(const char *pathName, int flags) * call is in the exit handler. Logging can continue in the exit handler to * help debug HOST tools ... */ -LIBLOG_HIDDEN int fakeLogClose(int fd) -{ - /* Assume that open() was called first. */ - return redirectClose(fd); +LIBLOG_HIDDEN int fakeLogClose(int fd) { + /* Assume that open() was called first. */ + return redirectClose(fd); } -LIBLOG_HIDDEN ssize_t fakeLogWritev(int fd, - const struct iovec* vector, int count) -{ - /* Assume that open() was called first. */ - return redirectWritev(fd, vector, count); +LIBLOG_HIDDEN ssize_t fakeLogWritev(int fd, const struct iovec* vector, + int count) { + /* Assume that open() was called first. */ + return redirectWritev(fd, vector, count); } -LIBLOG_HIDDEN ssize_t __send_log_msg(char *buf __unused, - size_t buf_size __unused) -{ - return -ENODEV; +LIBLOG_HIDDEN ssize_t __send_log_msg(char* buf __unused, + size_t buf_size __unused) { + return -ENODEV; } LIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio, - const char *tag __unused, - int def) -{ - int logLevel = def; - return logLevel >= 0 && prio >= logLevel; + const char* tag __unused, + int def) { + int logLevel = def; + return logLevel >= 0 && prio >= logLevel; } LIBLOG_ABI_PUBLIC int __android_log_is_loggable_len(int prio, - const char *tag __unused, + const char* tag __unused, size_t len __unused, - int def) -{ - int logLevel = def; - return logLevel >= 0 && prio >= logLevel; + int def) { + int logLevel = def; + return logLevel >= 0 && prio >= logLevel; } -LIBLOG_ABI_PRIVATE int __android_log_is_debuggable() -{ - return 1; +LIBLOG_ABI_PRIVATE int __android_log_is_debuggable() { + return 1; } diff --git a/liblog/fake_log_device.h b/liblog/fake_log_device.h index 4529b5d95..462d026b2 100644 --- a/liblog/fake_log_device.h +++ b/liblog/fake_log_device.h @@ -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 diff --git a/liblog/fake_writer.c b/liblog/fake_writer.c index 2350673e1..c280e3f49 100644 --- a/liblog/fake_writer.c +++ b/liblog/fake_writer.c @@ -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; - - 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); - } + 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; } - 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; - - 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; - } - - 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; - } - - return ret; +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; + } + + len = 0; + for (i = 0; i < nr; ++i) { + len += vec[i].iov_len; + } + + 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; + } + + return ret; } diff --git a/liblog/include/android/log.h b/liblog/include/android/log.h index 9f198fe87..15fba8b72 100644 --- a/liblog/include/android/log.h +++ b/liblog/include/android/log.h @@ -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 ; diff --git a/liblog/include/log/event_tag_map.h b/liblog/include/log/event_tag_map.h index e57e47bb2..8dd91572c 100644 --- a/liblog/include/log/event_tag_map.h +++ b/liblog/include/log/event_tag_map.h @@ -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 diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h index db2221160..6758c8415 100644 --- a/liblog/include/log/log.h +++ b/liblog/include/log/log.h @@ -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 */ - - /* 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, + /* 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, } 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 diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h index 31d49b2f9..55953fcad 100644 --- a/liblog/include/log/log_event_list.h +++ b/liblog/include/log/log_event_list.h @@ -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; - -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; - -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; - } - - /* To allow above C calls to use this class as parameter */ - operator android_log_context() const { return ctx; } - - 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; - } - - 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 <<(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 <<(const char* value) { - int retval = android_log_write_string8(ctx, value); - if (retval < 0) ret = retval; - return *this; - } + friend class __android_log_event_list; + + 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; + + 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; + } + + /* To allow above C calls to use this class as parameter */ + operator android_log_context() const { + return ctx; + } + + 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; + } + + 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<<(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<<(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; - } - - 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; - } - - /* - * 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 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, size_t len) { - int retval = android_log_write_string8_len(ctx, value, len); - if (retval < 0) ret = retval; - return ret >= 0; - } + 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 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. + */ + + 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 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; + } #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 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 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; + } #endif - 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; } - - 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 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; + } + + 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 diff --git a/liblog/include/log/log_frontend.h b/liblog/include/log/log_frontend.h index 5efa548af..8a69f5efc 100644 --- a/liblog/include/log/log_frontend.h +++ b/liblog/include/log/log_frontend.h @@ -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); diff --git a/liblog/include/log/log_id.h b/liblog/include/log/log_id.h index 3078e4eb1..7bfa2770b 100644 --- a/liblog/include/log/log_id.h +++ b/liblog/include/log/log_id.h @@ -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 diff --git a/liblog/include/log/log_main.h b/liblog/include/log/log_main.h index f45397ab8..da1615828 100644 --- a/liblog/include/log/log_main.h +++ b/liblog/include/log/log_main.h @@ -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 diff --git a/liblog/include/log/log_radio.h b/liblog/include/log/log_radio.h index 430e5229b..bd629fe35 100644 --- a/liblog/include/log/log_radio.h +++ b/liblog/include/log/log_radio.h @@ -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 */ diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h index 6a44b5685..d118563be 100644 --- a/liblog/include/log/log_read.h +++ b/liblog/include/log/log_read.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); - } - 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; + /* 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); } - 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 */ diff --git a/liblog/include/log/log_system.h b/liblog/include/log/log_system.h index 394a10645..3b5ae2277 100644 --- a/liblog/include/log/log_system.h +++ b/liblog/include/log/log_system.h @@ -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 */ diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h index 900dc1b94..5f70f7d4c 100644 --- a/liblog/include/log/log_time.h +++ b/liblog/include/log/log_time.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; - - 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; - } + 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; + + 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); - } - - /* 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); - } + 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); + } #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 diff --git a/liblog/include/log/logprint.h b/liblog/include/log/logprint.h index 5b99c3ce1..ca58bc7e0 100644 --- a/liblog/include/log/logprint.h +++ b/liblog/include/log/logprint.h @@ -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 } diff --git a/liblog/include/log/uio.h b/liblog/include/log/uio.h index 7059da5f7..a492baefe 100644 --- a/liblog/include/log/uio.h +++ b/liblog/include/log/uio.h @@ -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 */ - diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h index 9f81b1f06..e3ccfcff2 100644 --- a/liblog/include/private/android_logger.h +++ b/liblog/include/private/android_logger.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 diff --git a/liblog/local_logger.c b/liblog/local_logger.c index d504342ea..758905fd4 100644 --- a/liblog/local_logger.c +++ b/liblog/local_logger.c @@ -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; diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c index 9ac1d30eb..59ea5ef13 100644 --- a/liblog/log_event_list.c +++ b/liblog/log_event_list.c @@ -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; - - 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; + 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; + + 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; - - 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; +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; + + return (android_log_context)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; +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; } LIBLOG_ABI_PUBLIC int android_log_write_list_begin(android_log_context ctx) { - 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; + 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; } -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; - - 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; + 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; } -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; - - 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; + 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; } 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; - - 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; - } - } - 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; + 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; + } + 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; } 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; - - 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; + 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; } LIBLOG_ABI_PUBLIC int android_log_write_list_end(android_log_context ctx) { - 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]; + 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 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; - - 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; - } - 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); + android_log_context_internal* context; + const char* msg; + ssize_t len; + + 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; + } + 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); } 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; - - 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; - } - msg += sizeof(uint8_t) + sizeof(uint8_t); - } - *buffer = msg; - return 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; + } + 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; } /* * 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; - - context = (android_log_context_internal *)ctx; - - 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; - } - 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; - } + android_log_context ctx, int peek) { + android_log_list_element elem; + unsigned pos; + android_log_context_internal* context; + + context = (android_log_context_internal*)ctx; + + 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; + } + 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; } - 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) { + } 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) { 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; - } + 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; + } + 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; } - return elem; + 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); } diff --git a/liblog/log_event_write.c b/liblog/log_event_write.c index 14d648273..45a6f3767 100644 --- a/liblog/log_event_write.c +++ b/liblog/log_event_write.c @@ -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; } diff --git a/liblog/log_portability.h b/liblog/log_portability.h index 3ad20601e..88805c75f 100644 --- a/liblog/log_portability.h +++ b/liblog/log_portability.h @@ -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__ */ diff --git a/liblog/log_ratelimit.cpp b/liblog/log_ratelimit.cpp index dfd4b8fcc..33770dda4 100644 --- a/liblog/log_ratelimit.cpp +++ b/liblog/log_ratelimit.cpp @@ -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; } diff --git a/liblog/log_time.cpp b/liblog/log_time.cpp index dfd2d443a..ae376be57 100644 --- a/liblog/log_time.cpp +++ b/liblog/log_time.cpp @@ -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 *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 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; #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 (*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); + ptm = localtime_r(&now, &tmBuf); #else - ptm = localtime(&now); + ptm = localtime(&now); #endif - } else + } 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; - } + { + 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; } - f = cp = e; - ++f; + } + 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; - } + if (ret) { + tv_sec = mktime(ptm); + return ret; + } - // Upon error, place a known value into the class, the current time. +// Upon error, place a known value into the class, the current time. #ifdef __linux__ - *this = log_time(CLOCK_REALTIME); + *this = log_time(CLOCK_REALTIME); #else - time(&now); - tv_sec = now; - tv_nsec = 0; + time(&now); + tv_sec = now; + tv_nsec = 0; #endif - return ret; + 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; - } - - 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; +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; + + 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; - } - - 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; +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; + + 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; } diff --git a/liblog/logd_reader.c b/liblog/logd_reader.c index a6c3f7a44..600f4bb0b 100644 --- a/liblog/logd_reader.c +++ b/liblog/logd_reader.c @@ -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> @@ -41,87 +41,86 @@ #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 logdVersion(struct android_log_logger *logger, - struct android_log_transport_context *transp); -static int logdRead(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp, - struct log_msg *log_msg); -static int logdPoll(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp); -static void logdClose(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp); -static int logdClear(struct android_log_logger *logger, - struct android_log_transport_context *transp); -static ssize_t logdSetSize(struct android_log_logger *logger, - struct android_log_transport_context *transp, +static int logdVersion(struct android_log_logger* logger, + struct android_log_transport_context* transp); +static int logdRead(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp, + struct log_msg* log_msg); +static int logdPoll(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp); +static void logdClose(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp); +static int logdClear(struct android_log_logger* logger, + struct android_log_transport_context* transp); +static ssize_t logdSetSize(struct android_log_logger* logger, + struct android_log_transport_context* transp, size_t size); -static ssize_t logdGetSize(struct android_log_logger *logger, - struct android_log_transport_context *transp); -static ssize_t logdGetReadableSize(struct android_log_logger *logger, - struct android_log_transport_context *transp); -static ssize_t logdGetPrune(struct android_log_logger_list *logger, - struct android_log_transport_context *transp, - char *buf, size_t len); -static ssize_t logdSetPrune(struct android_log_logger_list *logger, - struct android_log_transport_context *transp, - char *buf, size_t len); -static ssize_t logdGetStats(struct android_log_logger_list *logger, - struct android_log_transport_context *transp, - char *buf, size_t len); +static ssize_t logdGetSize(struct android_log_logger* logger, + struct android_log_transport_context* transp); +static ssize_t logdGetReadableSize(struct android_log_logger* logger, + struct android_log_transport_context* transp); +static ssize_t logdGetPrune(struct android_log_logger_list* logger, + struct android_log_transport_context* transp, + char* buf, size_t len); +static ssize_t logdSetPrune(struct android_log_logger_list* logger, + struct android_log_transport_context* transp, + char* buf, size_t len); +static ssize_t logdGetStats(struct android_log_logger_list* logger, + struct android_log_transport_context* transp, + char* buf, size_t len); LIBLOG_HIDDEN struct android_log_transport_read logdLoggerRead = { - .node = { &logdLoggerRead.node, &logdLoggerRead.node }, - .name = "logd", - .available = logdAvailable, - .version = logdVersion, - .read = logdRead, - .poll = logdPoll, - .close = logdClose, - .clear = logdClear, - .getSize = logdGetSize, - .setSize = logdSetSize, - .getReadableSize = logdGetReadableSize, - .getPrune = logdGetPrune, - .setPrune = logdSetPrune, - .getStats = logdGetStats, + .node = { &logdLoggerRead.node, &logdLoggerRead.node }, + .name = "logd", + .available = logdAvailable, + .version = logdVersion, + .read = logdRead, + .poll = logdPoll, + .close = logdClose, + .clear = logdClear, + .getSize = logdGetSize, + .setSize = logdSetSize, + .getReadableSize = logdGetReadableSize, + .getPrune = logdGetPrune, + .setPrune = logdSetPrune, + .getStats = logdGetStats, }; -static int logdAvailable(log_id_t logId) -{ - if (logId >= LOG_ID_MAX) { - return -EINVAL; - } - if (logId == LOG_ID_SECURITY) { - uid_t uid = __android_log_uid(); - if (uid != AID_SYSTEM) { - return -EPERM; - } - } - if (access("/dev/socket/logdw", W_OK) == 0) { - return 0; +static int logdAvailable(log_id_t logId) { + if (logId >= LOG_ID_MAX) { + return -EINVAL; + } + if (logId == LOG_ID_SECURITY) { + uid_t uid = __android_log_uid(); + if (uid != AID_SYSTEM) { + return -EPERM; } - return -EBADF; + } + if (access("/dev/socket/logdw", W_OK) == 0) { + return 0; + } + return -EBADF; } /* Private copy of ../libcutils/socket_local_client.c prevent library loops */ #if defined(_WIN32) -LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type) -{ - errno = ENOSYS; - return -ENOSYS; +LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId, + int type) { + errno = ENOSYS; + return -ENOSYS; } #else /* !_WIN32 */ -#include <sys/socket.h> -#include <sys/un.h> #include <sys/select.h> +#include <sys/socket.h> #include <sys/types.h> +#include <sys/un.h> /* Private copy of ../libcutils/socket_local.h prevent library loops */ #define FILESYSTEM_SOCKET_PREFIX "/tmp/" @@ -131,78 +130,77 @@ LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type) #define LISTEN_BACKLOG 4 /* Documented in header file. */ -LIBLOG_WEAK int socket_make_sockaddr_un(const char *name, int namespaceId, - struct sockaddr_un *p_addr, - socklen_t *alen) -{ - memset (p_addr, 0, sizeof (*p_addr)); - size_t namelen; - - switch (namespaceId) { +LIBLOG_WEAK int socket_make_sockaddr_un(const char* name, int namespaceId, + struct sockaddr_un* p_addr, + socklen_t* alen) { + memset(p_addr, 0, sizeof(*p_addr)); + size_t namelen; + + switch (namespaceId) { case ANDROID_SOCKET_NAMESPACE_ABSTRACT: #if defined(__linux__) - namelen = strlen(name); + namelen = strlen(name); - /* Test with length +1 for the *initial* '\0'. */ - if ((namelen + 1) > sizeof(p_addr->sun_path)) { - goto error; - } + /* Test with length +1 for the *initial* '\0'. */ + if ((namelen + 1) > sizeof(p_addr->sun_path)) { + goto error; + } - /* - * Note: The path in this case is *not* supposed to be - * '\0'-terminated. ("man 7 unix" for the gory details.) - */ + /* + * Note: The path in this case is *not* supposed to be + * '\0'-terminated. ("man 7 unix" for the gory details.) + */ - p_addr->sun_path[0] = 0; - memcpy(p_addr->sun_path + 1, name, namelen); + p_addr->sun_path[0] = 0; + memcpy(p_addr->sun_path + 1, name, namelen); #else - /* this OS doesn't have the Linux abstract namespace */ + /* this OS doesn't have the Linux abstract namespace */ - namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX); - /* unix_path_max appears to be missing on linux */ - if (namelen > sizeof(*p_addr) - - offsetof(struct sockaddr_un, sun_path) - 1) { - goto error; - } + namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX); + /* unix_path_max appears to be missing on linux */ + if (namelen > + sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) { + goto error; + } - strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX); - strcat(p_addr->sun_path, name); + strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX); + strcat(p_addr->sun_path, name); #endif - break; + break; case ANDROID_SOCKET_NAMESPACE_RESERVED: - namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX); - /* unix_path_max appears to be missing on linux */ - if (namelen > sizeof(*p_addr) - - offsetof(struct sockaddr_un, sun_path) - 1) { - goto error; - } + namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX); + /* unix_path_max appears to be missing on linux */ + if (namelen > + sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) { + goto error; + } - strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX); - strcat(p_addr->sun_path, name); - break; + strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX); + strcat(p_addr->sun_path, name); + break; case ANDROID_SOCKET_NAMESPACE_FILESYSTEM: - namelen = strlen(name); - /* unix_path_max appears to be missing on linux */ - if (namelen > sizeof(*p_addr) - - offsetof(struct sockaddr_un, sun_path) - 1) { - goto error; - } + namelen = strlen(name); + /* unix_path_max appears to be missing on linux */ + if (namelen > + sizeof(*p_addr) - offsetof(struct sockaddr_un, sun_path) - 1) { + goto error; + } - strcpy(p_addr->sun_path, name); - break; + strcpy(p_addr->sun_path, name); + break; default: - /* invalid namespace id */ - return -1; - } + /* invalid namespace id */ + return -1; + } - p_addr->sun_family = AF_LOCAL; - *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1; - return 0; + p_addr->sun_family = AF_LOCAL; + *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1; + return 0; error: - return -1; + return -1; } /** @@ -212,466 +210,441 @@ error: * * Used by AndroidSocketImpl */ -LIBLOG_WEAK int socket_local_client_connect(int fd, const char *name, - int namespaceId, int type __unused) -{ - struct sockaddr_un addr; - socklen_t alen; - int err; +LIBLOG_WEAK int socket_local_client_connect(int fd, const char* name, + int namespaceId, int type __unused) { + struct sockaddr_un addr; + socklen_t alen; + int err; - err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); + err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); - if (err < 0) { - goto error; - } + if (err < 0) { + goto error; + } - if(connect(fd, (struct sockaddr *) &addr, alen) < 0) { - goto error; - } + if (connect(fd, (struct sockaddr*)&addr, alen) < 0) { + goto error; + } - return fd; + return fd; error: - return -1; + return -1; } /** * connect to peer named "name" * returns fd or -1 on error */ -LIBLOG_WEAK int socket_local_client(const char *name, int namespaceId, int type) -{ - int s; +LIBLOG_WEAK int socket_local_client(const char* name, int namespaceId, + int type) { + int s; - s = socket(AF_LOCAL, type, 0); - if(s < 0) return -1; + s = socket(AF_LOCAL, type, 0); + if (s < 0) return -1; - if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) { - close(s); - return -1; - } + if (0 > socket_local_client_connect(s, name, namespaceId, type)) { + close(s); + return -1; + } - return s; + return s; } #endif /* !_WIN32 */ /* End of ../libcutils/socket_local_client.c */ /* worker for sending the command to the logger */ -static ssize_t send_log_msg(struct android_log_logger *logger, - const char *msg, char *buf, size_t buf_size) -{ - ssize_t ret; - size_t len; - char *cp; - int errno_save = 0; - int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_STREAM); - if (sock < 0) { - return sock; - } - - if (msg) { - snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned) -1); - } +static ssize_t send_log_msg(struct android_log_logger* logger, const char* msg, + char* buf, size_t buf_size) { + ssize_t ret; + size_t len; + char* cp; + int errno_save = 0; + int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_STREAM); + if (sock < 0) { + return sock; + } - len = strlen(buf) + 1; - ret = TEMP_FAILURE_RETRY(write(sock, buf, len)); - if (ret <= 0) { - goto done; - } + if (msg) { + snprintf(buf, buf_size, msg, logger ? logger->logId : (unsigned)-1); + } - len = buf_size; - cp = buf; - while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) { - struct pollfd p; + len = strlen(buf) + 1; + ret = TEMP_FAILURE_RETRY(write(sock, buf, len)); + if (ret <= 0) { + goto done; + } - if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) { - break; - } + len = buf_size; + cp = buf; + while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) { + struct pollfd p; - len -= ret; - cp += ret; + if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) { + break; + } - memset(&p, 0, sizeof(p)); - p.fd = sock; - p.events = POLLIN; + len -= ret; + cp += ret; - /* Give other side 20ms to refill pipe */ - ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20)); + memset(&p, 0, sizeof(p)); + p.fd = sock; + p.events = POLLIN; - if (ret <= 0) { - break; - } + /* Give other side 20ms to refill pipe */ + ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20)); - if (!(p.revents & POLLIN)) { - ret = 0; - break; - } + if (ret <= 0) { + break; } - if (ret >= 0) { - ret += buf_size - len; + if (!(p.revents & POLLIN)) { + ret = 0; + break; } + } + + if (ret >= 0) { + ret += buf_size - len; + } done: - if ((ret == -1) && errno) { - errno_save = errno; - } - close(sock); - if (errno_save) { - errno = errno_save; - } - return ret; + if ((ret == -1) && errno) { + errno_save = errno; + } + close(sock); + if (errno_save) { + errno = errno_save; + } + return ret; } -LIBLOG_HIDDEN ssize_t __send_log_msg(char *buf, size_t buf_size) -{ - return send_log_msg(NULL, NULL, buf, buf_size); +LIBLOG_HIDDEN ssize_t __send_log_msg(char* buf, size_t buf_size) { + return send_log_msg(NULL, NULL, buf, buf_size); } -static int check_log_success(char *buf, ssize_t ret) -{ - if (ret < 0) { - return ret; - } +static int check_log_success(char* buf, ssize_t ret) { + if (ret < 0) { + return ret; + } - if (strncmp(buf, "success", 7)) { - errno = EINVAL; - return -1; - } + if (strncmp(buf, "success", 7)) { + errno = EINVAL; + return -1; + } - return 0; + return 0; } -static int logdClear(struct android_log_logger *logger, - struct android_log_transport_context *transp __unused) -{ - char buf[512]; +static int logdClear(struct android_log_logger* logger, + struct android_log_transport_context* transp __unused) { + char buf[512]; - return check_log_success(buf, - send_log_msg(logger, "clear %d", buf, sizeof(buf))); + return check_log_success(buf, + send_log_msg(logger, "clear %d", buf, sizeof(buf))); } /* returns the total size of the log's ring buffer */ -static ssize_t logdGetSize(struct android_log_logger *logger, - struct android_log_transport_context *transp __unused) -{ - char buf[512]; - - ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf)); - if (ret < 0) { - return ret; - } +static ssize_t logdGetSize(struct android_log_logger* logger, + struct android_log_transport_context* transp __unused) { + char buf[512]; - if ((buf[0] < '0') || ('9' < buf[0])) { - return -1; - } + ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf)); + if (ret < 0) { + return ret; + } + + if ((buf[0] < '0') || ('9' < buf[0])) { + return -1; + } - return atol(buf); + return atol(buf); } -static ssize_t logdSetSize( - struct android_log_logger *logger, - struct android_log_transport_context *transp __unused, - size_t size) -{ - char buf[512]; +static ssize_t logdSetSize(struct android_log_logger* logger, + struct android_log_transport_context* transp __unused, + size_t size) { + char buf[512]; - snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size); + snprintf(buf, sizeof(buf), "setLogSize %d %zu", logger->logId, size); - return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf))); + return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf))); } /* * returns the readable size of the log's ring buffer (that is, amount of the * log consumed) */ -static ssize_t logdGetReadableSize( - struct android_log_logger *logger, - struct android_log_transport_context *transp __unused) -{ - char buf[512]; - - ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf)); - if (ret < 0) { - return ret; - } +static ssize_t logdGetReadableSize(struct android_log_logger* logger, + struct android_log_transport_context* transp + __unused) { + char buf[512]; - if ((buf[0] < '0') || ('9' < buf[0])) { - return -1; - } + ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf)); + if (ret < 0) { + return ret; + } + + if ((buf[0] < '0') || ('9' < buf[0])) { + return -1; + } - return atol(buf); + return atol(buf); } /* * returns the logger version */ -static int logdVersion( - struct android_log_logger *logger __unused, - struct android_log_transport_context *transp __unused) -{ - uid_t uid = __android_log_uid(); - return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4; +static int logdVersion(struct android_log_logger* logger __unused, + struct android_log_transport_context* transp __unused) { + uid_t uid = __android_log_uid(); + return ((uid != AID_ROOT) && (uid != AID_LOG) && (uid != AID_SYSTEM)) ? 3 : 4; } /* * returns statistics */ -static ssize_t logdGetStats(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp __unused, - char *buf, size_t len) -{ - struct android_log_logger *logger; - char *cp = buf; - size_t remaining = len; - size_t n; - - n = snprintf(cp, remaining, "getStatistics"); +static ssize_t logdGetStats(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp __unused, + char* buf, size_t len) { + struct android_log_logger* logger; + char* cp = buf; + size_t remaining = len; + size_t n; + + n = snprintf(cp, remaining, "getStatistics"); + n = min(n, remaining); + remaining -= n; + cp += n; + + logger_for_each(logger, logger_list) { + n = snprintf(cp, remaining, " %d", logger->logId); n = min(n, remaining); remaining -= n; cp += n; + } - logger_for_each(logger, logger_list) { - n = snprintf(cp, remaining, " %d", logger->logId); - n = min(n, remaining); - remaining -= n; - cp += n; - } - - if (logger_list->pid) { - snprintf(cp, remaining, " pid=%u", logger_list->pid); - } + if (logger_list->pid) { + snprintf(cp, remaining, " pid=%u", logger_list->pid); + } - return send_log_msg(NULL, NULL, buf, len); + return send_log_msg(NULL, NULL, buf, len); } -static ssize_t logdGetPrune( - struct android_log_logger_list *logger_list __unused, - struct android_log_transport_context *transp __unused, - char *buf, size_t len) -{ - return send_log_msg(NULL, "getPruneList", buf, len); +static ssize_t logdGetPrune(struct android_log_logger_list* logger_list __unused, + struct android_log_transport_context* transp __unused, + char* buf, size_t len) { + return send_log_msg(NULL, "getPruneList", buf, len); } -static ssize_t logdSetPrune( - struct android_log_logger_list *logger_list __unused, - struct android_log_transport_context *transp __unused, - char *buf, size_t len) -{ - const char cmd[] = "setPruneList "; - const size_t cmdlen = sizeof(cmd) - 1; +static ssize_t logdSetPrune(struct android_log_logger_list* logger_list __unused, + struct android_log_transport_context* transp __unused, + char* buf, size_t len) { + const char cmd[] = "setPruneList "; + const size_t cmdlen = sizeof(cmd) - 1; - if (strlen(buf) > (len - cmdlen)) { - return -ENOMEM; /* KISS */ - } - memmove(buf + cmdlen, buf, len - cmdlen); - buf[len - 1] = '\0'; - memcpy(buf, cmd, cmdlen); + if (strlen(buf) > (len - cmdlen)) { + return -ENOMEM; /* KISS */ + } + memmove(buf + cmdlen, buf, len - cmdlen); + buf[len - 1] = '\0'; + memcpy(buf, cmd, cmdlen); - return check_log_success(buf, send_log_msg(NULL, NULL, buf, len)); + return check_log_success(buf, send_log_msg(NULL, NULL, buf, len)); } - -static void caught_signal(int signum __unused) -{ +static void caught_signal(int signum __unused) { } -static int logdOpen(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp) -{ - struct android_log_logger *logger; - struct sigaction ignore; - struct sigaction old_sigaction; - unsigned int old_alarm = 0; - char buffer[256], *cp, c; - int e, ret, remaining, sock; - - if (!logger_list) { - return -EINVAL; - } - - sock = atomic_load(&transp->context.sock); - if (sock > 0) { - return sock; - } - - sock = socket_local_client("logdr", - ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_SEQPACKET); - if (sock == 0) { - /* Guarantee not file descriptor zero */ - int newsock = socket_local_client("logdr", - ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_SEQPACKET); - close(sock); - sock = newsock; - } - if (sock <= 0) { - if ((sock == -1) && errno) { - return -errno; - } - return sock; - } - - strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? - "dumpAndClose" : "stream"); - cp = buffer + strlen(buffer); - - strcpy(cp, " lids"); - cp += 5; - c = '='; - remaining = sizeof(buffer) - (cp - buffer); - logger_for_each(logger, logger_list) { - ret = snprintf(cp, remaining, "%c%u", c, logger->logId); - ret = min(ret, remaining); - remaining -= ret; - cp += ret; - c = ','; - } - - if (logger_list->tail) { - ret = snprintf(cp, remaining, " tail=%u", logger_list->tail); - ret = min(ret, remaining); - remaining -= ret; - cp += ret; - } - - if (logger_list->start.tv_sec || logger_list->start.tv_nsec) { - if (logger_list->mode & ANDROID_LOG_WRAP) { - // ToDo: alternate API to allow timeout to be adjusted. - ret = snprintf(cp, remaining, " timeout=%u", - ANDROID_LOG_WRAP_DEFAULT_TIMEOUT); - ret = min(ret, remaining); - remaining -= ret; - cp += ret; - } - ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32, - logger_list->start.tv_sec, - logger_list->start.tv_nsec); - ret = min(ret, remaining); - remaining -= ret; - cp += ret; - } - - if (logger_list->pid) { - ret = snprintf(cp, remaining, " pid=%u", logger_list->pid); - ret = min(ret, remaining); - cp += ret; - } - - if (logger_list->mode & ANDROID_LOG_NONBLOCK) { - /* Deal with an unresponsive logd */ - memset(&ignore, 0, sizeof(ignore)); - ignore.sa_handler = caught_signal; - sigemptyset(&ignore.sa_mask); - /* particularily useful if tombstone is reporting for logd */ - sigaction(SIGALRM, &ignore, &old_sigaction); - old_alarm = alarm(30); +static int logdOpen(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp) { + struct android_log_logger* logger; + struct sigaction ignore; + struct sigaction old_sigaction; + unsigned int old_alarm = 0; + char buffer[256], *cp, c; + int e, ret, remaining, sock; + + if (!logger_list) { + return -EINVAL; + } + + sock = atomic_load(&transp->context.sock); + if (sock > 0) { + return sock; + } + + sock = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_SEQPACKET); + if (sock == 0) { + /* Guarantee not file descriptor zero */ + int newsock = socket_local_client( + "logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); + close(sock); + sock = newsock; + } + if (sock <= 0) { + if ((sock == -1) && errno) { + return -errno; } - ret = write(sock, buffer, cp - buffer); - e = errno; - if (logger_list->mode & ANDROID_LOG_NONBLOCK) { - if (e == EINTR) { - e = ETIMEDOUT; - } - alarm(old_alarm); - sigaction(SIGALRM, &old_sigaction, NULL); + return sock; + } + + strcpy(buffer, (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" + : "stream"); + cp = buffer + strlen(buffer); + + strcpy(cp, " lids"); + cp += 5; + c = '='; + remaining = sizeof(buffer) - (cp - buffer); + logger_for_each(logger, logger_list) { + ret = snprintf(cp, remaining, "%c%u", c, logger->logId); + ret = min(ret, remaining); + remaining -= ret; + cp += ret; + c = ','; + } + + if (logger_list->tail) { + ret = snprintf(cp, remaining, " tail=%u", logger_list->tail); + ret = min(ret, remaining); + remaining -= ret; + cp += ret; + } + + if (logger_list->start.tv_sec || logger_list->start.tv_nsec) { + if (logger_list->mode & ANDROID_LOG_WRAP) { + // ToDo: alternate API to allow timeout to be adjusted. + ret = snprintf(cp, remaining, " timeout=%u", + ANDROID_LOG_WRAP_DEFAULT_TIMEOUT); + ret = min(ret, remaining); + remaining -= ret; + cp += ret; + } + ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32, + logger_list->start.tv_sec, logger_list->start.tv_nsec); + ret = min(ret, remaining); + remaining -= ret; + cp += ret; + } + + if (logger_list->pid) { + ret = snprintf(cp, remaining, " pid=%u", logger_list->pid); + ret = min(ret, remaining); + cp += ret; + } + + if (logger_list->mode & ANDROID_LOG_NONBLOCK) { + /* Deal with an unresponsive logd */ + memset(&ignore, 0, sizeof(ignore)); + ignore.sa_handler = caught_signal; + sigemptyset(&ignore.sa_mask); + /* particularily useful if tombstone is reporting for logd */ + sigaction(SIGALRM, &ignore, &old_sigaction); + old_alarm = alarm(30); + } + ret = write(sock, buffer, cp - buffer); + e = errno; + if (logger_list->mode & ANDROID_LOG_NONBLOCK) { + if (e == EINTR) { + e = ETIMEDOUT; + } + alarm(old_alarm); + sigaction(SIGALRM, &old_sigaction, NULL); + } + + if (ret <= 0) { + close(sock); + if ((ret == -1) && e) { + return -e; } - - if (ret <= 0) { - close(sock); - if ((ret == -1) && e) { - return -e; - } - if (ret == 0) { - return -EIO; - } - return ret; + if (ret == 0) { + return -EIO; } + return ret; + } - ret = atomic_exchange(&transp->context.sock, sock); - if ((ret > 0) && (ret != sock)) { - close(ret); - } - return sock; + ret = atomic_exchange(&transp->context.sock, sock); + if ((ret > 0) && (ret != sock)) { + close(ret); + } + return sock; } /* Read from the selected logs */ -static int logdRead(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp, - struct log_msg *log_msg) -{ - int ret, e; - struct sigaction ignore; - struct sigaction old_sigaction; - unsigned int old_alarm = 0; - - ret = logdOpen(logger_list, transp); - if (ret < 0) { - return ret; - } - - memset(log_msg, 0, sizeof(*log_msg)); - - if (logger_list->mode & ANDROID_LOG_NONBLOCK) { - memset(&ignore, 0, sizeof(ignore)); - ignore.sa_handler = caught_signal; - sigemptyset(&ignore.sa_mask); - /* particularily useful if tombstone is reporting for logd */ - sigaction(SIGALRM, &ignore, &old_sigaction); - old_alarm = alarm(30); - } - - /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */ - ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0); - e = errno; - - if (logger_list->mode & ANDROID_LOG_NONBLOCK) { - if ((ret == 0) || (e == EINTR)) { - e = EAGAIN; - ret = -1; - } - alarm(old_alarm); - sigaction(SIGALRM, &old_sigaction, NULL); - } - - if ((ret == -1) && e) { - return -e; - } +static int logdRead(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp, + struct log_msg* log_msg) { + int ret, e; + struct sigaction ignore; + struct sigaction old_sigaction; + unsigned int old_alarm = 0; + + ret = logdOpen(logger_list, transp); + if (ret < 0) { return ret; + } + + memset(log_msg, 0, sizeof(*log_msg)); + + if (logger_list->mode & ANDROID_LOG_NONBLOCK) { + memset(&ignore, 0, sizeof(ignore)); + ignore.sa_handler = caught_signal; + sigemptyset(&ignore.sa_mask); + /* particularily useful if tombstone is reporting for logd */ + sigaction(SIGALRM, &ignore, &old_sigaction); + old_alarm = alarm(30); + } + + /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */ + ret = recv(ret, log_msg, LOGGER_ENTRY_MAX_LEN, 0); + e = errno; + + if (logger_list->mode & ANDROID_LOG_NONBLOCK) { + if ((ret == 0) || (e == EINTR)) { + e = EAGAIN; + ret = -1; + } + alarm(old_alarm); + sigaction(SIGALRM, &old_sigaction, NULL); + } + + if ((ret == -1) && e) { + return -e; + } + return ret; } -static int logdPoll(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp) -{ - struct pollfd p; - - int ret = logdOpen(logger_list, transp); - if (ret < 0) { - return ret; - } +static int logdPoll(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp) { + struct pollfd p; - memset(&p, 0, sizeof(p)); - p.fd = ret; - p.events = POLLIN; - ret = poll(&p, 1, 20); - if ((ret > 0) && !(p.revents & POLLIN)) { - ret = 0; - } - if ((ret == -1) && errno) { - return -errno; - } + int ret = logdOpen(logger_list, transp); + if (ret < 0) { return ret; + } + + memset(&p, 0, sizeof(p)); + p.fd = ret; + p.events = POLLIN; + ret = poll(&p, 1, 20); + if ((ret > 0) && !(p.revents & POLLIN)) { + ret = 0; + } + if ((ret == -1) && errno) { + return -errno; + } + return ret; } /* Close all the logs */ -static void logdClose(struct android_log_logger_list *logger_list __unused, - struct android_log_transport_context *transp) -{ - int sock = atomic_exchange(&transp->context.sock, -1); - if (sock > 0) { - close (sock); - } +static void logdClose(struct android_log_logger_list* logger_list __unused, + struct android_log_transport_context* transp) { + int sock = atomic_exchange(&transp->context.sock, -1); + if (sock > 0) { + close(sock); + } } diff --git a/liblog/logd_reader.h b/liblog/logd_reader.h index 04c2cf2b0..8ebb1aee1 100644 --- a/liblog/logd_reader.h +++ b/liblog/logd_reader.h @@ -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 diff --git a/liblog/logd_writer.c b/liblog/logd_writer.c index 12b797dae..e0e3ecaa1 100644 --- a/liblog/logd_writer.c +++ b/liblog/logd_writer.c @@ -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; - - 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; - } +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"); + + 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; + 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(int negative_errno) { + int sock = atomic_exchange(&logdLoggerWrite.context.sock, negative_errno); + if (sock >= 0) { + close(sock); + } } -static void logdClose() -{ - __logdClose(-EBADF); +static void logdClose() { + __logdClose(-EBADF); } -static int logdAvailable(log_id_t logId) -{ - if (logId >= LOG_ID_MAX || logId == LOG_ID_KERNEL) { - return -EINVAL; +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; } - if (atomic_load(&logdLoggerWrite.context.sock) < 0) { - if (access("/dev/socket/logdw", W_OK) == 0) { - return 0; - } - return -EBADF; - } - return 1; + 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: +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: + 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; - } - + /* logd, after initialization and priv drop */ + if (__android_log_uid() == AID_LOGD) { /* - * 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; - * }; - * }; + * ignore log messages we send to ourself (logd). + * Such log messages are often generated by libraries we depend on + * which use standard Android logging. */ - - 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); - } - } + 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; + 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; + 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; - } + 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; - } + } + + /* + * 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) { + } + 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 (ret < 0) { - return ret; - } - - ret = TEMP_FAILURE_RETRY(writev( - atomic_load(&logdLoggerWrite.context.sock), newVec, i)); - if (ret < 0) { - ret = -errno; - } - /* FALLTHRU */ + 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; + } + + ret = TEMP_FAILURE_RETRY( + writev(atomic_load(&logdLoggerWrite.context.sock), newVec, i)); + if (ret < 0) { + ret = -errno; + } + /* FALLTHRU */ default: - 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); - } + 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); } + } - return ret; + return ret; } diff --git a/liblog/logger.h b/liblog/logger.h index d94cd1467..86c75f8b8 100644 --- a/liblog/logger.h +++ b/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 (*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); + 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); + + 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(); diff --git a/liblog/logger_lock.c b/liblog/logger_lock.c index 14feee078..d4e3a75fe 100644 --- a/liblog/logger_lock.c +++ b/liblog/logger_lock.c @@ -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 } diff --git a/liblog/logger_name.c b/liblog/logger_name.c index 5c4feaf32..a5a83e05a 100644 --- a/liblog/logger_name.c +++ b/liblog/logger_name.c @@ -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 */ } diff --git a/liblog/logger_read.c b/liblog/logger_read.c index 7e50a23fe..0fd6efaab 100644 --- a/liblog/logger_read.c +++ b/liblog/logger_read.c @@ -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; + 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; + } } - - __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(); + if (!logMask) { + continue; } - __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; + transp = calloc(1, sizeof(*transp)); + if (!transp) { + return -ENOMEM; } - return 0; + 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 - -LIBLOG_ABI_PUBLIC int android_logger_clear(struct logger *logger) -{ - LOGGER_FUNCTION(logger, -ENODEV, clear); +#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); } /* 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; - - if (!logger_list_internal || (logId >= LOG_ID_MAX)) { - goto err; +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; + } + + 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); - - if (!logger_list) { - return NULL; - } +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 (!android_logger_open(logger_list, logId)) { - android_logger_list_free(logger_list); - return NULL; - } + if (!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); - - if (ret > (int)sizeof(*log_msg)) { - ret = sizeof(*log_msg); - } - - transp->ret = ret; +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); - /* 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; - } + if (ret > (int)sizeof(*log_msg)) { + ret = sizeof(*log_msg); + } - /* 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; - } + transp->ret = ret; - /* 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; + /* 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; } /* 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; - - 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); - - /* 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(); +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; + } + + /* 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(); + } + 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, - 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; + 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); } - transp = node_to_item(logger_list_internal->transport.next, - struct android_log_transport_context, node); - } while (!oldest && (ret > 0)); - if (!oldest) { - return ret; + } + } + if (ret < retval) { + ret = retval; } - // 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)); + 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; } - memcpy(log_msg, &oldest->logMsg, ret); - oldest->logMsg.entry.len = 0; /* Mark it as copied */ - return ret; + 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)); + 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(); + 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); + 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); + if (transp->transport && transp->transport->close) { + (*transp->transport->close)(logger_list_internal, 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); + 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); } diff --git a/liblog/logger_write.c b/liblog/logger_write.c index 2a9710164..79de6ce6f 100644 --- a/liblog/logger_write.c +++ b/liblog/logger_write.c @@ -36,8 +36,9 @@ #define LOG_BUF_SIZE 1024 -static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr); -static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init; +static int __write_to_log_init(log_id_t, struct iovec* vec, size_t nr); +static int (*write_to_log)(log_id_t, struct iovec* vec, + size_t nr) = __write_to_log_init; /* * This is used by the C++ code to decide if it should write logs through @@ -45,91 +46,84 @@ static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_ * the simulator rather than a desktop tool and want to use the device. */ static enum { - kLogUninitialized, kLogNotAvailable, kLogAvailable + kLogUninitialized, + kLogNotAvailable, + kLogAvailable } g_log_status = kLogUninitialized; -static int check_log_uid_permissions() -{ +static int check_log_uid_permissions() { #if defined(__ANDROID__) - uid_t uid = __android_log_uid(); + uid_t uid = __android_log_uid(); - /* Matches clientHasLogCredentials() in logd */ + /* Matches clientHasLogCredentials() in logd */ + if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { + uid = geteuid(); if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { - uid = geteuid(); - if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) { - gid_t gid = getgid(); - if ((gid != AID_SYSTEM) && - (gid != AID_ROOT) && - (gid != AID_LOG)) { - gid = getegid(); - if ((gid != AID_SYSTEM) && - (gid != AID_ROOT) && - (gid != AID_LOG)) { - int num_groups; - gid_t *groups; - - num_groups = getgroups(0, NULL); - if (num_groups <= 0) { - return -EPERM; - } - groups = calloc(num_groups, sizeof(gid_t)); - if (!groups) { - return -ENOMEM; - } - num_groups = getgroups(num_groups, groups); - while (num_groups > 0) { - if (groups[num_groups - 1] == AID_LOG) { - break; - } - --num_groups; - } - free(groups); - if (num_groups <= 0) { - return -EPERM; - } - } + gid_t gid = getgid(); + if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { + gid = getegid(); + if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { + int num_groups; + gid_t* groups; + + num_groups = getgroups(0, NULL); + if (num_groups <= 0) { + return -EPERM; + } + groups = calloc(num_groups, sizeof(gid_t)); + if (!groups) { + return -ENOMEM; + } + num_groups = getgroups(num_groups, groups); + while (num_groups > 0) { + if (groups[num_groups - 1] == AID_LOG) { + break; } + --num_groups; + } + free(groups); + if (num_groups <= 0) { + return -EPERM; + } } + } } + } #endif - return 0; + return 0; } static void __android_log_cache_available( - struct android_log_transport_write *node) -{ - size_t i; - - if (node->logMask) { - return; - } - - for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { - if (node->write && - (i != LOG_ID_KERNEL) && - ((i != LOG_ID_SECURITY) || - (check_log_uid_permissions() == 0)) && - (!node->available || ((*node->available)(i) >= 0))) { - node->logMask |= 1 << i; - } + struct android_log_transport_write* node) { + size_t i; + + if (node->logMask) { + return; + } + + for (i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) { + if (node->write && (i != LOG_ID_KERNEL) && + ((i != LOG_ID_SECURITY) || (check_log_uid_permissions() == 0)) && + (!node->available || ((*node->available)(i) >= 0))) { + node->logMask |= 1 << i; } + } } -LIBLOG_ABI_PUBLIC int __android_log_dev_available() -{ - struct android_log_transport_write *node; +LIBLOG_ABI_PUBLIC int __android_log_dev_available() { + struct android_log_transport_write* node; - if (list_empty(&__android_log_transport_write)) { - return kLogUninitialized; - } + if (list_empty(&__android_log_transport_write)) { + return kLogUninitialized; + } - write_transport_for_each(node, &__android_log_transport_write) { - __android_log_cache_available(node); - if (node->logMask) { - return kLogAvailable; - } + write_transport_for_each(node, &__android_log_transport_write) { + __android_log_cache_available(node); + if (node->logMask) { + return kLogAvailable; } - return kLogNotAvailable; + } + return kLogNotAvailable; } #if defined(__ANDROID__) @@ -139,423 +133,400 @@ static atomic_uintptr_t tagMap; /* * Release any logger resources. A new log write will immediately re-acquire. */ -LIBLOG_ABI_PUBLIC void __android_log_close() -{ - struct android_log_transport_write *transport; +LIBLOG_ABI_PUBLIC void __android_log_close() { + struct android_log_transport_write* transport; #if defined(__ANDROID__) - EventTagMap *m; + EventTagMap* m; #endif - __android_log_lock(); + __android_log_lock(); - write_to_log = __write_to_log_init; + write_to_log = __write_to_log_init; - /* - * Threads that are actively writing at this point are not held back - * by a lock and are at risk of dropping the messages with a return code - * -EBADF. Prefer to return error code than add the overhead of a lock to - * each log writing call to guarantee delivery. In addition, anyone - * calling this is doing so to release the logging resources and shut down, - * for them to do so with outstanding log requests in other threads is a - * disengenuous use of this function. - */ + /* + * Threads that are actively writing at this point are not held back + * by a lock and are at risk of dropping the messages with a return code + * -EBADF. Prefer to return error code than add the overhead of a lock to + * each log writing call to guarantee delivery. In addition, anyone + * calling this is doing so to release the logging resources and shut down, + * for them to do so with outstanding log requests in other threads is a + * disengenuous use of this function. + */ - write_transport_for_each(transport, &__android_log_persist_write) { - if (transport->close) { - (*transport->close)(); - } + write_transport_for_each(transport, &__android_log_persist_write) { + if (transport->close) { + (*transport->close)(); } + } - write_transport_for_each(transport, &__android_log_transport_write) { - if (transport->close) { - (*transport->close)(); - } + write_transport_for_each(transport, &__android_log_transport_write) { + if (transport->close) { + (*transport->close)(); } + } - __android_log_config_write_close(); + __android_log_config_write_close(); #if defined(__ANDROID__) - /* - * Additional risk here somewhat mitigated by immediately unlock flushing - * the processor cache. The multi-threaded race that we choose to accept, - * to minimize locking, is an atomic_load in a writer picking up a value - * just prior to entering this routine. There will be an use after free. - * - * Again, anyone calling this is doing so to release the logging resources - * is most probably going to quiesce then shut down; or to restart after - * a fork so the risk should be non-existent. For this reason we - * choose a mitigation stance for efficiency instead of incuring the cost - * of a lock for every log write. - */ - m = (EventTagMap *)atomic_exchange(&tagMap, (uintptr_t)0); + /* + * Additional risk here somewhat mitigated by immediately unlock flushing + * the processor cache. The multi-threaded race that we choose to accept, + * to minimize locking, is an atomic_load in a writer picking up a value + * just prior to entering this routine. There will be an use after free. + * + * Again, anyone calling this is doing so to release the logging resources + * is most probably going to quiesce then shut down; or to restart after + * a fork so the risk should be non-existent. For this reason we + * choose a mitigation stance for efficiency instead of incuring the cost + * of a lock for every log write. + */ + m = (EventTagMap*)atomic_exchange(&tagMap, (uintptr_t)0); #endif - __android_log_unlock(); + __android_log_unlock(); #if defined(__ANDROID__) - if (m != (EventTagMap *)(uintptr_t)-1LL) android_closeEventTagMap(m); + if (m != (EventTagMap*)(uintptr_t)-1LL) android_closeEventTagMap(m); #endif - } /* log_init_lock assumed */ -static int __write_to_log_initialize() -{ - struct android_log_transport_write *transport; - struct listnode *n; - int i = 0, ret = 0; - - __android_log_config_write(); - write_transport_for_each_safe(transport, n, &__android_log_transport_write) { - __android_log_cache_available(transport); - if (!transport->logMask) { - list_remove(&transport->node); - continue; - } - if (!transport->open || ((*transport->open)() < 0)) { - if (transport->close) { - (*transport->close)(); - } - list_remove(&transport->node); - continue; - } - ++ret; +static int __write_to_log_initialize() { + struct android_log_transport_write* transport; + struct listnode* n; + int i = 0, ret = 0; + + __android_log_config_write(); + write_transport_for_each_safe(transport, n, &__android_log_transport_write) { + __android_log_cache_available(transport); + if (!transport->logMask) { + list_remove(&transport->node); + continue; } - write_transport_for_each_safe(transport, n, &__android_log_persist_write) { - __android_log_cache_available(transport); - if (!transport->logMask) { - list_remove(&transport->node); - continue; - } - if (!transport->open || ((*transport->open)() < 0)) { - if (transport->close) { - (*transport->close)(); - } - list_remove(&transport->node); - continue; - } - ++i; + if (!transport->open || ((*transport->open)() < 0)) { + if (transport->close) { + (*transport->close)(); + } + list_remove(&transport->node); + continue; + } + ++ret; + } + write_transport_for_each_safe(transport, n, &__android_log_persist_write) { + __android_log_cache_available(transport); + if (!transport->logMask) { + list_remove(&transport->node); + continue; } - if (!ret && !i) { - return -ENODEV; + if (!transport->open || ((*transport->open)() < 0)) { + if (transport->close) { + (*transport->close)(); + } + list_remove(&transport->node); + continue; } + ++i; + } + if (!ret && !i) { + return -ENODEV; + } - return ret; + return ret; } /* * Extract a 4-byte value from a byte stream. le32toh open coded */ -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 __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) -{ - struct android_log_transport_write *node; - int ret; - struct timespec ts; - size_t len, i; +static int __write_to_log_daemon(log_id_t log_id, struct iovec* vec, size_t nr) { + struct android_log_transport_write* node; + int ret; + struct timespec ts; + size_t len, i; - for (len = i = 0; i < nr; ++i) { - len += vec[i].iov_len; - } - if (!len) { - return -EINVAL; - } + for (len = i = 0; i < nr; ++i) { + len += vec[i].iov_len; + } + if (!len) { + return -EINVAL; + } #if defined(__ANDROID__) - clock_gettime(android_log_clockid(), &ts); + clock_gettime(android_log_clockid(), &ts); - if (log_id == LOG_ID_SECURITY) { - if (vec[0].iov_len < 4) { - return -EINVAL; - } + if (log_id == LOG_ID_SECURITY) { + if (vec[0].iov_len < 4) { + return -EINVAL; + } - ret = check_log_uid_permissions(); - if (ret < 0) { - return ret; - } - if (!__android_log_security()) { - /* If only we could reset downstream logd counter */ - return -EPERM; - } - } else if (log_id == LOG_ID_EVENTS) { - const char *tag; - size_t len; - EventTagMap *m, *f; + ret = check_log_uid_permissions(); + if (ret < 0) { + return ret; + } + if (!__android_log_security()) { + /* If only we could reset downstream logd counter */ + return -EPERM; + } + } else if (log_id == LOG_ID_EVENTS) { + const char* tag; + size_t len; + EventTagMap *m, *f; - if (vec[0].iov_len < 4) { - return -EINVAL; - } + if (vec[0].iov_len < 4) { + return -EINVAL; + } - tag = NULL; - len = 0; - f = NULL; - m = (EventTagMap *)atomic_load(&tagMap); - - if (!m) { - ret = __android_log_trylock(); - m = (EventTagMap *)atomic_load(&tagMap); /* trylock flush cache */ - if (!m) { - m = android_openEventTagMap(NULL); - if (ret) { /* trylock failed, use local copy, mark for close */ - f = m; - } else { - if (!m) { /* One chance to open map file */ - m = (EventTagMap *)(uintptr_t)-1LL; - } - atomic_store(&tagMap, (uintptr_t)m); - } - } - if (!ret) { /* trylock succeeded, unlock */ - __android_log_unlock(); - } + tag = NULL; + len = 0; + f = NULL; + m = (EventTagMap*)atomic_load(&tagMap); + + if (!m) { + ret = __android_log_trylock(); + m = (EventTagMap*)atomic_load(&tagMap); /* trylock flush cache */ + if (!m) { + m = android_openEventTagMap(NULL); + if (ret) { /* trylock failed, use local copy, mark for close */ + f = m; + } else { + if (!m) { /* One chance to open map file */ + m = (EventTagMap*)(uintptr_t)-1LL; + } + atomic_store(&tagMap, (uintptr_t)m); } - if (m && (m != (EventTagMap *)(uintptr_t)-1LL)) { - tag = android_lookupEventTag_len(m, &len, get4LE(vec[0].iov_base)); - } - ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, - tag, len, - ANDROID_LOG_VERBOSE); - if (f) { /* local copy marked for close */ - android_closeEventTagMap(f); - } - if (!ret) { - return -EPERM; - } - } else { - /* Validate the incoming tag, tag content can not split across iovec */ - char prio = ANDROID_LOG_VERBOSE; - const char *tag = vec[0].iov_base; - size_t len = vec[0].iov_len; + } + if (!ret) { /* trylock succeeded, unlock */ + __android_log_unlock(); + } + } + if (m && (m != (EventTagMap*)(uintptr_t)-1LL)) { + tag = android_lookupEventTag_len(m, &len, get4LE(vec[0].iov_base)); + } + ret = __android_log_is_loggable_len(ANDROID_LOG_INFO, tag, len, + ANDROID_LOG_VERBOSE); + if (f) { /* local copy marked for close */ + android_closeEventTagMap(f); + } + if (!ret) { + return -EPERM; + } + } else { + /* Validate the incoming tag, tag content can not split across iovec */ + char prio = ANDROID_LOG_VERBOSE; + const char* tag = vec[0].iov_base; + size_t len = vec[0].iov_len; + if (!tag) { + len = 0; + } + if (len > 0) { + prio = *tag; + if (len > 1) { + --len; + ++tag; + } else { + len = vec[1].iov_len; + tag = ((const char*)vec[1].iov_base); if (!tag) { - len = 0; - } - if (len > 0) { - prio = *tag; - if (len > 1) { - --len; - ++tag; - } else { - len = vec[1].iov_len; - tag = ((const char *)vec[1].iov_base); - if (!tag) { - len = 0; - } - } - } - /* tag must be nul terminated */ - if (tag && strnlen(tag, len) >= len) { - tag = NULL; + len = 0; } + } + } + /* tag must be nul terminated */ + if (tag && strnlen(tag, len) >= len) { + tag = NULL; + } - if (!__android_log_is_loggable_len(prio, - tag, len - 1, - ANDROID_LOG_VERBOSE)) { - return -EPERM; - } + if (!__android_log_is_loggable_len(prio, tag, len - 1, ANDROID_LOG_VERBOSE)) { + return -EPERM; } + } #else - /* simulate clock_gettime(CLOCK_REALTIME, &ts); */ - { - struct timeval tv; - gettimeofday(&tv, NULL); - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - } + /* simulate clock_gettime(CLOCK_REALTIME, &ts); */ + { + struct timeval tv; + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + } #endif - ret = 0; - i = 1 << log_id; - write_transport_for_each(node, &__android_log_transport_write) { - if (node->logMask & i) { - ssize_t retval; - retval = (*node->write)(log_id, &ts, vec, nr); - if (ret >= 0) { - ret = retval; - } - } + ret = 0; + i = 1 << log_id; + write_transport_for_each(node, &__android_log_transport_write) { + if (node->logMask & i) { + ssize_t retval; + retval = (*node->write)(log_id, &ts, vec, nr); + if (ret >= 0) { + ret = retval; + } } + } - write_transport_for_each(node, &__android_log_persist_write) { - if (node->logMask & i) { - (void)(*node->write)(log_id, &ts, vec, nr); - } + write_transport_for_each(node, &__android_log_persist_write) { + if (node->logMask & i) { + (void)(*node->write)(log_id, &ts, vec, nr); } + } - return ret; + return ret; } -static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) -{ - __android_log_lock(); - - if (write_to_log == __write_to_log_init) { - int ret; +static int __write_to_log_init(log_id_t log_id, struct iovec* vec, size_t nr) { + __android_log_lock(); - ret = __write_to_log_initialize(); - if (ret < 0) { - __android_log_unlock(); - if (!list_empty(&__android_log_persist_write)) { - __write_to_log_daemon(log_id, vec, nr); - } - return ret; - } + if (write_to_log == __write_to_log_init) { + int ret; - write_to_log = __write_to_log_daemon; + ret = __write_to_log_initialize(); + if (ret < 0) { + __android_log_unlock(); + if (!list_empty(&__android_log_persist_write)) { + __write_to_log_daemon(log_id, vec, nr); + } + return ret; } - __android_log_unlock(); + write_to_log = __write_to_log_daemon; + } - return write_to_log(log_id, vec, nr); + __android_log_unlock(); + + return write_to_log(log_id, vec, nr); } -LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char *tag, - const char *msg) -{ - return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg); +LIBLOG_ABI_PUBLIC int __android_log_write(int prio, const char* tag, + const char* msg) { + return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg); } LIBLOG_ABI_PUBLIC int __android_log_buf_write(int bufID, int prio, - const char *tag, const char *msg) -{ - struct iovec vec[3]; - char tmp_tag[32]; - - if (!tag) - tag = ""; - - /* XXX: This needs to go! */ - if ((bufID != LOG_ID_RADIO) && - (!strcmp(tag, "HTC_RIL") || - !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */ - !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */ - !strcmp(tag, "AT") || - !strcmp(tag, "GSM") || - !strcmp(tag, "STK") || - !strcmp(tag, "CDMA") || - !strcmp(tag, "PHONE") || - !strcmp(tag, "SMS"))) { - bufID = LOG_ID_RADIO; - /* Inform third party apps/ril/radio.. to use Rlog or RLOG */ - snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag); - tag = tmp_tag; - } + const char* tag, const char* msg) { + struct iovec vec[3]; + char tmp_tag[32]; + + if (!tag) tag = ""; + + /* XXX: This needs to go! */ + if ((bufID != LOG_ID_RADIO) && + (!strcmp(tag, "HTC_RIL") || + !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */ + !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */ + !strcmp(tag, "AT") || !strcmp(tag, "GSM") || !strcmp(tag, "STK") || + !strcmp(tag, "CDMA") || !strcmp(tag, "PHONE") || !strcmp(tag, "SMS"))) { + bufID = LOG_ID_RADIO; + /* Inform third party apps/ril/radio.. to use Rlog or RLOG */ + snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag); + tag = tmp_tag; + } #if __BIONIC__ - if (prio == ANDROID_LOG_FATAL) { - android_set_abort_message(msg); - } + if (prio == ANDROID_LOG_FATAL) { + android_set_abort_message(msg); + } #endif - vec[0].iov_base = (unsigned char *)&prio; - vec[0].iov_len = 1; - vec[1].iov_base = (void *)tag; - vec[1].iov_len = strlen(tag) + 1; - vec[2].iov_base = (void *)msg; - vec[2].iov_len = strlen(msg) + 1; + vec[0].iov_base = (unsigned char*)&prio; + vec[0].iov_len = 1; + vec[1].iov_base = (void*)tag; + vec[1].iov_len = strlen(tag) + 1; + vec[2].iov_base = (void*)msg; + vec[2].iov_len = strlen(msg) + 1; - return write_to_log(bufID, vec, 3); + return write_to_log(bufID, vec, 3); } -LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char *tag, - const char *fmt, va_list ap) -{ - char buf[LOG_BUF_SIZE]; +LIBLOG_ABI_PUBLIC int __android_log_vprint(int prio, const char* tag, + const char* fmt, va_list ap) { + char buf[LOG_BUF_SIZE]; - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); + vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - return __android_log_write(prio, tag, buf); + return __android_log_write(prio, tag, buf); } -LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char *tag, - const char *fmt, ...) -{ - va_list ap; - char buf[LOG_BUF_SIZE]; +LIBLOG_ABI_PUBLIC int __android_log_print(int prio, const char* tag, + const char* fmt, ...) { + va_list ap; + char buf[LOG_BUF_SIZE]; - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); + va_end(ap); - return __android_log_write(prio, tag, buf); + return __android_log_write(prio, tag, buf); } LIBLOG_ABI_PUBLIC int __android_log_buf_print(int bufID, int prio, - const char *tag, - const char *fmt, ...) -{ - va_list ap; - char buf[LOG_BUF_SIZE]; + const char* tag, const char* fmt, + ...) { + va_list ap; + char buf[LOG_BUF_SIZE]; - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); + va_end(ap); - return __android_log_buf_write(bufID, prio, tag, buf); + return __android_log_buf_write(bufID, prio, tag, buf); } -LIBLOG_ABI_PUBLIC void __android_log_assert(const char *cond, const char *tag, - const char *fmt, ...) -{ - char buf[LOG_BUF_SIZE]; - - if (fmt) { - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); - } else { - /* Msg not provided, log condition. N.B. Do not use cond directly as - * format string as it could contain spurious '%' syntax (e.g. - * "%d" in "blocks%devs == 0"). - */ - if (cond) - snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond); - else - strcpy(buf, "Unspecified assertion failed"); - } +LIBLOG_ABI_PUBLIC void __android_log_assert(const char* cond, const char* tag, + const char* fmt, ...) { + char buf[LOG_BUF_SIZE]; - // Log assertion failures to stderr for the benefit of "adb shell" users - // and gtests (http://b/23675822). - struct iovec iov[2] = { - { buf, strlen(buf) }, - { (char*) "\n", 1 }, - }; - TEMP_FAILURE_RETRY(writev(2, iov, 2)); - - __android_log_write(ANDROID_LOG_FATAL, tag, buf); - abort(); /* abort so we have a chance to debug the situation */ - /* NOTREACHED */ + if (fmt) { + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); + va_end(ap); + } else { + /* Msg not provided, log condition. N.B. Do not use cond directly as + * format string as it could contain spurious '%' syntax (e.g. + * "%d" in "blocks%devs == 0"). + */ + if (cond) + snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond); + else + strcpy(buf, "Unspecified assertion failed"); + } + + // Log assertion failures to stderr for the benefit of "adb shell" users + // and gtests (http://b/23675822). + struct iovec iov[2] = { + { buf, strlen(buf) }, { (char*)"\n", 1 }, + }; + TEMP_FAILURE_RETRY(writev(2, iov, 2)); + + __android_log_write(ANDROID_LOG_FATAL, tag, buf); + abort(); /* abort so we have a chance to debug the situation */ + /* NOTREACHED */ } -LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag, - const void *payload, size_t len) -{ - struct iovec vec[2]; +LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag, const void* payload, + size_t len) { + struct iovec vec[2]; - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = (void*)payload; - vec[1].iov_len = len; + vec[0].iov_base = &tag; + vec[0].iov_len = sizeof(tag); + vec[1].iov_base = (void*)payload; + vec[1].iov_len = len; - return write_to_log(LOG_ID_EVENTS, vec, 2); + return write_to_log(LOG_ID_EVENTS, vec, 2); } LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag, - const void *payload, - size_t len) -{ - struct iovec vec[2]; + const void* payload, + size_t len) { + struct iovec vec[2]; - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = (void*)payload; - vec[1].iov_len = len; + vec[0].iov_base = &tag; + vec[0].iov_len = sizeof(tag); + vec[1].iov_base = (void*)payload; + vec[1].iov_len = len; - return write_to_log(LOG_ID_SECURITY, vec, 2); + return write_to_log(LOG_ID_SECURITY, vec, 2); } /* @@ -564,40 +535,38 @@ LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag, * handy if we just want to dump an integer into the log. */ LIBLOG_ABI_PUBLIC int __android_log_btwrite(int32_t tag, char type, - const void *payload, size_t len) -{ - struct iovec vec[3]; - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = &type; - vec[1].iov_len = sizeof(type); - vec[2].iov_base = (void*)payload; - vec[2].iov_len = len; - - return write_to_log(LOG_ID_EVENTS, vec, 3); + const void* payload, size_t len) { + struct iovec vec[3]; + + vec[0].iov_base = &tag; + vec[0].iov_len = sizeof(tag); + vec[1].iov_base = &type; + vec[1].iov_len = sizeof(type); + vec[2].iov_base = (void*)payload; + vec[2].iov_len = len; + + return write_to_log(LOG_ID_EVENTS, vec, 3); } /* * Like __android_log_bwrite, but used for writing strings to the * event log. */ -LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload) -{ - struct iovec vec[4]; - char type = EVENT_TYPE_STRING; - uint32_t len = strlen(payload); - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = &type; - vec[1].iov_len = sizeof(type); - vec[2].iov_base = &len; - vec[2].iov_len = sizeof(len); - vec[3].iov_base = (void*)payload; - vec[3].iov_len = len; - - return write_to_log(LOG_ID_EVENTS, vec, 4); +LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char* payload) { + struct iovec vec[4]; + char type = EVENT_TYPE_STRING; + uint32_t len = strlen(payload); + + vec[0].iov_base = &tag; + vec[0].iov_len = sizeof(tag); + vec[1].iov_base = &type; + vec[1].iov_len = sizeof(type); + vec[2].iov_base = &len; + vec[2].iov_len = sizeof(len); + vec[3].iov_base = (void*)payload; + vec[3].iov_len = len; + + return write_to_log(LOG_ID_EVENTS, vec, 4); } /* @@ -605,104 +574,100 @@ LIBLOG_ABI_PUBLIC int __android_log_bswrite(int32_t tag, const char *payload) * security log. */ LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag, - const char *payload) -{ - struct iovec vec[4]; - char type = EVENT_TYPE_STRING; - uint32_t len = strlen(payload); - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = &type; - vec[1].iov_len = sizeof(type); - vec[2].iov_base = &len; - vec[2].iov_len = sizeof(len); - vec[3].iov_base = (void*)payload; - vec[3].iov_len = len; - - return write_to_log(LOG_ID_SECURITY, vec, 4); + const char* payload) { + struct iovec vec[4]; + char type = EVENT_TYPE_STRING; + uint32_t len = strlen(payload); + + vec[0].iov_base = &tag; + vec[0].iov_len = sizeof(tag); + vec[1].iov_base = &type; + vec[1].iov_len = sizeof(type); + vec[2].iov_base = &len; + vec[2].iov_len = sizeof(len); + vec[3].iov_base = (void*)payload; + vec[3].iov_len = len; + + return write_to_log(LOG_ID_SECURITY, vec, 4); } -static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr) -{ - size_t len, i; +static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr) { + size_t len, i; - if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) { - return -EINVAL; - } + if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) { + return -EINVAL; + } - for (len = i = 0; i < nr; ++i) { - len += vec[i].iov_len; - } - if (!len) { - return -EINVAL; - } - return len; + for (len = i = 0; i < nr; ++i) { + len += vec[i].iov_len; + } + if (!len) { + return -EINVAL; + } + return len; } /* Following functions need access to our internal write_to_log status */ LIBLOG_HIDDEN int __android_log_frontend; -LIBLOG_ABI_PUBLIC int android_set_log_frontend(int frontend_flag) -{ - int retval; +LIBLOG_ABI_PUBLIC int android_set_log_frontend(int frontend_flag) { + int retval; - if (frontend_flag < 0) { - return -EINVAL; - } + if (frontend_flag < 0) { + return -EINVAL; + } - retval = LOGGER_NULL; + retval = LOGGER_NULL; - __android_log_lock(); + __android_log_lock(); - if (frontend_flag & LOGGER_NULL) { - write_to_log = __write_to_log_null; + if (frontend_flag & LOGGER_NULL) { + write_to_log = __write_to_log_null; - __android_log_unlock(); + __android_log_unlock(); - return retval; - } + return retval; + } - __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; + __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; - frontend_flag &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; + frontend_flag &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; - if (__android_log_frontend != frontend_flag) { - __android_log_frontend = frontend_flag; - __android_log_config_write_close(); - __android_log_config_read_close(); + if (__android_log_frontend != frontend_flag) { + __android_log_frontend = frontend_flag; + __android_log_config_write_close(); + __android_log_config_read_close(); - write_to_log = __write_to_log_init; + write_to_log = __write_to_log_init; /* generically we only expect these two values for write_to_log */ - } else if ((write_to_log != __write_to_log_init) && - (write_to_log != __write_to_log_daemon)) { - write_to_log = __write_to_log_init; - } + } else if ((write_to_log != __write_to_log_init) && + (write_to_log != __write_to_log_daemon)) { + write_to_log = __write_to_log_init; + } - retval = __android_log_frontend; + retval = __android_log_frontend; - __android_log_unlock(); + __android_log_unlock(); - return retval; + return retval; } -LIBLOG_ABI_PUBLIC int android_get_log_frontend() -{ - int ret = LOGGER_DEFAULT; - - __android_log_lock(); - if (write_to_log == __write_to_log_null) { - ret = LOGGER_NULL; - } else { - __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; - ret = __android_log_frontend; - if ((write_to_log != __write_to_log_init) && - (write_to_log != __write_to_log_daemon)) { - ret = -EINVAL; - } +LIBLOG_ABI_PUBLIC int android_get_log_frontend() { + int ret = LOGGER_DEFAULT; + + __android_log_lock(); + if (write_to_log == __write_to_log_null) { + ret = LOGGER_NULL; + } else { + __android_log_frontend &= LOGGER_LOCAL | LOGGER_LOGD | LOGGER_STDERR; + ret = __android_log_frontend; + if ((write_to_log != __write_to_log_init) && + (write_to_log != __write_to_log_daemon)) { + ret = -EINVAL; } - __android_log_unlock(); + } + __android_log_unlock(); - return ret; + return ret; } diff --git a/liblog/logprint.c b/liblog/logprint.c index 4421f83a3..2ade7b02c 100644 --- a/liblog/logprint.c +++ b/liblog/logprint.c @@ -45,29 +45,29 @@ #define US_PER_NSEC 1000 #ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif typedef struct FilterInfo_t { - char *mTag; - android_LogPriority mPri; - struct FilterInfo_t *p_next; + char* mTag; + android_LogPriority mPri; + struct FilterInfo_t* p_next; } FilterInfo; struct AndroidLogFormat_t { - android_LogPriority global_pri; - FilterInfo *filters; - AndroidLogPrintFormat format; - bool colored_output; - bool usec_time_output; - bool nsec_time_output; - bool printable_output; - bool year_output; - bool zone_output; - bool epoch_output; - bool monotonic_output; - bool uid_output; - bool descriptive_output; + android_LogPriority global_pri; + FilterInfo* filters; + AndroidLogPrintFormat format; + bool colored_output; + bool usec_time_output; + bool nsec_time_output; + bool printable_output; + bool year_output; + bool zone_output; + bool epoch_output; + bool monotonic_output; + bool uid_output; + bool descriptive_output; }; /* @@ -83,22 +83,21 @@ static bool descriptive_output = false; * The color manipulation character stream is defined as: * ESC [ 3 8 ; 5 ; <color#> m */ -#define ANDROID_COLOR_BLUE 75 +#define ANDROID_COLOR_BLUE 75 #define ANDROID_COLOR_DEFAULT 231 -#define ANDROID_COLOR_GREEN 40 -#define ANDROID_COLOR_ORANGE 166 -#define ANDROID_COLOR_RED 196 -#define ANDROID_COLOR_YELLOW 226 +#define ANDROID_COLOR_GREEN 40 +#define ANDROID_COLOR_ORANGE 166 +#define ANDROID_COLOR_RED 196 +#define ANDROID_COLOR_YELLOW 226 -static FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri) -{ - FilterInfo *p_ret; +static FilterInfo* filterinfo_new(const char* tag, android_LogPriority pri) { + FilterInfo* p_ret; - p_ret = (FilterInfo *)calloc(1, sizeof(FilterInfo)); - p_ret->mTag = strdup(tag); - p_ret->mPri = pri; + p_ret = (FilterInfo*)calloc(1, sizeof(FilterInfo)); + p_ret->mTag = strdup(tag); + p_ret->mPri = pri; - return p_ret; + return p_ret; } /* balance to above, filterinfo_free left unimplemented */ @@ -107,201 +106,193 @@ static FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri) * Note: also accepts 0-9 priorities * returns ANDROID_LOG_UNKNOWN if the character is unrecognized */ -static android_LogPriority filterCharToPri (char c) -{ - android_LogPriority pri; +static android_LogPriority filterCharToPri(char c) { + android_LogPriority pri; - c = tolower(c); + c = tolower(c); - if (c >= '0' && c <= '9') { - if (c >= ('0' + ANDROID_LOG_SILENT)) { - pri = ANDROID_LOG_VERBOSE; - } else { - pri = (android_LogPriority)(c - '0'); - } - } else if (c == 'v') { - pri = ANDROID_LOG_VERBOSE; - } else if (c == 'd') { - pri = ANDROID_LOG_DEBUG; - } else if (c == 'i') { - pri = ANDROID_LOG_INFO; - } else if (c == 'w') { - pri = ANDROID_LOG_WARN; - } else if (c == 'e') { - pri = ANDROID_LOG_ERROR; - } else if (c == 'f') { - pri = ANDROID_LOG_FATAL; - } else if (c == 's') { - pri = ANDROID_LOG_SILENT; - } else if (c == '*') { - pri = ANDROID_LOG_DEFAULT; + if (c >= '0' && c <= '9') { + if (c >= ('0' + ANDROID_LOG_SILENT)) { + pri = ANDROID_LOG_VERBOSE; } else { - pri = ANDROID_LOG_UNKNOWN; - } - - return pri; + pri = (android_LogPriority)(c - '0'); + } + } else if (c == 'v') { + pri = ANDROID_LOG_VERBOSE; + } else if (c == 'd') { + pri = ANDROID_LOG_DEBUG; + } else if (c == 'i') { + pri = ANDROID_LOG_INFO; + } else if (c == 'w') { + pri = ANDROID_LOG_WARN; + } else if (c == 'e') { + pri = ANDROID_LOG_ERROR; + } else if (c == 'f') { + pri = ANDROID_LOG_FATAL; + } else if (c == 's') { + pri = ANDROID_LOG_SILENT; + } else if (c == '*') { + pri = ANDROID_LOG_DEFAULT; + } else { + pri = ANDROID_LOG_UNKNOWN; + } + + return pri; } -static char filterPriToChar (android_LogPriority pri) -{ - switch (pri) { - case ANDROID_LOG_VERBOSE: return 'V'; - case ANDROID_LOG_DEBUG: return 'D'; - case ANDROID_LOG_INFO: return 'I'; - case ANDROID_LOG_WARN: return 'W'; - case ANDROID_LOG_ERROR: return 'E'; - case ANDROID_LOG_FATAL: return 'F'; - case ANDROID_LOG_SILENT: return 'S'; - - case ANDROID_LOG_DEFAULT: - case ANDROID_LOG_UNKNOWN: - default: return '?'; - } +static char filterPriToChar(android_LogPriority pri) { + switch (pri) { + /* clang-format off */ + case ANDROID_LOG_VERBOSE: return 'V'; + case ANDROID_LOG_DEBUG: return 'D'; + case ANDROID_LOG_INFO: return 'I'; + case ANDROID_LOG_WARN: return 'W'; + case ANDROID_LOG_ERROR: return 'E'; + case ANDROID_LOG_FATAL: return 'F'; + case ANDROID_LOG_SILENT: return 'S'; + + case ANDROID_LOG_DEFAULT: + case ANDROID_LOG_UNKNOWN: + default: return '?'; + /* clang-format on */ + } } -static int colorFromPri (android_LogPriority pri) -{ - switch (pri) { - case ANDROID_LOG_VERBOSE: return ANDROID_COLOR_DEFAULT; - case ANDROID_LOG_DEBUG: return ANDROID_COLOR_BLUE; - case ANDROID_LOG_INFO: return ANDROID_COLOR_GREEN; - case ANDROID_LOG_WARN: return ANDROID_COLOR_ORANGE; - case ANDROID_LOG_ERROR: return ANDROID_COLOR_RED; - case ANDROID_LOG_FATAL: return ANDROID_COLOR_RED; - case ANDROID_LOG_SILENT: return ANDROID_COLOR_DEFAULT; - - case ANDROID_LOG_DEFAULT: - case ANDROID_LOG_UNKNOWN: - default: return ANDROID_COLOR_DEFAULT; - } +static int colorFromPri(android_LogPriority pri) { + switch (pri) { + /* clang-format off */ + case ANDROID_LOG_VERBOSE: return ANDROID_COLOR_DEFAULT; + case ANDROID_LOG_DEBUG: return ANDROID_COLOR_BLUE; + case ANDROID_LOG_INFO: return ANDROID_COLOR_GREEN; + case ANDROID_LOG_WARN: return ANDROID_COLOR_ORANGE; + case ANDROID_LOG_ERROR: return ANDROID_COLOR_RED; + case ANDROID_LOG_FATAL: return ANDROID_COLOR_RED; + case ANDROID_LOG_SILENT: return ANDROID_COLOR_DEFAULT; + + case ANDROID_LOG_DEFAULT: + case ANDROID_LOG_UNKNOWN: + default: return ANDROID_COLOR_DEFAULT; + /* clang-format on */ + } } -static android_LogPriority filterPriForTag( - AndroidLogFormat *p_format, const char *tag) -{ - FilterInfo *p_curFilter; - - for (p_curFilter = p_format->filters - ; p_curFilter != NULL - ; p_curFilter = p_curFilter->p_next - ) { - if (0 == strcmp(tag, p_curFilter->mTag)) { - if (p_curFilter->mPri == ANDROID_LOG_DEFAULT) { - return p_format->global_pri; - } else { - return p_curFilter->mPri; - } - } +static android_LogPriority filterPriForTag(AndroidLogFormat* p_format, + const char* tag) { + FilterInfo* p_curFilter; + + for (p_curFilter = p_format->filters; p_curFilter != NULL; + p_curFilter = p_curFilter->p_next) { + if (0 == strcmp(tag, p_curFilter->mTag)) { + if (p_curFilter->mPri == ANDROID_LOG_DEFAULT) { + return p_format->global_pri; + } else { + return p_curFilter->mPri; + } } + } - return p_format->global_pri; + return p_format->global_pri; } /** * returns 1 if this log line should be printed based on its priority * and tag, and 0 if it should not */ -LIBLOG_ABI_PUBLIC int android_log_shouldPrintLine ( - AndroidLogFormat *p_format, - const char *tag, - android_LogPriority pri) -{ - return pri >= filterPriForTag(p_format, tag); +LIBLOG_ABI_PUBLIC int android_log_shouldPrintLine(AndroidLogFormat* p_format, + const char* tag, + android_LogPriority pri) { + return pri >= filterPriForTag(p_format, tag); } -LIBLOG_ABI_PUBLIC AndroidLogFormat *android_log_format_new() -{ - AndroidLogFormat *p_ret; - - p_ret = calloc(1, sizeof(AndroidLogFormat)); - - p_ret->global_pri = ANDROID_LOG_VERBOSE; - p_ret->format = FORMAT_BRIEF; - p_ret->colored_output = false; - p_ret->usec_time_output = false; - p_ret->nsec_time_output = false; - p_ret->printable_output = false; - p_ret->year_output = false; - p_ret->zone_output = false; - p_ret->epoch_output = false; +LIBLOG_ABI_PUBLIC AndroidLogFormat* android_log_format_new() { + AndroidLogFormat* p_ret; + + p_ret = calloc(1, sizeof(AndroidLogFormat)); + + p_ret->global_pri = ANDROID_LOG_VERBOSE; + p_ret->format = FORMAT_BRIEF; + p_ret->colored_output = false; + p_ret->usec_time_output = false; + p_ret->nsec_time_output = false; + p_ret->printable_output = false; + p_ret->year_output = false; + p_ret->zone_output = false; + p_ret->epoch_output = false; #ifdef __ANDROID__ - p_ret->monotonic_output = android_log_clockid() == CLOCK_MONOTONIC; + p_ret->monotonic_output = android_log_clockid() == CLOCK_MONOTONIC; #else - p_ret->monotonic_output = false; + p_ret->monotonic_output = false; #endif - p_ret->uid_output = false; - p_ret->descriptive_output = false; - descriptive_output = false; + p_ret->uid_output = false; + p_ret->descriptive_output = false; + descriptive_output = false; - return p_ret; + return p_ret; } static list_declare(convertHead); -LIBLOG_ABI_PUBLIC void android_log_format_free(AndroidLogFormat *p_format) -{ - FilterInfo *p_info, *p_info_old; +LIBLOG_ABI_PUBLIC void android_log_format_free(AndroidLogFormat* p_format) { + FilterInfo *p_info, *p_info_old; - p_info = p_format->filters; + p_info = p_format->filters; - while (p_info != NULL) { - p_info_old = p_info; - p_info = p_info->p_next; + while (p_info != NULL) { + p_info_old = p_info; + p_info = p_info->p_next; - free(p_info_old); - } + free(p_info_old); + } - free(p_format); + free(p_format); - /* Free conversion resource, can always be reconstructed */ - while (!list_empty(&convertHead)) { - struct listnode *node = list_head(&convertHead); - list_remove(node); - free(node); - } + /* Free conversion resource, can always be reconstructed */ + while (!list_empty(&convertHead)) { + struct listnode* node = list_head(&convertHead); + list_remove(node); + free(node); + } } -LIBLOG_ABI_PUBLIC int android_log_setPrintFormat( - AndroidLogFormat *p_format, - AndroidLogPrintFormat format) -{ - switch (format) { +LIBLOG_ABI_PUBLIC int android_log_setPrintFormat(AndroidLogFormat* p_format, + AndroidLogPrintFormat format) { + switch (format) { case FORMAT_MODIFIER_COLOR: - p_format->colored_output = true; - return 0; + p_format->colored_output = true; + return 0; case FORMAT_MODIFIER_TIME_USEC: - p_format->usec_time_output = true; - return 0; + p_format->usec_time_output = true; + return 0; case FORMAT_MODIFIER_TIME_NSEC: - p_format->nsec_time_output = true; - return 0; + p_format->nsec_time_output = true; + return 0; case FORMAT_MODIFIER_PRINTABLE: - p_format->printable_output = true; - return 0; + p_format->printable_output = true; + return 0; case FORMAT_MODIFIER_YEAR: - p_format->year_output = true; - return 0; + p_format->year_output = true; + return 0; case FORMAT_MODIFIER_ZONE: - p_format->zone_output = !p_format->zone_output; - return 0; + p_format->zone_output = !p_format->zone_output; + return 0; case FORMAT_MODIFIER_EPOCH: - p_format->epoch_output = true; - return 0; + p_format->epoch_output = true; + return 0; case FORMAT_MODIFIER_MONOTONIC: - p_format->monotonic_output = true; - return 0; + p_format->monotonic_output = true; + return 0; case FORMAT_MODIFIER_UID: - p_format->uid_output = true; - return 0; + p_format->uid_output = true; + return 0; case FORMAT_MODIFIER_DESCRIPT: - p_format->descriptive_output = true; - descriptive_output = true; - return 0; + p_format->descriptive_output = true; + descriptive_output = true; + return 0; default: - break; - } - p_format->format = format; - return 1; + break; + } + p_format->format = format; + return 1; } static const char tz[] = "TZ"; @@ -310,65 +301,65 @@ static const char utc[] = "UTC"; /** * Returns FORMAT_OFF on invalid string */ -LIBLOG_ABI_PUBLIC AndroidLogPrintFormat android_log_formatFromString( - const char * formatString) -{ - static AndroidLogPrintFormat format; - - if (strcmp(formatString, "brief") == 0) format = FORMAT_BRIEF; - else if (strcmp(formatString, "process") == 0) format = FORMAT_PROCESS; - else if (strcmp(formatString, "tag") == 0) format = FORMAT_TAG; - else if (strcmp(formatString, "thread") == 0) format = FORMAT_THREAD; - else if (strcmp(formatString, "raw") == 0) format = FORMAT_RAW; - else if (strcmp(formatString, "time") == 0) format = FORMAT_TIME; - else if (strcmp(formatString, "threadtime") == 0) format = FORMAT_THREADTIME; - else if (strcmp(formatString, "long") == 0) format = FORMAT_LONG; - else if (strcmp(formatString, "color") == 0) format = FORMAT_MODIFIER_COLOR; - else if (strcmp(formatString, "colour") == 0) format = FORMAT_MODIFIER_COLOR; - else if (strcmp(formatString, "usec") == 0) format = FORMAT_MODIFIER_TIME_USEC; - else if (strcmp(formatString, "nsec") == 0) format = FORMAT_MODIFIER_TIME_NSEC; - else if (strcmp(formatString, "printable") == 0) format = FORMAT_MODIFIER_PRINTABLE; - else if (strcmp(formatString, "year") == 0) format = FORMAT_MODIFIER_YEAR; - else if (strcmp(formatString, "zone") == 0) format = FORMAT_MODIFIER_ZONE; - else if (strcmp(formatString, "epoch") == 0) format = FORMAT_MODIFIER_EPOCH; - else if (strcmp(formatString, "monotonic") == 0) format = FORMAT_MODIFIER_MONOTONIC; - else if (strcmp(formatString, "uid") == 0) format = FORMAT_MODIFIER_UID; - else if (strcmp(formatString, "descriptive") == 0) format = FORMAT_MODIFIER_DESCRIPT; +LIBLOG_ABI_PUBLIC AndroidLogPrintFormat +android_log_formatFromString(const char* formatString) { + static AndroidLogPrintFormat format; + + /* clang-format off */ + if (!strcmp(formatString, "brief")) format = FORMAT_BRIEF; + else if (!strcmp(formatString, "process")) format = FORMAT_PROCESS; + else if (!strcmp(formatString, "tag")) format = FORMAT_TAG; + else if (!strcmp(formatString, "thread")) format = FORMAT_THREAD; + else if (!strcmp(formatString, "raw")) format = FORMAT_RAW; + else if (!strcmp(formatString, "time")) format = FORMAT_TIME; + else if (!strcmp(formatString, "threadtime")) format = FORMAT_THREADTIME; + else if (!strcmp(formatString, "long")) format = FORMAT_LONG; + else if (!strcmp(formatString, "color")) format = FORMAT_MODIFIER_COLOR; + else if (!strcmp(formatString, "colour")) format = FORMAT_MODIFIER_COLOR; + else if (!strcmp(formatString, "usec")) format = FORMAT_MODIFIER_TIME_USEC; + else if (!strcmp(formatString, "nsec")) format = FORMAT_MODIFIER_TIME_NSEC; + else if (!strcmp(formatString, "printable")) format = FORMAT_MODIFIER_PRINTABLE; + else if (!strcmp(formatString, "year")) format = FORMAT_MODIFIER_YEAR; + else if (!strcmp(formatString, "zone")) format = FORMAT_MODIFIER_ZONE; + else if (!strcmp(formatString, "epoch")) format = FORMAT_MODIFIER_EPOCH; + else if (!strcmp(formatString, "monotonic")) format = FORMAT_MODIFIER_MONOTONIC; + else if (!strcmp(formatString, "uid")) format = FORMAT_MODIFIER_UID; + else if (!strcmp(formatString, "descriptive")) format = FORMAT_MODIFIER_DESCRIPT; + /* clang-format on */ #ifndef __MINGW32__ - else { - extern char *tzname[2]; - static const char gmt[] = "GMT"; - char *cp = getenv(tz); - if (cp) { - cp = strdup(cp); - } - setenv(tz, formatString, 1); - /* - * Run tzset here to determine if the timezone is legitimate. If the - * zone is GMT, check if that is what was asked for, if not then - * did not match any on the system; report an error to caller. - */ - tzset(); - if (!tzname[0] - || ((!strcmp(tzname[0], utc) - || !strcmp(tzname[0], gmt)) /* error? */ - && strcasecmp(formatString, utc) - && strcasecmp(formatString, gmt))) { /* ok */ - if (cp) { - setenv(tz, cp, 1); - } else { - unsetenv(tz); - } - tzset(); - format = FORMAT_OFF; - } else { - format = FORMAT_MODIFIER_ZONE; - } - free(cp); + else { + extern char* tzname[2]; + static const char gmt[] = "GMT"; + char* cp = getenv(tz); + if (cp) { + cp = strdup(cp); + } + setenv(tz, formatString, 1); + /* + * Run tzset here to determine if the timezone is legitimate. If the + * zone is GMT, check if that is what was asked for, if not then + * did not match any on the system; report an error to caller. + */ + tzset(); + if (!tzname[0] || + ((!strcmp(tzname[0], utc) || !strcmp(tzname[0], gmt)) /* error? */ + && strcasecmp(formatString, utc) && + strcasecmp(formatString, gmt))) { /* ok */ + if (cp) { + setenv(tz, cp, 1); + } else { + unsetenv(tz); + } + tzset(); + format = FORMAT_OFF; + } else { + format = FORMAT_MODIFIER_ZONE; } + free(cp); + } #endif - return format; + return format; } /** @@ -380,92 +371,89 @@ LIBLOG_ABI_PUBLIC AndroidLogPrintFormat android_log_formatFromString( * Assumes single threaded execution */ -LIBLOG_ABI_PUBLIC int android_log_addFilterRule( - AndroidLogFormat *p_format, - const char *filterExpression) -{ - size_t tagNameLength; - android_LogPriority pri = ANDROID_LOG_DEFAULT; +LIBLOG_ABI_PUBLIC int android_log_addFilterRule(AndroidLogFormat* p_format, + const char* filterExpression) { + size_t tagNameLength; + android_LogPriority pri = ANDROID_LOG_DEFAULT; - tagNameLength = strcspn(filterExpression, ":"); + tagNameLength = strcspn(filterExpression, ":"); - if (tagNameLength == 0) { - goto error; - } + if (tagNameLength == 0) { + goto error; + } - if(filterExpression[tagNameLength] == ':') { - pri = filterCharToPri(filterExpression[tagNameLength + 1]); + if (filterExpression[tagNameLength] == ':') { + pri = filterCharToPri(filterExpression[tagNameLength + 1]); - if (pri == ANDROID_LOG_UNKNOWN) { - goto error; - } + if (pri == ANDROID_LOG_UNKNOWN) { + goto error; } + } - if(0 == strncmp("*", filterExpression, tagNameLength)) { - /* - * This filter expression refers to the global filter - * The default level for this is DEBUG if the priority - * is unspecified - */ - if (pri == ANDROID_LOG_DEFAULT) { - pri = ANDROID_LOG_DEBUG; - } + if (0 == strncmp("*", filterExpression, tagNameLength)) { + /* + * This filter expression refers to the global filter + * The default level for this is DEBUG if the priority + * is unspecified + */ + if (pri == ANDROID_LOG_DEFAULT) { + pri = ANDROID_LOG_DEBUG; + } - p_format->global_pri = pri; - } else { - /* - * for filter expressions that don't refer to the global - * filter, the default is verbose if the priority is unspecified - */ - if (pri == ANDROID_LOG_DEFAULT) { - pri = ANDROID_LOG_VERBOSE; - } + p_format->global_pri = pri; + } else { + /* + * for filter expressions that don't refer to the global + * filter, the default is verbose if the priority is unspecified + */ + if (pri == ANDROID_LOG_DEFAULT) { + pri = ANDROID_LOG_VERBOSE; + } - char *tagName; + char* tagName; /* * Presently HAVE_STRNDUP is never defined, so the second case is always taken * Darwin doesn't have strndup, everything else does */ #ifdef HAVE_STRNDUP - tagName = strndup(filterExpression, tagNameLength); + tagName = strndup(filterExpression, tagNameLength); #else - /* a few extra bytes copied... */ - tagName = strdup(filterExpression); - tagName[tagNameLength] = '\0'; + /* a few extra bytes copied... */ + tagName = strdup(filterExpression); + tagName[tagNameLength] = '\0'; #endif /*HAVE_STRNDUP*/ - FilterInfo *p_fi = filterinfo_new(tagName, pri); - free(tagName); + FilterInfo* p_fi = filterinfo_new(tagName, pri); + free(tagName); - p_fi->p_next = p_format->filters; - p_format->filters = p_fi; - } + p_fi->p_next = p_format->filters; + p_format->filters = p_fi; + } - return 0; + return 0; error: - return -1; + return -1; } #ifndef HAVE_STRSEP /* KISS replacement helper for below */ -static char* strsep(char** stringp, const char* delim) -{ - char* token; - char* ret = *stringp; - - if (!ret || !*ret) { - return NULL; - } - token = strpbrk(ret, delim); - if (token) { - *token = '\0'; - ++token; - } else { - token = ret + strlen(ret); - } - *stringp = token; - return ret; +static char* strsep(char** stringp, const char* delim) { + char* token; + char* ret = *stringp; + + if (!ret || !*ret) { + return NULL; + } + token = strpbrk(ret, delim); + if (token) { + *token = '\0'; + ++token; + } else { + token = ret + strlen(ret); + } + *stringp = token; + return ret; } #endif @@ -479,32 +467,30 @@ static char* strsep(char** stringp, const char* delim) * Assumes single threaded execution * */ -LIBLOG_ABI_PUBLIC int android_log_addFilterString( - AndroidLogFormat *p_format, - const char *filterString) -{ - char *filterStringCopy = strdup (filterString); - char *p_cur = filterStringCopy; - char *p_ret; - int err; - - /* Yes, I'm using strsep */ - while (NULL != (p_ret = strsep(&p_cur, " \t,"))) { - /* ignore whitespace-only entries */ - if(p_ret[0] != '\0') { - err = android_log_addFilterRule(p_format, p_ret); - - if (err < 0) { - goto error; - } - } +LIBLOG_ABI_PUBLIC int android_log_addFilterString(AndroidLogFormat* p_format, + const char* filterString) { + char* filterStringCopy = strdup(filterString); + char* p_cur = filterStringCopy; + char* p_ret; + int err; + + /* Yes, I'm using strsep */ + while (NULL != (p_ret = strsep(&p_cur, " \t,"))) { + /* ignore whitespace-only entries */ + if (p_ret[0] != '\0') { + err = android_log_addFilterRule(p_format, p_ret); + + if (err < 0) { + goto error; + } } + } - free (filterStringCopy); - return 0; + free(filterStringCopy); + return 0; error: - free (filterStringCopy); - return -1; + free(filterStringCopy); + return -1; } /** @@ -514,128 +500,124 @@ error: * Returns 0 on success and -1 on invalid wire format (entry will be * in unspecified state) */ -LIBLOG_ABI_PUBLIC int android_log_processLogBuffer( - struct logger_entry *buf, - AndroidLogEntry *entry) -{ - entry->message = NULL; - entry->messageLen = 0; - - entry->tv_sec = buf->sec; - entry->tv_nsec = buf->nsec; - entry->uid = -1; - entry->pid = buf->pid; - entry->tid = buf->tid; - +LIBLOG_ABI_PUBLIC int android_log_processLogBuffer(struct logger_entry* buf, + AndroidLogEntry* entry) { + entry->message = NULL; + entry->messageLen = 0; + + entry->tv_sec = buf->sec; + entry->tv_nsec = buf->nsec; + entry->uid = -1; + entry->pid = buf->pid; + entry->tid = buf->tid; + + /* + * format: <priority:1><tag:N>\0<message:N>\0 + * + * tag str + * starts at buf->msg+1 + * msg + * starts at buf->msg+1+len(tag)+1 + * + * The message may have been truncated by the kernel log driver. + * When that happens, we must null-terminate the message ourselves. + */ + if (buf->len < 3) { /* - * format: <priority:1><tag:N>\0<message:N>\0 - * - * tag str - * starts at buf->msg+1 - * msg - * starts at buf->msg+1+len(tag)+1 - * - * The message may have been truncated by the kernel log driver. - * When that happens, we must null-terminate the message ourselves. + * An well-formed entry must consist of at least a priority + * and two null characters */ - if (buf->len < 3) { - /* - * An well-formed entry must consist of at least a priority - * and two null characters - */ - fprintf(stderr, "+++ LOG: entry too small\n"); - return -1; + fprintf(stderr, "+++ LOG: entry too small\n"); + return -1; + } + + int msgStart = -1; + int msgEnd = -1; + + int i; + char* msg = buf->msg; + struct logger_entry_v2* buf2 = (struct logger_entry_v2*)buf; + if (buf2->hdr_size) { + if ((buf2->hdr_size < sizeof(((struct log_msg*)NULL)->entry_v1)) || + (buf2->hdr_size > sizeof(((struct log_msg*)NULL)->entry))) { + fprintf(stderr, "+++ LOG: entry illegal hdr_size\n"); + return -1; + } + msg = ((char*)buf2) + buf2->hdr_size; + if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) { + entry->uid = ((struct logger_entry_v4*)buf)->uid; + } + } + for (i = 1; i < buf->len; i++) { + if (msg[i] == '\0') { + if (msgStart == -1) { + msgStart = i + 1; + } else { + msgEnd = i; + break; + } } + } - int msgStart = -1; - int msgEnd = -1; - - int i; - char *msg = buf->msg; - struct logger_entry_v2 *buf2 = (struct logger_entry_v2 *)buf; - if (buf2->hdr_size) { - if ((buf2->hdr_size < sizeof(((struct log_msg *)NULL)->entry_v1)) || - (buf2->hdr_size > sizeof(((struct log_msg *)NULL)->entry))) { - fprintf(stderr, "+++ LOG: entry illegal hdr_size\n"); - return -1; - } - msg = ((char *)buf2) + buf2->hdr_size; - if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) { - entry->uid = ((struct logger_entry_v4 *)buf)->uid; - } - } + if (msgStart == -1) { + /* +++ LOG: malformed log message, DYB */ for (i = 1; i < buf->len; i++) { - if (msg[i] == '\0') { - if (msgStart == -1) { - msgStart = i + 1; - } else { - msgEnd = i; - break; - } - } + /* odd characters in tag? */ + if ((msg[i] <= ' ') || (msg[i] == ':') || (msg[i] >= 0x7f)) { + msg[i] = '\0'; + msgStart = i + 1; + break; + } } - if (msgStart == -1) { - /* +++ LOG: malformed log message, DYB */ - for (i = 1; i < buf->len; i++) { - /* odd characters in tag? */ - if ((msg[i] <= ' ') || (msg[i] == ':') || (msg[i] >= 0x7f)) { - msg[i] = '\0'; - msgStart = i + 1; - break; - } - } - if (msgStart == -1) { - msgStart = buf->len - 1; /* All tag, no message, print truncates */ - } - } - if (msgEnd == -1) { - /* incoming message not null-terminated; force it */ - msgEnd = buf->len - 1; /* may result in msgEnd < msgStart */ - msg[msgEnd] = '\0'; - } - - entry->priority = msg[0]; - entry->tag = msg + 1; - entry->tagLen = msgStart - 1; - entry->message = msg + msgStart; - entry->messageLen = (msgEnd < msgStart) ? 0 : (msgEnd - msgStart); - - return 0; + msgStart = buf->len - 1; /* All tag, no message, print truncates */ + } + } + if (msgEnd == -1) { + /* incoming message not null-terminated; force it */ + msgEnd = buf->len - 1; /* may result in msgEnd < msgStart */ + msg[msgEnd] = '\0'; + } + + entry->priority = msg[0]; + entry->tag = msg + 1; + entry->tagLen = msgStart - 1; + entry->message = msg + msgStart; + entry->messageLen = (msgEnd < msgStart) ? 0 : (msgEnd - msgStart); + + return 0; } /* * 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, high; +static inline uint64_t get8LE(const uint8_t* src) { + uint32_t low, high; - low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); - high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24); - return ((uint64_t)high << 32) | (uint64_t)low; + low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24); + return ((uint64_t)high << 32) | (uint64_t)low; } static bool findChar(const char** cp, size_t* len, int c) { - while ((*len) && isspace(*(*cp))) { - ++(*cp); - --(*len); - } - if (c == INT_MAX) return *len; - if ((*len) && (*(*cp) == c)) { - ++(*cp); - --(*len); - return true; - } - return false; + while ((*len) && isspace(*(*cp))) { + ++(*cp); + --(*len); + } + if (c == INT_MAX) return *len; + if ((*len) && (*(*cp) == c)) { + ++(*cp); + --(*len); + return true; + } + return false; } /* @@ -650,340 +632,337 @@ static bool findChar(const char** cp, size_t* len, int c) { * Returns 0 on success, 1 on buffer full, -1 on failure. */ enum objectType { - TYPE_OBJECTS = '1', - TYPE_BYTES = '2', - TYPE_MILLISECONDS = '3', - TYPE_ALLOCATIONS = '4', - TYPE_ID = '5', - TYPE_PERCENT = '6' + TYPE_OBJECTS = '1', + TYPE_BYTES = '2', + TYPE_MILLISECONDS = '3', + TYPE_ALLOCATIONS = '4', + TYPE_ID = '5', + TYPE_PERCENT = '6' }; static int android_log_printBinaryEvent(const unsigned char** pEventData, - size_t* pEventDataLen, char** pOutBuf, size_t* pOutBufLen, - const char** fmtStr, size_t* fmtLen) -{ - const unsigned char* eventData = *pEventData; - size_t eventDataLen = *pEventDataLen; - char* outBuf = *pOutBuf; - char* outBufSave = outBuf; - size_t outBufLen = *pOutBufLen; - size_t outBufLenSave = outBufLen; - unsigned char type; - size_t outCount; - int result = 0; - const char* cp; - size_t len; - int64_t lval; - - if (eventDataLen < 1) return -1; - - type = *eventData++; - eventDataLen--; - - cp = NULL; + size_t* pEventDataLen, char** pOutBuf, + size_t* pOutBufLen, const char** fmtStr, + size_t* fmtLen) { + const unsigned char* eventData = *pEventData; + size_t eventDataLen = *pEventDataLen; + char* outBuf = *pOutBuf; + char* outBufSave = outBuf; + size_t outBufLen = *pOutBufLen; + size_t outBufLenSave = outBufLen; + unsigned char type; + size_t outCount; + int result = 0; + const char* cp; + size_t len; + int64_t lval; + + if (eventDataLen < 1) return -1; + + type = *eventData++; + eventDataLen--; + + cp = NULL; + len = 0; + if (fmtStr && *fmtStr && fmtLen && *fmtLen && **fmtStr) { + cp = *fmtStr; + len = *fmtLen; + } + /* + * event.logtag format specification: + * + * Optionally, after the tag names can be put a description for the value(s) + * of the tag. Description are in the format + * (<name>|data type[|data unit]) + * Multiple values are separated by commas. + * + * The data type is a number from the following values: + * 1: int + * 2: long + * 3: string + * 4: list + * 5: float + * + * The data unit is a number taken from the following list: + * 1: Number of objects + * 2: Number of bytes + * 3: Number of milliseconds + * 4: Number of allocations + * 5: Id + * 6: Percent + * Default value for data of type int/long is 2 (bytes). + */ + if (!cp || !findChar(&cp, &len, '(')) { len = 0; - if (fmtStr && *fmtStr && fmtLen && *fmtLen && **fmtStr) { - cp = *fmtStr; - len = *fmtLen; - } - /* - * event.logtag format specification: - * - * Optionally, after the tag names can be put a description for the value(s) - * of the tag. Description are in the format - * (<name>|data type[|data unit]) - * Multiple values are separated by commas. - * - * The data type is a number from the following values: - * 1: int - * 2: long - * 3: string - * 4: list - * 5: float - * - * The data unit is a number taken from the following list: - * 1: Number of objects - * 2: Number of bytes - * 3: Number of milliseconds - * 4: Number of allocations - * 5: Id - * 6: Percent - * Default value for data of type int/long is 2 (bytes). - */ - if (!cp || !findChar(&cp, &len, '(')) { + } else { + char* outBufLastSpace = NULL; + + findChar(&cp, &len, INT_MAX); + while (len && *cp && (*cp != '|') && (*cp != ')')) { + if (outBufLen <= 0) { + /* halt output */ + goto no_room; + } + outBufLastSpace = isspace(*cp) ? outBuf : NULL; + *outBuf = *cp; + ++outBuf; + ++cp; + --outBufLen; + --len; + } + if (outBufLastSpace) { + outBufLen += outBuf - outBufLastSpace; + outBuf = outBufLastSpace; + } + if (outBufLen <= 0) { + /* halt output */ + goto no_room; + } + if (outBufSave != outBuf) { + *outBuf = '='; + ++outBuf; + --outBufLen; + } + + if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) { + static const unsigned char typeTable[] = { + EVENT_TYPE_INT, EVENT_TYPE_LONG, EVENT_TYPE_STRING, EVENT_TYPE_LIST, + EVENT_TYPE_FLOAT + }; + + if ((*cp >= '1') && + (*cp < (char)('1' + (sizeof(typeTable) / sizeof(typeTable[0])))) && + (type != typeTable[(size_t)(*cp - '1')])) len = 0; - } else { - char* outBufLastSpace = NULL; - findChar(&cp, &len, INT_MAX); - while (len && *cp && (*cp != '|') && (*cp != ')')) { - if (outBufLen <= 0) { - /* halt output */ - goto no_room; - } - outBufLastSpace = isspace(*cp) ? outBuf : NULL; - *outBuf = *cp; - ++outBuf; - ++cp; - --outBufLen; - --len; - } - if (outBufLastSpace) { - outBufLen += outBuf - outBufLastSpace; - outBuf = outBufLastSpace; - } - if (outBufLen <= 0) { - /* halt output */ - goto no_room; - } - if (outBufSave != outBuf) { - *outBuf = '='; - ++outBuf; - --outBufLen; - } - - if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) { - static const unsigned char typeTable[] = { - EVENT_TYPE_INT, - EVENT_TYPE_LONG, - EVENT_TYPE_STRING, - EVENT_TYPE_LIST, - EVENT_TYPE_FLOAT - }; - - if ((*cp >= '1') && - (*cp < (char)('1' + (sizeof(typeTable) / sizeof(typeTable[0])))) && - (type != typeTable[(size_t)(*cp - '1')])) len = 0; - - if (len) { - ++cp; - --len; - } else { - /* reset the format */ - outBuf = outBufSave; - outBufLen = outBufLenSave; - } - } - } - outCount = 0; - lval = 0; - switch (type) { + if (len) { + ++cp; + --len; + } else { + /* reset the format */ + outBuf = outBufSave; + outBufLen = outBufLenSave; + } + } + } + outCount = 0; + lval = 0; + switch (type) { case EVENT_TYPE_INT: - /* 32-bit signed int */ - { - int32_t ival; + /* 32-bit signed int */ + { + int32_t ival; - if (eventDataLen < 4) return -1; - ival = get4LE(eventData); - eventData += 4; - eventDataLen -= 4; + if (eventDataLen < 4) return -1; + ival = get4LE(eventData); + eventData += 4; + eventDataLen -= 4; - lval = ival; - } - goto pr_lval; + lval = ival; + } + goto pr_lval; case EVENT_TYPE_LONG: - /* 64-bit signed long */ - if (eventDataLen < 8) return -1; - lval = get8LE(eventData); - eventData += 8; - eventDataLen -= 8; + /* 64-bit signed long */ + if (eventDataLen < 8) return -1; + lval = get8LE(eventData); + eventData += 8; + eventDataLen -= 8; pr_lval: - outCount = snprintf(outBuf, outBufLen, "%" PRId64, lval); + outCount = snprintf(outBuf, outBufLen, "%" PRId64, lval); + if (outCount < outBufLen) { + outBuf += outCount; + outBufLen -= outCount; + } else { + /* halt output */ + goto no_room; + } + break; + case EVENT_TYPE_FLOAT: + /* float */ + { + uint32_t ival; + float fval; + + if (eventDataLen < 4) return -1; + ival = get4LE(eventData); + fval = *(float*)&ival; + eventData += 4; + eventDataLen -= 4; + + outCount = snprintf(outBuf, outBufLen, "%f", fval); if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; + outBuf += outCount; + outBufLen -= outCount; } else { - /* halt output */ - goto no_room; - } - break; - case EVENT_TYPE_FLOAT: - /* float */ - { - uint32_t ival; - float fval; - - if (eventDataLen < 4) return -1; - ival = get4LE(eventData); - fval = *(float*)&ival; - eventData += 4; - eventDataLen -= 4; - - outCount = snprintf(outBuf, outBufLen, "%f", fval); - if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; - } else { - /* halt output */ - goto no_room; - } + /* halt output */ + goto no_room; } - break; + } + break; case EVENT_TYPE_STRING: - /* UTF-8 chars, not NULL-terminated */ - { - unsigned int strLen; - - if (eventDataLen < 4) return -1; - strLen = get4LE(eventData); - eventData += 4; - eventDataLen -= 4; - - if (eventDataLen < strLen) { - result = -1; /* mark truncated */ - strLen = eventDataLen; - } + /* UTF-8 chars, not NULL-terminated */ + { + unsigned int strLen; - if (cp && (strLen == 0)) { - /* reset the format if no content */ - outBuf = outBufSave; - outBufLen = outBufLenSave; - } - if (strLen < outBufLen) { - memcpy(outBuf, eventData, strLen); - outBuf += strLen; - outBufLen -= strLen; - } else { - if (outBufLen > 0) { - /* copy what we can */ - memcpy(outBuf, eventData, outBufLen); - outBuf += outBufLen; - outBufLen -= outBufLen; - } - if (!result) result = 1; /* if not truncated, return no room */ - } - eventData += strLen; - eventDataLen -= strLen; - if (result != 0) goto bail; - break; + if (eventDataLen < 4) return -1; + strLen = get4LE(eventData); + eventData += 4; + eventDataLen -= 4; + + if (eventDataLen < strLen) { + result = -1; /* mark truncated */ + strLen = eventDataLen; } - case EVENT_TYPE_LIST: - /* N items, all different types */ - { - unsigned char count; - int i; - if (eventDataLen < 1) return -1; + if (cp && (strLen == 0)) { + /* reset the format if no content */ + outBuf = outBufSave; + outBufLen = outBufLenSave; + } + if (strLen < outBufLen) { + memcpy(outBuf, eventData, strLen); + outBuf += strLen; + outBufLen -= strLen; + } else { + if (outBufLen > 0) { + /* copy what we can */ + memcpy(outBuf, eventData, outBufLen); + outBuf += outBufLen; + outBufLen -= outBufLen; + } + if (!result) result = 1; /* if not truncated, return no room */ + } + eventData += strLen; + eventDataLen -= strLen; + if (result != 0) goto bail; + break; + } + case EVENT_TYPE_LIST: + /* N items, all different types */ + { + unsigned char count; + int i; - count = *eventData++; - eventDataLen--; + if (eventDataLen < 1) return -1; - if (outBufLen <= 0) goto no_room; + count = *eventData++; + eventDataLen--; - *outBuf++ = '['; - outBufLen--; + if (outBufLen <= 0) goto no_room; - for (i = 0; i < count; i++) { - result = android_log_printBinaryEvent(&eventData, &eventDataLen, - &outBuf, &outBufLen, fmtStr, fmtLen); - if (result != 0) goto bail; + *outBuf++ = '['; + outBufLen--; - if (i < (count - 1)) { - if (outBufLen <= 0) goto no_room; - *outBuf++ = ','; - outBufLen--; - } - } + for (i = 0; i < count; i++) { + result = android_log_printBinaryEvent( + &eventData, &eventDataLen, &outBuf, &outBufLen, fmtStr, fmtLen); + if (result != 0) goto bail; + if (i < (count - 1)) { if (outBufLen <= 0) goto no_room; - - *outBuf++ = ']'; + *outBuf++ = ','; outBufLen--; + } } - break; + + if (outBufLen <= 0) goto no_room; + + *outBuf++ = ']'; + outBufLen--; + } + break; default: - fprintf(stderr, "Unknown binary event type %d\n", type); - return -1; - } - if (cp && len) { - if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) { - switch (*cp) { - case TYPE_OBJECTS: - outCount = 0; - /* outCount = snprintf(outBuf, outBufLen, " objects"); */ - break; - case TYPE_BYTES: - if ((lval != 0) && ((lval % 1024) == 0)) { - /* repaint with multiplier */ - static const char suffixTable[] = { 'K', 'M', 'G', 'T' }; - size_t idx = 0; - outBuf -= outCount; - outBufLen += outCount; - do { - lval /= 1024; - if ((lval % 1024) != 0) break; - } while (++idx < ((sizeof(suffixTable) / - sizeof(suffixTable[0])) - 1)); - outCount = snprintf(outBuf, outBufLen, - "%" PRId64 "%cB", - lval, suffixTable[idx]); - } else { - outCount = snprintf(outBuf, outBufLen, "B"); - } - break; - case TYPE_MILLISECONDS: - if (((lval <= -1000) || (1000 <= lval)) && - (outBufLen || (outBuf[-1] == '0'))) { - /* repaint as (fractional) seconds, possibly saving space */ - if (outBufLen) outBuf[0] = outBuf[-1]; - outBuf[-1] = outBuf[-2]; - outBuf[-2] = outBuf[-3]; - outBuf[-3] = '.'; - while ((outBufLen == 0) || (*outBuf == '0')) { - --outBuf; - ++outBufLen; - } - if (*outBuf != '.') { - ++outBuf; - --outBufLen; - } - outCount = snprintf(outBuf, outBufLen, "s"); - } else { - outCount = snprintf(outBuf, outBufLen, "ms"); - } - break; - case TYPE_ALLOCATIONS: - outCount = 0; - /* outCount = snprintf(outBuf, outBufLen, " allocations"); */ - break; - case TYPE_ID: - outCount = 0; - break; - case TYPE_PERCENT: - outCount = snprintf(outBuf, outBufLen, "%%"); - break; - default: /* ? */ - outCount = 0; - break; + fprintf(stderr, "Unknown binary event type %d\n", type); + return -1; + } + if (cp && len) { + if (findChar(&cp, &len, '|') && findChar(&cp, &len, INT_MAX)) { + switch (*cp) { + case TYPE_OBJECTS: + outCount = 0; + /* outCount = snprintf(outBuf, outBufLen, " objects"); */ + break; + case TYPE_BYTES: + if ((lval != 0) && ((lval % 1024) == 0)) { + /* repaint with multiplier */ + static const char suffixTable[] = { 'K', 'M', 'G', 'T' }; + size_t idx = 0; + outBuf -= outCount; + outBufLen += outCount; + do { + lval /= 1024; + if ((lval % 1024) != 0) break; + } while (++idx < + ((sizeof(suffixTable) / sizeof(suffixTable[0])) - 1)); + outCount = snprintf(outBuf, outBufLen, "%" PRId64 "%cB", lval, + suffixTable[idx]); + } else { + outCount = snprintf(outBuf, outBufLen, "B"); + } + break; + case TYPE_MILLISECONDS: + if (((lval <= -1000) || (1000 <= lval)) && + (outBufLen || (outBuf[-1] == '0'))) { + /* repaint as (fractional) seconds, possibly saving space */ + if (outBufLen) outBuf[0] = outBuf[-1]; + outBuf[-1] = outBuf[-2]; + outBuf[-2] = outBuf[-3]; + outBuf[-3] = '.'; + while ((outBufLen == 0) || (*outBuf == '0')) { + --outBuf; + ++outBufLen; } - ++cp; - --len; - if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; - } else if (outCount) { - /* halt output */ - goto no_room; + if (*outBuf != '.') { + ++outBuf; + --outBufLen; } - } - if (!findChar(&cp, &len, ')')) len = 0; - if (!findChar(&cp, &len, ',')) len = 0; - } + outCount = snprintf(outBuf, outBufLen, "s"); + } else { + outCount = snprintf(outBuf, outBufLen, "ms"); + } + break; + case TYPE_ALLOCATIONS: + outCount = 0; + /* outCount = snprintf(outBuf, outBufLen, " allocations"); */ + break; + case TYPE_ID: + outCount = 0; + break; + case TYPE_PERCENT: + outCount = snprintf(outBuf, outBufLen, "%%"); + break; + default: /* ? */ + outCount = 0; + break; + } + ++cp; + --len; + if (outCount < outBufLen) { + outBuf += outCount; + outBufLen -= outCount; + } else if (outCount) { + /* halt output */ + goto no_room; + } + } + if (!findChar(&cp, &len, ')')) len = 0; + if (!findChar(&cp, &len, ',')) len = 0; + } bail: - *pEventData = eventData; - *pEventDataLen = eventDataLen; - *pOutBuf = outBuf; - *pOutBufLen = outBufLen; - if (cp) { - *fmtStr = cp; - *fmtLen = len; - } - return result; + *pEventData = eventData; + *pEventDataLen = eventDataLen; + *pOutBuf = outBuf; + *pOutBufLen = outBufLen; + if (cp) { + *fmtStr = cp; + *fmtLen = len; + } + return result; no_room: - result = 1; - goto bail; + result = 1; + goto bail; } /** @@ -995,147 +974,144 @@ no_room: * here. */ LIBLOG_ABI_PUBLIC int android_log_processBinaryLogBuffer( - struct logger_entry *buf, - AndroidLogEntry *entry, - const EventTagMap *map __unused, /* only on !__ANDROID__ */ - char *messageBuf, int messageBufLen) -{ - size_t inCount; - uint32_t tagIndex; - const unsigned char* eventData; - - entry->message = NULL; - entry->messageLen = 0; - - entry->tv_sec = buf->sec; - entry->tv_nsec = buf->nsec; - entry->priority = ANDROID_LOG_INFO; - entry->uid = -1; - entry->pid = buf->pid; - entry->tid = buf->tid; - - /* - * Pull the tag out, fill in some additional details based on incoming - * buffer version (v3 adds lid, v4 adds uid). - */ - eventData = (const unsigned char*)buf->msg; - struct logger_entry_v2 *buf2 = (struct logger_entry_v2 *)buf; - if (buf2->hdr_size) { - if ((buf2->hdr_size < sizeof(((struct log_msg *)NULL)->entry_v1)) || - (buf2->hdr_size > sizeof(((struct log_msg *)NULL)->entry))) { - fprintf(stderr, "+++ LOG: entry illegal hdr_size\n"); - return -1; - } - eventData = ((unsigned char *)buf2) + buf2->hdr_size; - if ((buf2->hdr_size >= sizeof(struct logger_entry_v3)) && - (((struct logger_entry_v3 *)buf)->lid == LOG_ID_SECURITY)) { - entry->priority = ANDROID_LOG_WARN; - } - if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) { - entry->uid = ((struct logger_entry_v4 *)buf)->uid; - } - } - inCount = buf->len; - if (inCount < 4) return -1; - tagIndex = get4LE(eventData); - eventData += 4; - inCount -= 4; - - entry->tagLen = 0; - entry->tag = NULL; + struct logger_entry* buf, AndroidLogEntry* entry, + const EventTagMap* map __unused, /* only on !__ANDROID__ */ + char* messageBuf, int messageBufLen) { + size_t inCount; + uint32_t tagIndex; + const unsigned char* eventData; + + entry->message = NULL; + entry->messageLen = 0; + + entry->tv_sec = buf->sec; + entry->tv_nsec = buf->nsec; + entry->priority = ANDROID_LOG_INFO; + entry->uid = -1; + entry->pid = buf->pid; + entry->tid = buf->tid; + + /* + * Pull the tag out, fill in some additional details based on incoming + * buffer version (v3 adds lid, v4 adds uid). + */ + eventData = (const unsigned char*)buf->msg; + struct logger_entry_v2* buf2 = (struct logger_entry_v2*)buf; + if (buf2->hdr_size) { + if ((buf2->hdr_size < sizeof(((struct log_msg*)NULL)->entry_v1)) || + (buf2->hdr_size > sizeof(((struct log_msg*)NULL)->entry))) { + fprintf(stderr, "+++ LOG: entry illegal hdr_size\n"); + return -1; + } + eventData = ((unsigned char*)buf2) + buf2->hdr_size; + if ((buf2->hdr_size >= sizeof(struct logger_entry_v3)) && + (((struct logger_entry_v3*)buf)->lid == LOG_ID_SECURITY)) { + entry->priority = ANDROID_LOG_WARN; + } + if (buf2->hdr_size >= sizeof(struct logger_entry_v4)) { + entry->uid = ((struct logger_entry_v4*)buf)->uid; + } + } + inCount = buf->len; + if (inCount < 4) return -1; + tagIndex = get4LE(eventData); + eventData += 4; + inCount -= 4; + + entry->tagLen = 0; + entry->tag = NULL; #ifdef __ANDROID__ - if (map != NULL) { - entry->tag = android_lookupEventTag_len(map, &entry->tagLen, tagIndex); - } + if (map != NULL) { + entry->tag = android_lookupEventTag_len(map, &entry->tagLen, tagIndex); + } #endif - /* - * If we don't have a map, or didn't find the tag number in the map, - * stuff a generated tag value into the start of the output buffer and - * shift the buffer pointers down. - */ - if (entry->tag == NULL) { - size_t tagLen; - - tagLen = snprintf(messageBuf, messageBufLen, "[%" PRIu32 "]", tagIndex); - if (tagLen >= (size_t)messageBufLen) { - tagLen = messageBufLen - 1; - } - entry->tag = messageBuf; - entry->tagLen = tagLen; - messageBuf += tagLen + 1; - messageBufLen -= tagLen + 1; - } - - /* - * Format the event log data into the buffer. - */ - const char* fmtStr = NULL; - size_t fmtLen = 0; + /* + * If we don't have a map, or didn't find the tag number in the map, + * stuff a generated tag value into the start of the output buffer and + * shift the buffer pointers down. + */ + if (entry->tag == NULL) { + size_t tagLen; + + tagLen = snprintf(messageBuf, messageBufLen, "[%" PRIu32 "]", tagIndex); + if (tagLen >= (size_t)messageBufLen) { + tagLen = messageBufLen - 1; + } + entry->tag = messageBuf; + entry->tagLen = tagLen; + messageBuf += tagLen + 1; + messageBufLen -= tagLen + 1; + } + + /* + * Format the event log data into the buffer. + */ + const char* fmtStr = NULL; + size_t fmtLen = 0; #ifdef __ANDROID__ - if (descriptive_output && map) { - fmtStr = android_lookupEventFormat_len(map, &fmtLen, tagIndex); - } + if (descriptive_output && map) { + fmtStr = android_lookupEventFormat_len(map, &fmtLen, tagIndex); + } #endif - char* outBuf = messageBuf; - size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */ - int result = 0; - - if ((inCount > 0) || fmtLen) { - result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, - &outRemaining, &fmtStr, &fmtLen); - } - if ((result == 1) && fmtStr) { - /* We overflowed :-(, let's repaint the line w/o format dressings */ - eventData = (const unsigned char*)buf->msg; - if (buf2->hdr_size) { - eventData = ((unsigned char *)buf2) + buf2->hdr_size; - } - eventData += 4; - outBuf = messageBuf; - outRemaining = messageBufLen - 1; - result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, - &outRemaining, NULL, NULL); - } - if (result < 0) { - fprintf(stderr, "Binary log entry conversion failed\n"); - } - if (result) { - if (!outRemaining) { - /* make space to leave an indicator */ - --outBuf; - ++outRemaining; - } - *outBuf++ = (result < 0) ? '!' : '^'; /* Error or Truncation? */ - outRemaining--; - /* pretend we ate all the data to prevent log stutter */ - inCount = 0; - if (result > 0) result = 0; - } - - /* eat the silly terminating '\n' */ - if (inCount == 1 && *eventData == '\n') { - eventData++; - inCount--; - } + char* outBuf = messageBuf; + size_t outRemaining = messageBufLen - 1; /* leave one for nul byte */ + int result = 0; - if (inCount != 0) { - fprintf(stderr, - "Warning: leftover binary log data (%zu bytes)\n", inCount); + if ((inCount > 0) || fmtLen) { + result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, + &outRemaining, &fmtStr, &fmtLen); + } + if ((result == 1) && fmtStr) { + /* We overflowed :-(, let's repaint the line w/o format dressings */ + eventData = (const unsigned char*)buf->msg; + if (buf2->hdr_size) { + eventData = ((unsigned char*)buf2) + buf2->hdr_size; } - - /* - * Terminate the buffer. The NUL byte does not count as part of - * entry->messageLen. - */ - *outBuf = '\0'; - entry->messageLen = outBuf - messageBuf; - assert(entry->messageLen == (messageBufLen - 1) - outRemaining); - - entry->message = messageBuf; - - return result; + eventData += 4; + outBuf = messageBuf; + outRemaining = messageBufLen - 1; + result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, + &outRemaining, NULL, NULL); + } + if (result < 0) { + fprintf(stderr, "Binary log entry conversion failed\n"); + } + if (result) { + if (!outRemaining) { + /* make space to leave an indicator */ + --outBuf; + ++outRemaining; + } + *outBuf++ = (result < 0) ? '!' : '^'; /* Error or Truncation? */ + outRemaining--; + /* pretend we ate all the data to prevent log stutter */ + inCount = 0; + if (result > 0) result = 0; + } + + /* eat the silly terminating '\n' */ + if (inCount == 1 && *eventData == '\n') { + eventData++; + inCount--; + } + + if (inCount != 0) { + fprintf(stderr, "Warning: leftover binary log data (%zu bytes)\n", inCount); + } + + /* + * Terminate the buffer. The NUL byte does not count as part of + * entry->messageLen. + */ + *outBuf = '\0'; + entry->messageLen = outBuf - messageBuf; + assert(entry->messageLen == (messageBufLen - 1) - outRemaining); + + entry->message = messageBuf; + + return result; } /* @@ -1150,388 +1126,377 @@ LIBLOG_ABI_PUBLIC int android_log_processBinaryLogBuffer( * _also_ be part of libutils/Unicode.cpp if its usefullness needs to * propagate globally. */ -LIBLOG_WEAK ssize_t utf8_character_length(const char *src, size_t len) -{ - const char *cur = src; - const char first_char = *cur++; - static const uint32_t kUnicodeMaxCodepoint = 0x0010FFFF; - int32_t mask, to_ignore_mask; - size_t num_to_read; - uint32_t utf32; - - if ((first_char & 0x80) == 0) { /* ASCII */ - return first_char ? 1 : -1; - } - - /* - * (UTF-8's character must not be like 10xxxxxx, - * but 110xxxxx, 1110xxxx, ... or 1111110x) - */ - if ((first_char & 0x40) == 0) { - return -1; - } +LIBLOG_WEAK ssize_t utf8_character_length(const char* src, size_t len) { + const char* cur = src; + const char first_char = *cur++; + static const uint32_t kUnicodeMaxCodepoint = 0x0010FFFF; + int32_t mask, to_ignore_mask; + size_t num_to_read; + uint32_t utf32; + + if ((first_char & 0x80) == 0) { /* ASCII */ + return first_char ? 1 : -1; + } + + /* + * (UTF-8's character must not be like 10xxxxxx, + * but 110xxxxx, 1110xxxx, ... or 1111110x) + */ + if ((first_char & 0x40) == 0) { + return -1; + } - for (utf32 = 1, num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80; - num_to_read < 5 && (first_char & mask); - num_to_read++, to_ignore_mask |= mask, mask >>= 1) { - if (num_to_read > len) { - return -1; - } - if ((*cur & 0xC0) != 0x80) { /* can not be 10xxxxxx? */ - return -1; - } - utf32 = (utf32 << 6) + (*cur++ & 0b00111111); + for (utf32 = 1, num_to_read = 1, mask = 0x40, to_ignore_mask = 0x80; + num_to_read < 5 && (first_char & mask); + num_to_read++, to_ignore_mask |= mask, mask >>= 1) { + if (num_to_read > len) { + return -1; } - /* "first_char" must be (110xxxxx - 11110xxx) */ - if (num_to_read >= 5) { - return -1; + if ((*cur & 0xC0) != 0x80) { /* can not be 10xxxxxx? */ + return -1; } - to_ignore_mask |= mask; - utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1)); - if (utf32 > kUnicodeMaxCodepoint) { - return -1; - } - return num_to_read; + utf32 = (utf32 << 6) + (*cur++ & 0b00111111); + } + /* "first_char" must be (110xxxxx - 11110xxx) */ + if (num_to_read >= 5) { + return -1; + } + to_ignore_mask |= mask; + utf32 |= ((~to_ignore_mask) & first_char) << (6 * (num_to_read - 1)); + if (utf32 > kUnicodeMaxCodepoint) { + return -1; + } + return num_to_read; } /* * Convert to printable from message to p buffer, return string length. If p is * NULL, do not copy, but still return the expected string length. */ -static size_t convertPrintable(char *p, const char *message, size_t messageLen) -{ - char *begin = p; - bool print = p != NULL; - - while (messageLen) { - char buf[6]; - ssize_t len = sizeof(buf) - 1; - if ((size_t)len > messageLen) { - len = messageLen; - } - len = utf8_character_length(message, len); - - if (len < 0) { - snprintf(buf, sizeof(buf), - ((messageLen > 1) && isdigit(message[1])) - ? "\\%03o" - : "\\%o", - *message & 0377); - len = 1; - } else { - buf[0] = '\0'; - if (len == 1) { - if (*message == '\a') { - strcpy(buf, "\\a"); - } else if (*message == '\b') { - strcpy(buf, "\\b"); - } else if (*message == '\t') { - strcpy(buf, "\t"); /* Do not escape tabs */ - } else if (*message == '\v') { - strcpy(buf, "\\v"); - } else if (*message == '\f') { - strcpy(buf, "\\f"); - } else if (*message == '\r') { - strcpy(buf, "\\r"); - } else if (*message == '\\') { - strcpy(buf, "\\\\"); - } else if ((*message < ' ') || (*message & 0x80)) { - snprintf(buf, sizeof(buf), "\\%o", *message & 0377); - } - } - if (!buf[0]) { - strncpy(buf, message, len); - buf[len] = '\0'; - } - } - if (print) { - strcpy(p, buf); +static size_t convertPrintable(char* p, const char* message, size_t messageLen) { + char* begin = p; + bool print = p != NULL; + + while (messageLen) { + char buf[6]; + ssize_t len = sizeof(buf) - 1; + if ((size_t)len > messageLen) { + len = messageLen; + } + len = utf8_character_length(message, len); + + if (len < 0) { + snprintf(buf, sizeof(buf), + ((messageLen > 1) && isdigit(message[1])) ? "\\%03o" : "\\%o", + *message & 0377); + len = 1; + } else { + buf[0] = '\0'; + if (len == 1) { + if (*message == '\a') { + strcpy(buf, "\\a"); + } else if (*message == '\b') { + strcpy(buf, "\\b"); + } else if (*message == '\t') { + strcpy(buf, "\t"); /* Do not escape tabs */ + } else if (*message == '\v') { + strcpy(buf, "\\v"); + } else if (*message == '\f') { + strcpy(buf, "\\f"); + } else if (*message == '\r') { + strcpy(buf, "\\r"); + } else if (*message == '\\') { + strcpy(buf, "\\\\"); + } else if ((*message < ' ') || (*message & 0x80)) { + snprintf(buf, sizeof(buf), "\\%o", *message & 0377); } - p += strlen(buf); - message += len; - messageLen -= len; - } - return p - begin; + } + if (!buf[0]) { + strncpy(buf, message, len); + buf[len] = '\0'; + } + } + if (print) { + strcpy(p, buf); + } + p += strlen(buf); + message += len; + messageLen -= len; + } + return p - begin; } -static char *readSeconds(char *e, struct timespec *t) -{ - unsigned long multiplier; - char *p; - t->tv_sec = strtoul(e, &p, 10); - if (*p != '.') { - return NULL; - } - t->tv_nsec = 0; - multiplier = NS_PER_SEC; - while (isdigit(*++p) && (multiplier /= 10)) { - t->tv_nsec += (*p - '0') * multiplier; - } - return p; +static char* readSeconds(char* e, struct timespec* t) { + unsigned long multiplier; + char* p; + t->tv_sec = strtoul(e, &p, 10); + if (*p != '.') { + return NULL; + } + t->tv_nsec = 0; + multiplier = NS_PER_SEC; + while (isdigit(*++p) && (multiplier /= 10)) { + t->tv_nsec += (*p - '0') * multiplier; + } + return p; } -static struct timespec *sumTimespec(struct timespec *left, - struct timespec *right) -{ - left->tv_nsec += right->tv_nsec; - left->tv_sec += right->tv_sec; - if (left->tv_nsec >= (long)NS_PER_SEC) { - left->tv_nsec -= NS_PER_SEC; - left->tv_sec += 1; - } - return left; +static struct timespec* sumTimespec(struct timespec* left, + struct timespec* right) { + left->tv_nsec += right->tv_nsec; + left->tv_sec += right->tv_sec; + if (left->tv_nsec >= (long)NS_PER_SEC) { + left->tv_nsec -= NS_PER_SEC; + left->tv_sec += 1; + } + return left; } -static struct timespec *subTimespec(struct timespec *result, - struct timespec *left, - struct timespec *right) -{ - result->tv_nsec = left->tv_nsec - right->tv_nsec; - result->tv_sec = left->tv_sec - right->tv_sec; - if (result->tv_nsec < 0) { - result->tv_nsec += NS_PER_SEC; - result->tv_sec -= 1; - } - return result; +static struct timespec* subTimespec(struct timespec* result, + struct timespec* left, + struct timespec* right) { + result->tv_nsec = left->tv_nsec - right->tv_nsec; + result->tv_sec = left->tv_sec - right->tv_sec; + if (result->tv_nsec < 0) { + result->tv_nsec += NS_PER_SEC; + result->tv_sec -= 1; + } + return result; } -static long long nsecTimespec(struct timespec *now) -{ - return (long long)now->tv_sec * NS_PER_SEC + now->tv_nsec; +static long long nsecTimespec(struct timespec* now) { + return (long long)now->tv_sec * NS_PER_SEC + now->tv_nsec; } #ifdef __ANDROID__ -static void convertMonotonic(struct timespec *result, - const AndroidLogEntry *entry) -{ - struct listnode *node; - struct conversionList { - struct listnode node; /* first */ - struct timespec time; - struct timespec convert; - } *list, *next; - struct timespec time, convert; - - /* If we do not have a conversion list, build one up */ - if (list_empty(&convertHead)) { - bool suspended_pending = false; - struct timespec suspended_monotonic = { 0, 0 }; - struct timespec suspended_diff = { 0, 0 }; - - /* - * Read dmesg for _some_ synchronization markers and insert - * Anything in the Android Logger before the dmesg logging span will - * be highly suspect regarding the monotonic time calculations. - */ - FILE *p = popen("/system/bin/dmesg", "re"); - if (p) { - char *line = NULL; - size_t len = 0; - while (getline(&line, &len, p) > 0) { - static const char suspend[] = "PM: suspend entry "; - static const char resume[] = "PM: suspend exit "; - static const char healthd[] = "healthd"; - static const char battery[] = ": battery "; - static const char suspended[] = "Suspended for "; - struct timespec monotonic; - struct tm tm; - char *cp, *e = line; - bool add_entry = true; - - if (*e == '<') { - while (*e && (*e != '>')) { - ++e; - } - if (*e != '>') { - continue; - } - } - if (*e != '[') { - continue; - } - while (*++e == ' ') { - ; - } - e = readSeconds(e, &monotonic); - if (!e || (*e != ']')) { - continue; - } - - if ((e = strstr(e, suspend))) { - e += sizeof(suspend) - 1; - } else if ((e = strstr(line, resume))) { - e += sizeof(resume) - 1; - } else if (((e = strstr(line, healthd))) - && ((e = strstr(e + sizeof(healthd) - 1, battery)))) { - /* NB: healthd is roughly 150us late, worth the price to - * deal with ntp-induced or hardware clock drift. */ - e += sizeof(battery) - 1; - } else if ((e = strstr(line, suspended))) { - e += sizeof(suspended) - 1; - e = readSeconds(e, &time); - if (!e) { - continue; - } - add_entry = false; - suspended_pending = true; - suspended_monotonic = monotonic; - suspended_diff = time; - } else { - continue; - } - if (add_entry) { - /* look for "????-??-?? ??:??:??.????????? UTC" */ - cp = strstr(e, " UTC"); - if (!cp || ((cp - e) < 29) || (cp[-10] != '.')) { - continue; - } - e = cp - 29; - cp = readSeconds(cp - 10, &time); - if (!cp) { - continue; - } - cp = strptime(e, "%Y-%m-%d %H:%M:%S.", &tm); - if (!cp) { - continue; - } - cp = getenv(tz); - if (cp) { - cp = strdup(cp); - } - setenv(tz, utc, 1); - time.tv_sec = mktime(&tm); - if (cp) { - setenv(tz, cp, 1); - free(cp); - } else { - unsetenv(tz); - } - list = calloc(1, sizeof(struct conversionList)); - list_init(&list->node); - list->time = time; - subTimespec(&list->convert, &time, &monotonic); - list_add_tail(&convertHead, &list->node); - } - if (suspended_pending && !list_empty(&convertHead)) { - list = node_to_item(list_tail(&convertHead), - struct conversionList, node); - if (subTimespec(&time, - subTimespec(&time, - &list->time, - &list->convert), - &suspended_monotonic)->tv_sec > 0) { - /* resume, what is convert factor before? */ - subTimespec(&convert, &list->convert, &suspended_diff); - } else { - /* suspend */ - convert = list->convert; - } - time = suspended_monotonic; - sumTimespec(&time, &convert); - /* breakpoint just before sleep */ - list = calloc(1, sizeof(struct conversionList)); - list_init(&list->node); - list->time = time; - list->convert = convert; - list_add_tail(&convertHead, &list->node); - /* breakpoint just after sleep */ - list = calloc(1, sizeof(struct conversionList)); - list_init(&list->node); - list->time = time; - sumTimespec(&list->time, &suspended_diff); - list->convert = convert; - sumTimespec(&list->convert, &suspended_diff); - list_add_tail(&convertHead, &list->node); - suspended_pending = false; - } - } - pclose(p); +static void convertMonotonic(struct timespec* result, + const AndroidLogEntry* entry) { + struct listnode* node; + struct conversionList { + struct listnode node; /* first */ + struct timespec time; + struct timespec convert; + } * list, *next; + struct timespec time, convert; + + /* If we do not have a conversion list, build one up */ + if (list_empty(&convertHead)) { + bool suspended_pending = false; + struct timespec suspended_monotonic = { 0, 0 }; + struct timespec suspended_diff = { 0, 0 }; + + /* + * Read dmesg for _some_ synchronization markers and insert + * Anything in the Android Logger before the dmesg logging span will + * be highly suspect regarding the monotonic time calculations. + */ + FILE* p = popen("/system/bin/dmesg", "re"); + if (p) { + char* line = NULL; + size_t len = 0; + while (getline(&line, &len, p) > 0) { + static const char suspend[] = "PM: suspend entry "; + static const char resume[] = "PM: suspend exit "; + static const char healthd[] = "healthd"; + static const char battery[] = ": battery "; + static const char suspended[] = "Suspended for "; + struct timespec monotonic; + struct tm tm; + char *cp, *e = line; + bool add_entry = true; + + if (*e == '<') { + while (*e && (*e != '>')) { + ++e; + } + if (*e != '>') { + continue; + } } - /* last entry is our current time conversion */ - list = calloc(1, sizeof(struct conversionList)); - list_init(&list->node); - clock_gettime(CLOCK_REALTIME, &list->time); - clock_gettime(CLOCK_MONOTONIC, &convert); - clock_gettime(CLOCK_MONOTONIC, &time); - /* Correct for instant clock_gettime latency (syscall or ~30ns) */ - subTimespec(&time, &convert, subTimespec(&time, &time, &convert)); - /* Calculate conversion factor */ - subTimespec(&list->convert, &list->time, &time); - list_add_tail(&convertHead, &list->node); - if (suspended_pending) { - /* manufacture a suspend @ point before */ - subTimespec(&convert, &list->convert, &suspended_diff); - time = suspended_monotonic; - sumTimespec(&time, &convert); - /* breakpoint just after sleep */ - list = calloc(1, sizeof(struct conversionList)); - list_init(&list->node); - list->time = time; - sumTimespec(&list->time, &suspended_diff); - list->convert = convert; - sumTimespec(&list->convert, &suspended_diff); - list_add_head(&convertHead, &list->node); - /* breakpoint just before sleep */ - list = calloc(1, sizeof(struct conversionList)); - list_init(&list->node); - list->time = time; - list->convert = convert; - list_add_head(&convertHead, &list->node); + if (*e != '[') { + continue; } - } - - /* Find the breakpoint in the conversion list */ - list = node_to_item(list_head(&convertHead), struct conversionList, node); - next = NULL; - list_for_each(node, &convertHead) { - next = node_to_item(node, struct conversionList, node); - if (entry->tv_sec < next->time.tv_sec) { - break; - } else if (entry->tv_sec == next->time.tv_sec) { - if (entry->tv_nsec < next->time.tv_nsec) { - break; - } + while (*++e == ' ') { + ; + } + e = readSeconds(e, &monotonic); + if (!e || (*e != ']')) { + continue; } - list = next; - } - /* blend time from one breakpoint to the next */ - convert = list->convert; - if (next) { - unsigned long long total, run; - - total = nsecTimespec(subTimespec(&time, &next->time, &list->time)); - time.tv_sec = entry->tv_sec; - time.tv_nsec = entry->tv_nsec; - run = nsecTimespec(subTimespec(&time, &time, &list->time)); - if (run < total) { - long long crun; - - float f = nsecTimespec(subTimespec(&time, &next->convert, &convert)); - f *= run; - f /= total; - crun = f; - convert.tv_sec += crun / (long long)NS_PER_SEC; - if (crun < 0) { - convert.tv_nsec -= (-crun) % NS_PER_SEC; - if (convert.tv_nsec < 0) { - convert.tv_nsec += NS_PER_SEC; - convert.tv_sec -= 1; - } - } else { - convert.tv_nsec += crun % NS_PER_SEC; - if (convert.tv_nsec >= (long)NS_PER_SEC) { - convert.tv_nsec -= NS_PER_SEC; - convert.tv_sec += 1; - } - } + if ((e = strstr(e, suspend))) { + e += sizeof(suspend) - 1; + } else if ((e = strstr(line, resume))) { + e += sizeof(resume) - 1; + } else if (((e = strstr(line, healthd))) && + ((e = strstr(e + sizeof(healthd) - 1, battery)))) { + /* NB: healthd is roughly 150us late, worth the price to + * deal with ntp-induced or hardware clock drift. */ + e += sizeof(battery) - 1; + } else if ((e = strstr(line, suspended))) { + e += sizeof(suspended) - 1; + e = readSeconds(e, &time); + if (!e) { + continue; + } + add_entry = false; + suspended_pending = true; + suspended_monotonic = monotonic; + suspended_diff = time; + } else { + continue; + } + if (add_entry) { + /* look for "????-??-?? ??:??:??.????????? UTC" */ + cp = strstr(e, " UTC"); + if (!cp || ((cp - e) < 29) || (cp[-10] != '.')) { + continue; + } + e = cp - 29; + cp = readSeconds(cp - 10, &time); + if (!cp) { + continue; + } + cp = strptime(e, "%Y-%m-%d %H:%M:%S.", &tm); + if (!cp) { + continue; + } + cp = getenv(tz); + if (cp) { + cp = strdup(cp); + } + setenv(tz, utc, 1); + time.tv_sec = mktime(&tm); + if (cp) { + setenv(tz, cp, 1); + free(cp); + } else { + unsetenv(tz); + } + list = calloc(1, sizeof(struct conversionList)); + list_init(&list->node); + list->time = time; + subTimespec(&list->convert, &time, &monotonic); + list_add_tail(&convertHead, &list->node); + } + if (suspended_pending && !list_empty(&convertHead)) { + list = node_to_item(list_tail(&convertHead), struct conversionList, + node); + if (subTimespec(&time, subTimespec(&time, &list->time, &list->convert), + &suspended_monotonic) + ->tv_sec > 0) { + /* resume, what is convert factor before? */ + subTimespec(&convert, &list->convert, &suspended_diff); + } else { + /* suspend */ + convert = list->convert; + } + time = suspended_monotonic; + sumTimespec(&time, &convert); + /* breakpoint just before sleep */ + list = calloc(1, sizeof(struct conversionList)); + list_init(&list->node); + list->time = time; + list->convert = convert; + list_add_tail(&convertHead, &list->node); + /* breakpoint just after sleep */ + list = calloc(1, sizeof(struct conversionList)); + list_init(&list->node); + list->time = time; + sumTimespec(&list->time, &suspended_diff); + list->convert = convert; + sumTimespec(&list->convert, &suspended_diff); + list_add_tail(&convertHead, &list->node); + suspended_pending = false; } + } + pclose(p); + } + /* last entry is our current time conversion */ + list = calloc(1, sizeof(struct conversionList)); + list_init(&list->node); + clock_gettime(CLOCK_REALTIME, &list->time); + clock_gettime(CLOCK_MONOTONIC, &convert); + clock_gettime(CLOCK_MONOTONIC, &time); + /* Correct for instant clock_gettime latency (syscall or ~30ns) */ + subTimespec(&time, &convert, subTimespec(&time, &time, &convert)); + /* Calculate conversion factor */ + subTimespec(&list->convert, &list->time, &time); + list_add_tail(&convertHead, &list->node); + if (suspended_pending) { + /* manufacture a suspend @ point before */ + subTimespec(&convert, &list->convert, &suspended_diff); + time = suspended_monotonic; + sumTimespec(&time, &convert); + /* breakpoint just after sleep */ + list = calloc(1, sizeof(struct conversionList)); + list_init(&list->node); + list->time = time; + sumTimespec(&list->time, &suspended_diff); + list->convert = convert; + sumTimespec(&list->convert, &suspended_diff); + list_add_head(&convertHead, &list->node); + /* breakpoint just before sleep */ + list = calloc(1, sizeof(struct conversionList)); + list_init(&list->node); + list->time = time; + list->convert = convert; + list_add_head(&convertHead, &list->node); + } + } + + /* Find the breakpoint in the conversion list */ + list = node_to_item(list_head(&convertHead), struct conversionList, node); + next = NULL; + list_for_each(node, &convertHead) { + next = node_to_item(node, struct conversionList, node); + if (entry->tv_sec < next->time.tv_sec) { + break; + } else if (entry->tv_sec == next->time.tv_sec) { + if (entry->tv_nsec < next->time.tv_nsec) { + break; + } + } + list = next; + } + + /* blend time from one breakpoint to the next */ + convert = list->convert; + if (next) { + unsigned long long total, run; + + total = nsecTimespec(subTimespec(&time, &next->time, &list->time)); + time.tv_sec = entry->tv_sec; + time.tv_nsec = entry->tv_nsec; + run = nsecTimespec(subTimespec(&time, &time, &list->time)); + if (run < total) { + long long crun; + + float f = nsecTimespec(subTimespec(&time, &next->convert, &convert)); + f *= run; + f /= total; + crun = f; + convert.tv_sec += crun / (long long)NS_PER_SEC; + if (crun < 0) { + convert.tv_nsec -= (-crun) % NS_PER_SEC; + if (convert.tv_nsec < 0) { + convert.tv_nsec += NS_PER_SEC; + convert.tv_sec -= 1; + } + } else { + convert.tv_nsec += crun % NS_PER_SEC; + if (convert.tv_nsec >= (long)NS_PER_SEC) { + convert.tv_nsec -= NS_PER_SEC; + convert.tv_sec += 1; + } + } } + } - /* Apply the correction factor */ - result->tv_sec = entry->tv_sec; - result->tv_nsec = entry->tv_nsec; - subTimespec(result, result, &convert); + /* Apply the correction factor */ + result->tv_sec = entry->tv_sec; + result->tv_nsec = entry->tv_nsec; + subTimespec(result, result, &convert); } #endif @@ -1543,302 +1508,295 @@ static void convertMonotonic(struct timespec *result, * Returns NULL on malloc error */ -LIBLOG_ABI_PUBLIC char *android_log_formatLogLine ( - AndroidLogFormat *p_format, - char *defaultBuffer, - size_t defaultBufferSize, - const AndroidLogEntry *entry, - size_t *p_outLength) -{ +LIBLOG_ABI_PUBLIC char* android_log_formatLogLine(AndroidLogFormat* p_format, + char* defaultBuffer, + size_t defaultBufferSize, + const AndroidLogEntry* entry, + size_t* p_outLength) { #if !defined(_WIN32) - struct tm tmBuf; + struct tm tmBuf; #endif - struct tm* ptm; - /* good margin, 23+nul for msec, 26+nul for usec, 29+nul to nsec */ - char timeBuf[64]; - char prefixBuf[128], suffixBuf[128]; - char priChar; - int prefixSuffixIsHeaderFooter = 0; - char *ret; - time_t now; - unsigned long nsec; - - priChar = filterPriToChar(entry->priority); - size_t prefixLen = 0, suffixLen = 0; - size_t len; - - /* - * Get the current date/time in pretty form - * - * It's often useful when examining a log with "less" to jump to - * a specific point in the file by searching for the date/time stamp. - * For this reason it's very annoying to have regexp meta characters - * in the time stamp. Don't use forward slashes, parenthesis, - * brackets, asterisks, or other special chars here. - * - * The caller may have affected the timezone environment, this is - * expected to be sensitive to that. - */ - now = entry->tv_sec; - nsec = entry->tv_nsec; + struct tm* ptm; + /* good margin, 23+nul for msec, 26+nul for usec, 29+nul to nsec */ + char timeBuf[64]; + char prefixBuf[128], suffixBuf[128]; + char priChar; + int prefixSuffixIsHeaderFooter = 0; + char* ret; + time_t now; + unsigned long nsec; + + priChar = filterPriToChar(entry->priority); + size_t prefixLen = 0, suffixLen = 0; + size_t len; + + /* + * Get the current date/time in pretty form + * + * It's often useful when examining a log with "less" to jump to + * a specific point in the file by searching for the date/time stamp. + * For this reason it's very annoying to have regexp meta characters + * in the time stamp. Don't use forward slashes, parenthesis, + * brackets, asterisks, or other special chars here. + * + * The caller may have affected the timezone environment, this is + * expected to be sensitive to that. + */ + now = entry->tv_sec; + nsec = entry->tv_nsec; #if __ANDROID__ - if (p_format->monotonic_output) { - /* prevent convertMonotonic from being called if logd is monotonic */ - if (android_log_clockid() != CLOCK_MONOTONIC) { - struct timespec time; - convertMonotonic(&time, entry); - now = time.tv_sec; - nsec = time.tv_nsec; - } - } + if (p_format->monotonic_output) { + /* prevent convertMonotonic from being called if logd is monotonic */ + if (android_log_clockid() != CLOCK_MONOTONIC) { + struct timespec time; + convertMonotonic(&time, entry); + now = time.tv_sec; + nsec = time.tv_nsec; + } + } #endif - if (now < 0) { - nsec = NS_PER_SEC - nsec; - } - if (p_format->epoch_output || p_format->monotonic_output) { - ptm = NULL; - snprintf(timeBuf, sizeof(timeBuf), - p_format->monotonic_output ? "%6lld" : "%19lld", - (long long)now); - } else { + if (now < 0) { + nsec = NS_PER_SEC - nsec; + } + if (p_format->epoch_output || p_format->monotonic_output) { + ptm = NULL; + snprintf(timeBuf, sizeof(timeBuf), + p_format->monotonic_output ? "%6lld" : "%19lld", (long long)now); + } else { #if !defined(_WIN32) - ptm = localtime_r(&now, &tmBuf); + ptm = localtime_r(&now, &tmBuf); #else - ptm = localtime(&now); + ptm = localtime(&now); #endif - strftime(timeBuf, sizeof(timeBuf), - &"%Y-%m-%d %H:%M:%S"[p_format->year_output ? 0 : 3], - ptm); - } - len = strlen(timeBuf); - if (p_format->nsec_time_output) { - len += snprintf(timeBuf + len, sizeof(timeBuf) - len, - ".%09ld", nsec); - } else if (p_format->usec_time_output) { - len += snprintf(timeBuf + len, sizeof(timeBuf) - len, - ".%06ld", nsec / US_PER_NSEC); - } else { - len += snprintf(timeBuf + len, sizeof(timeBuf) - len, - ".%03ld", nsec / MS_PER_NSEC); - } - if (p_format->zone_output && ptm) { - strftime(timeBuf + len, sizeof(timeBuf) - len, " %z", ptm); - } - - /* - * Construct a buffer containing the log header and log message. - */ - if (p_format->colored_output) { - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[38;5;%dm", - colorFromPri(entry->priority)); - prefixLen = MIN(prefixLen, sizeof(prefixBuf)); - suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), "\x1B[0m"); - suffixLen = MIN(suffixLen, sizeof(suffixBuf)); - } - - char uid[16]; - uid[0] = '\0'; - if (p_format->uid_output) { - if (entry->uid >= 0) { - - /* - * This code is Android specific, bionic guarantees that - * calls to non-reentrant getpwuid() are thread safe. - */ + strftime(timeBuf, sizeof(timeBuf), + &"%Y-%m-%d %H:%M:%S"[p_format->year_output ? 0 : 3], ptm); + } + len = strlen(timeBuf); + if (p_format->nsec_time_output) { + len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%09ld", nsec); + } else if (p_format->usec_time_output) { + len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%06ld", + nsec / US_PER_NSEC); + } else { + len += snprintf(timeBuf + len, sizeof(timeBuf) - len, ".%03ld", + nsec / MS_PER_NSEC); + } + if (p_format->zone_output && ptm) { + strftime(timeBuf + len, sizeof(timeBuf) - len, " %z", ptm); + } + + /* + * Construct a buffer containing the log header and log message. + */ + if (p_format->colored_output) { + prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "\x1B[38;5;%dm", + colorFromPri(entry->priority)); + prefixLen = MIN(prefixLen, sizeof(prefixBuf)); + suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), "\x1B[0m"); + suffixLen = MIN(suffixLen, sizeof(suffixBuf)); + } + + char uid[16]; + uid[0] = '\0'; + if (p_format->uid_output) { + if (entry->uid >= 0) { +/* + * This code is Android specific, bionic guarantees that + * calls to non-reentrant getpwuid() are thread safe. + */ #if !defined(__MINGW32__) #if (FAKE_LOG_DEVICE == 0) #ifndef __BIONIC__ -#warning "This code assumes that getpwuid is thread safe, only true with Bionic!" +#warning \ + "This code assumes that getpwuid is thread safe, only true with Bionic!" #endif #endif - struct passwd* pwd = getpwuid(entry->uid); - if (pwd && (strlen(pwd->pw_name) <= 5)) { - snprintf(uid, sizeof(uid), "%5s:", pwd->pw_name); - } else + struct passwd* pwd = getpwuid(entry->uid); + if (pwd && (strlen(pwd->pw_name) <= 5)) { + snprintf(uid, sizeof(uid), "%5s:", pwd->pw_name); + } else #endif - { - /* Not worth parsing package list, names all longer than 5 */ - snprintf(uid, sizeof(uid), "%5d:", entry->uid); - } - } else { - snprintf(uid, sizeof(uid), " "); - } - } - - switch (p_format->format) { - case FORMAT_TAG: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%c/%-8.*s: ", priChar, (int)entry->tagLen, entry->tag); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_PROCESS: - len = snprintf(suffixBuf + suffixLen, sizeof(suffixBuf) - suffixLen, - " (%.*s)\n", (int)entry->tagLen, entry->tag); - suffixLen += MIN(len, sizeof(suffixBuf) - suffixLen); - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%c(%s%5d) ", priChar, uid, entry->pid); - break; - case FORMAT_THREAD: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%c(%s%5d:%5d) ", priChar, uid, entry->pid, entry->tid); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_RAW: - prefixBuf[prefixLen] = 0; - len = 0; - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_TIME: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%s %c/%-8.*s(%s%5d): ", timeBuf, priChar, - (int)entry->tagLen, entry->tag, uid, entry->pid); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_THREADTIME: - ret = strchr(uid, ':'); - if (ret) { - *ret = ' '; - } - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%s %s%5d %5d %c %-8.*s: ", timeBuf, uid, entry->pid, - entry->tid, priChar, (int)entry->tagLen, entry->tag); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - case FORMAT_LONG: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "[ %s %s%5d:%5d %c/%-8.*s ]\n", - timeBuf, uid, entry->pid, entry->tid, priChar, - (int)entry->tagLen, entry->tag); - strcpy(suffixBuf + suffixLen, "\n\n"); - suffixLen += 2; - prefixSuffixIsHeaderFooter = 1; - break; - case FORMAT_BRIEF: - default: - len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, - "%c/%-8.*s(%s%5d): ", priChar, (int)entry->tagLen, entry->tag, - uid, entry->pid); - strcpy(suffixBuf + suffixLen, "\n"); - ++suffixLen; - break; - } - - /* snprintf has a weird return value. It returns what would have been - * written given a large enough buffer. In the case that the prefix is - * longer then our buffer(128), it messes up the calculations below - * possibly causing heap corruption. To avoid this we double check and - * set the length at the maximum (size minus null byte) - */ - prefixLen += len; - if (prefixLen >= sizeof(prefixBuf)) { - prefixLen = sizeof(prefixBuf) - 1; - prefixBuf[sizeof(prefixBuf) - 1] = '\0'; - } - if (suffixLen >= sizeof(suffixBuf)) { - suffixLen = sizeof(suffixBuf) - 1; - suffixBuf[sizeof(suffixBuf) - 2] = '\n'; - suffixBuf[sizeof(suffixBuf) - 1] = '\0'; - } - - /* the following code is tragically unreadable */ - - size_t numLines; - char *p; - size_t bufferSize; - const char *pm; - - if (prefixSuffixIsHeaderFooter) { - /* we're just wrapping message with a header/footer */ - numLines = 1; + { + /* Not worth parsing package list, names all longer than 5 */ + snprintf(uid, sizeof(uid), "%5d:", entry->uid); + } } else { - pm = entry->message; - numLines = 0; - - /* - * The line-end finding here must match the line-end finding - * in for ( ... numLines...) loop below - */ - while (pm < (entry->message + entry->messageLen)) { - if (*pm++ == '\n') numLines++; - } - /* plus one line for anything not newline-terminated at the end */ - if (pm > entry->message && *(pm - 1) != '\n') numLines++; - } + snprintf(uid, sizeof(uid), " "); + } + } + + switch (p_format->format) { + case FORMAT_TAG: + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "%c/%-8.*s: ", priChar, (int)entry->tagLen, entry->tag); + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; + break; + case FORMAT_PROCESS: + len = snprintf(suffixBuf + suffixLen, sizeof(suffixBuf) - suffixLen, + " (%.*s)\n", (int)entry->tagLen, entry->tag); + suffixLen += MIN(len, sizeof(suffixBuf) - suffixLen); + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "%c(%s%5d) ", priChar, uid, entry->pid); + break; + case FORMAT_THREAD: + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "%c(%s%5d:%5d) ", priChar, uid, entry->pid, entry->tid); + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; + break; + case FORMAT_RAW: + prefixBuf[prefixLen] = 0; + len = 0; + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; + break; + case FORMAT_TIME: + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "%s %c/%-8.*s(%s%5d): ", timeBuf, priChar, + (int)entry->tagLen, entry->tag, uid, entry->pid); + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; + break; + case FORMAT_THREADTIME: + ret = strchr(uid, ':'); + if (ret) { + *ret = ' '; + } + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "%s %s%5d %5d %c %-8.*s: ", timeBuf, uid, entry->pid, + entry->tid, priChar, (int)entry->tagLen, entry->tag); + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; + break; + case FORMAT_LONG: + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "[ %s %s%5d:%5d %c/%-8.*s ]\n", timeBuf, uid, entry->pid, + entry->tid, priChar, (int)entry->tagLen, entry->tag); + strcpy(suffixBuf + suffixLen, "\n\n"); + suffixLen += 2; + prefixSuffixIsHeaderFooter = 1; + break; + case FORMAT_BRIEF: + default: + len = snprintf(prefixBuf + prefixLen, sizeof(prefixBuf) - prefixLen, + "%c/%-8.*s(%s%5d): ", priChar, (int)entry->tagLen, + entry->tag, uid, entry->pid); + strcpy(suffixBuf + suffixLen, "\n"); + ++suffixLen; + break; + } + + /* snprintf has a weird return value. It returns what would have been + * written given a large enough buffer. In the case that the prefix is + * longer then our buffer(128), it messes up the calculations below + * possibly causing heap corruption. To avoid this we double check and + * set the length at the maximum (size minus null byte) + */ + prefixLen += len; + if (prefixLen >= sizeof(prefixBuf)) { + prefixLen = sizeof(prefixBuf) - 1; + prefixBuf[sizeof(prefixBuf) - 1] = '\0'; + } + if (suffixLen >= sizeof(suffixBuf)) { + suffixLen = sizeof(suffixBuf) - 1; + suffixBuf[sizeof(suffixBuf) - 2] = '\n'; + suffixBuf[sizeof(suffixBuf) - 1] = '\0'; + } + + /* the following code is tragically unreadable */ + + size_t numLines; + char* p; + size_t bufferSize; + const char* pm; + + if (prefixSuffixIsHeaderFooter) { + /* we're just wrapping message with a header/footer */ + numLines = 1; + } else { + pm = entry->message; + numLines = 0; /* - * this is an upper bound--newlines in message may be counted - * extraneously + * The line-end finding here must match the line-end finding + * in for ( ... numLines...) loop below */ - bufferSize = (numLines * (prefixLen + suffixLen)) + 1; + while (pm < (entry->message + entry->messageLen)) { + if (*pm++ == '\n') numLines++; + } + /* plus one line for anything not newline-terminated at the end */ + if (pm > entry->message && *(pm - 1) != '\n') numLines++; + } + + /* + * this is an upper bound--newlines in message may be counted + * extraneously + */ + bufferSize = (numLines * (prefixLen + suffixLen)) + 1; + if (p_format->printable_output) { + /* Calculate extra length to convert non-printable to printable */ + bufferSize += convertPrintable(NULL, entry->message, entry->messageLen); + } else { + bufferSize += entry->messageLen; + } + + if (defaultBufferSize >= bufferSize) { + ret = defaultBuffer; + } else { + ret = (char*)malloc(bufferSize); + + if (ret == NULL) { + return ret; + } + } + + ret[0] = '\0'; /* to start strcat off */ + + p = ret; + pm = entry->message; + + if (prefixSuffixIsHeaderFooter) { + strcat(p, prefixBuf); + p += prefixLen; if (p_format->printable_output) { - /* Calculate extra length to convert non-printable to printable */ - bufferSize += convertPrintable(NULL, entry->message, entry->messageLen); + p += convertPrintable(p, entry->message, entry->messageLen); } else { - bufferSize += entry->messageLen; + strncat(p, entry->message, entry->messageLen); + p += entry->messageLen; } - - if (defaultBufferSize >= bufferSize) { - ret = defaultBuffer; - } else { - ret = (char *)malloc(bufferSize); - - if (ret == NULL) { - return ret; - } - } - - ret[0] = '\0'; /* to start strcat off */ - - p = ret; - pm = entry->message; - - if (prefixSuffixIsHeaderFooter) { - strcat(p, prefixBuf); - p += prefixLen; - if (p_format->printable_output) { - p += convertPrintable(p, entry->message, entry->messageLen); - } else { - strncat(p, entry->message, entry->messageLen); - p += entry->messageLen; - } - strcat(p, suffixBuf); - p += suffixLen; - } else { - do { - const char *lineStart; - size_t lineLen; - lineStart = pm; - - /* Find the next end-of-line in message */ - while (pm < (entry->message + entry->messageLen) - && *pm != '\n') pm++; - lineLen = pm - lineStart; - - strcat(p, prefixBuf); - p += prefixLen; - if (p_format->printable_output) { - p += convertPrintable(p, lineStart, lineLen); - } else { - strncat(p, lineStart, lineLen); - p += lineLen; - } - strcat(p, suffixBuf); - p += suffixLen; - - if (*pm == '\n') pm++; - } while (pm < (entry->message + entry->messageLen)); - } - - if (p_outLength != NULL) { - *p_outLength = p - ret; - } - - return ret; + strcat(p, suffixBuf); + p += suffixLen; + } else { + do { + const char* lineStart; + size_t lineLen; + lineStart = pm; + + /* Find the next end-of-line in message */ + while (pm < (entry->message + entry->messageLen) && *pm != '\n') pm++; + lineLen = pm - lineStart; + + strcat(p, prefixBuf); + p += prefixLen; + if (p_format->printable_output) { + p += convertPrintable(p, lineStart, lineLen); + } else { + strncat(p, lineStart, lineLen); + p += lineLen; + } + strcat(p, suffixBuf); + p += suffixLen; + + if (*pm == '\n') pm++; + } while (pm < (entry->message + entry->messageLen)); + } + + if (p_outLength != NULL) { + *p_outLength = p - ret; + } + + return ret; } /** @@ -1847,41 +1805,38 @@ LIBLOG_ABI_PUBLIC char *android_log_formatLogLine ( * Returns count bytes written */ -LIBLOG_ABI_PUBLIC int android_log_printLogLine( - AndroidLogFormat *p_format, - int fd, - const AndroidLogEntry *entry) -{ - int ret; - char defaultBuffer[512]; - char *outBuffer = NULL; - size_t totalLen; +LIBLOG_ABI_PUBLIC int android_log_printLogLine(AndroidLogFormat* p_format, + int fd, + const AndroidLogEntry* entry) { + int ret; + char defaultBuffer[512]; + char* outBuffer = NULL; + size_t totalLen; - outBuffer = android_log_formatLogLine(p_format, defaultBuffer, - sizeof(defaultBuffer), entry, &totalLen); + outBuffer = android_log_formatLogLine( + p_format, defaultBuffer, sizeof(defaultBuffer), entry, &totalLen); - if (!outBuffer) return -1; + if (!outBuffer) return -1; - do { - ret = write(fd, outBuffer, totalLen); - } while (ret < 0 && errno == EINTR); + do { + ret = write(fd, outBuffer, totalLen); + } while (ret < 0 && errno == EINTR); - if (ret < 0) { - fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); - ret = 0; - goto done; - } + if (ret < 0) { + fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); + ret = 0; + goto done; + } - if (((size_t)ret) < totalLen) { - fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", ret, - (int)totalLen); - goto done; - } + if (((size_t)ret) < totalLen) { + fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", ret, (int)totalLen); + goto done; + } done: - if (outBuffer != defaultBuffer) { - free(outBuffer); - } + if (outBuffer != defaultBuffer) { + free(outBuffer); + } - return ret; + return ret; } diff --git a/liblog/pmsg_reader.c b/liblog/pmsg_reader.c index e1b81aaf0..c3ed8a261 100644 --- a/liblog/pmsg_reader.c +++ b/liblog/pmsg_reader.c @@ -29,591 +29,571 @@ #include "logger.h" static int pmsgAvailable(log_id_t logId); -static int pmsgVersion(struct android_log_logger *logger, - struct android_log_transport_context *transp); -static int pmsgRead(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp, - struct log_msg *log_msg); -static void pmsgClose(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp); -static int pmsgClear(struct android_log_logger *logger, - struct android_log_transport_context *transp); +static int pmsgVersion(struct android_log_logger* logger, + struct android_log_transport_context* transp); +static int pmsgRead(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp, + struct log_msg* log_msg); +static void pmsgClose(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp); +static int pmsgClear(struct android_log_logger* logger, + struct android_log_transport_context* transp); LIBLOG_HIDDEN struct android_log_transport_read pmsgLoggerRead = { - .node = { &pmsgLoggerRead.node, &pmsgLoggerRead.node }, - .name = "pmsg", - .available = pmsgAvailable, - .version = pmsgVersion, - .read = pmsgRead, - .poll = NULL, - .close = pmsgClose, - .clear = pmsgClear, - .setSize = NULL, - .getSize = NULL, - .getReadableSize = NULL, - .getPrune = NULL, - .setPrune = NULL, - .getStats = NULL, + .node = { &pmsgLoggerRead.node, &pmsgLoggerRead.node }, + .name = "pmsg", + .available = pmsgAvailable, + .version = pmsgVersion, + .read = pmsgRead, + .poll = NULL, + .close = pmsgClose, + .clear = pmsgClear, + .setSize = NULL, + .getSize = NULL, + .getReadableSize = NULL, + .getPrune = NULL, + .setPrune = NULL, + .getStats = NULL, }; -static int pmsgAvailable(log_id_t logId) -{ - if (logId > LOG_ID_SECURITY) { - return -EINVAL; - } - if (access("/dev/pmsg0", W_OK) == 0) { - return 0; - } - return -EBADF; +static int pmsgAvailable(log_id_t logId) { + if (logId > LOG_ID_SECURITY) { + return -EINVAL; + } + if (access("/dev/pmsg0", W_OK) == 0) { + return 0; + } + return -EBADF; } /* Determine the credentials of the caller */ -static bool uid_has_log_permission(uid_t uid) -{ - return (uid == AID_SYSTEM) || (uid == AID_LOG) || (uid == AID_ROOT) || (uid == AID_LOGD); +static bool uid_has_log_permission(uid_t uid) { + return (uid == AID_SYSTEM) || (uid == AID_LOG) || (uid == AID_ROOT) || + (uid == AID_LOGD); } -static uid_t get_best_effective_uid() -{ - uid_t euid; - uid_t uid; - gid_t gid; - ssize_t i; - static uid_t last_uid = (uid_t) -1; - - if (last_uid != (uid_t) -1) { - return last_uid; - } - uid = __android_log_uid(); - if (uid_has_log_permission(uid)) { - return last_uid = uid; - } - euid = geteuid(); - if (uid_has_log_permission(euid)) { - return last_uid = euid; - } - gid = getgid(); - if (uid_has_log_permission(gid)) { - return last_uid = gid; - } - gid = getegid(); - if (uid_has_log_permission(gid)) { - return last_uid = gid; - } - i = getgroups((size_t) 0, NULL); - if (i > 0) { - gid_t list[i]; - - getgroups(i, list); - while (--i >= 0) { - if (uid_has_log_permission(list[i])) { - return last_uid = list[i]; - } - } - } +static uid_t get_best_effective_uid() { + uid_t euid; + uid_t uid; + gid_t gid; + ssize_t i; + static uid_t last_uid = (uid_t)-1; + + if (last_uid != (uid_t)-1) { + return last_uid; + } + uid = __android_log_uid(); + if (uid_has_log_permission(uid)) { return last_uid = uid; + } + euid = geteuid(); + if (uid_has_log_permission(euid)) { + return last_uid = euid; + } + gid = getgid(); + if (uid_has_log_permission(gid)) { + return last_uid = gid; + } + gid = getegid(); + if (uid_has_log_permission(gid)) { + return last_uid = gid; + } + i = getgroups((size_t)0, NULL); + if (i > 0) { + gid_t list[i]; + + getgroups(i, list); + while (--i >= 0) { + if (uid_has_log_permission(list[i])) { + return last_uid = list[i]; + } + } + } + return last_uid = uid; } -static int pmsgClear(struct android_log_logger *logger __unused, - struct android_log_transport_context *transp __unused) -{ - if (uid_has_log_permission(get_best_effective_uid())) { - return unlink("/sys/fs/pstore/pmsg-ramoops-0"); - } - errno = EPERM; - return -1; +static int pmsgClear(struct android_log_logger* logger __unused, + struct android_log_transport_context* transp __unused) { + if (uid_has_log_permission(get_best_effective_uid())) { + return unlink("/sys/fs/pstore/pmsg-ramoops-0"); + } + errno = EPERM; + return -1; } /* * returns the logger version */ -static int pmsgVersion(struct android_log_logger *logger __unused, - struct android_log_transport_context *transp __unused) -{ - return 4; +static int pmsgVersion(struct android_log_logger* logger __unused, + struct android_log_transport_context* transp __unused) { + return 4; } -static int pmsgRead(struct android_log_logger_list *logger_list, - struct android_log_transport_context *transp, - struct log_msg *log_msg) -{ - ssize_t ret; - off_t current, next; - uid_t uid; - struct android_log_logger *logger; - struct __attribute__((__packed__)) { - android_pmsg_log_header_t p; - android_log_header_t l; - uint8_t prio; - } buf; - static uint8_t preread_count; - bool is_system; - - memset(log_msg, 0, sizeof(*log_msg)); - - if (atomic_load(&transp->context.fd) <= 0) { - int i, fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC); - - if (fd < 0) { - return -errno; - } - if (fd == 0) { /* Argggg */ - fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC); - close(0); - if (fd < 0) { - return -errno; - } - } - i = atomic_exchange(&transp->context.fd, fd); - if ((i > 0) && (i != fd)) { - close(i); - } - preread_count = 0; +static int pmsgRead(struct android_log_logger_list* logger_list, + struct android_log_transport_context* transp, + struct log_msg* log_msg) { + ssize_t ret; + off_t current, next; + uid_t uid; + struct android_log_logger* logger; + struct __attribute__((__packed__)) { + android_pmsg_log_header_t p; + android_log_header_t l; + uint8_t prio; + } buf; + static uint8_t preread_count; + bool is_system; + + memset(log_msg, 0, sizeof(*log_msg)); + + if (atomic_load(&transp->context.fd) <= 0) { + int i, fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC); + + if (fd < 0) { + return -errno; } - - while(1) { - int fd; - - if (preread_count < sizeof(buf)) { - fd = atomic_load(&transp->context.fd); - if (fd <= 0) { - return -EBADF; - } - ret = TEMP_FAILURE_RETRY(read(fd, - &buf.p.magic + preread_count, - sizeof(buf) - preread_count)); - if (ret < 0) { - return -errno; - } - preread_count += ret; - } - if (preread_count != sizeof(buf)) { - return preread_count ? -EIO : -EAGAIN; - } - if ((buf.p.magic != LOGGER_MAGIC) || - (buf.p.len <= sizeof(buf)) || - (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD)) || - (buf.l.id >= LOG_ID_MAX) || - (buf.l.realtime.tv_nsec >= NS_PER_SEC) || - ((buf.l.id != LOG_ID_EVENTS) && - (buf.l.id != LOG_ID_SECURITY) && - ((buf.prio == ANDROID_LOG_UNKNOWN) || - (buf.prio == ANDROID_LOG_DEFAULT) || - (buf.prio >= ANDROID_LOG_SILENT)))) { - do { - memmove(&buf.p.magic, &buf.p.magic + 1, --preread_count); - } while (preread_count && (buf.p.magic != LOGGER_MAGIC)); - continue; - } - preread_count = 0; - - if ((transp->logMask & (1 << buf.l.id)) && - ((!logger_list->start.tv_sec && !logger_list->start.tv_nsec) || - ((logger_list->start.tv_sec <= buf.l.realtime.tv_sec) && - ((logger_list->start.tv_sec != buf.l.realtime.tv_sec) || - (logger_list->start.tv_nsec <= - buf.l.realtime.tv_nsec)))) && - (!logger_list->pid || (logger_list->pid == buf.p.pid))) { - uid = get_best_effective_uid(); - is_system = uid_has_log_permission(uid); - if (is_system || (uid == buf.p.uid)) { - char *msg = is_system ? - log_msg->entry_v4.msg : - log_msg->entry_v3.msg; - *msg = buf.prio; - fd = atomic_load(&transp->context.fd); - if (fd <= 0) { - return -EBADF; - } - ret = TEMP_FAILURE_RETRY(read(fd, - msg + sizeof(buf.prio), - buf.p.len - sizeof(buf))); - if (ret < 0) { - return -errno; - } - if (ret != (ssize_t)(buf.p.len - sizeof(buf))) { - return -EIO; - } - - log_msg->entry_v4.len = buf.p.len - sizeof(buf) + sizeof(buf.prio); - log_msg->entry_v4.hdr_size = is_system ? - sizeof(log_msg->entry_v4) : - sizeof(log_msg->entry_v3); - log_msg->entry_v4.pid = buf.p.pid; - log_msg->entry_v4.tid = buf.l.tid; - log_msg->entry_v4.sec = buf.l.realtime.tv_sec; - log_msg->entry_v4.nsec = buf.l.realtime.tv_nsec; - log_msg->entry_v4.lid = buf.l.id; - if (is_system) { - log_msg->entry_v4.uid = buf.p.uid; - } - - return ret + sizeof(buf.prio) + log_msg->entry_v4.hdr_size; - } - } - + if (fd == 0) { /* Argggg */ + fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY | O_CLOEXEC); + close(0); + if (fd < 0) { + return -errno; + } + } + i = atomic_exchange(&transp->context.fd, fd); + if ((i > 0) && (i != fd)) { + close(i); + } + preread_count = 0; + } + + while (1) { + int fd; + + if (preread_count < sizeof(buf)) { + fd = atomic_load(&transp->context.fd); + if (fd <= 0) { + return -EBADF; + } + ret = TEMP_FAILURE_RETRY( + read(fd, &buf.p.magic + preread_count, sizeof(buf) - preread_count)); + if (ret < 0) { + return -errno; + } + preread_count += ret; + } + if (preread_count != sizeof(buf)) { + return preread_count ? -EIO : -EAGAIN; + } + if ((buf.p.magic != LOGGER_MAGIC) || (buf.p.len <= sizeof(buf)) || + (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD)) || + (buf.l.id >= LOG_ID_MAX) || (buf.l.realtime.tv_nsec >= NS_PER_SEC) || + ((buf.l.id != LOG_ID_EVENTS) && (buf.l.id != LOG_ID_SECURITY) && + ((buf.prio == ANDROID_LOG_UNKNOWN) || + (buf.prio == ANDROID_LOG_DEFAULT) || + (buf.prio >= ANDROID_LOG_SILENT)))) { + do { + memmove(&buf.p.magic, &buf.p.magic + 1, --preread_count); + } while (preread_count && (buf.p.magic != LOGGER_MAGIC)); + continue; + } + preread_count = 0; + + if ((transp->logMask & (1 << buf.l.id)) && + ((!logger_list->start.tv_sec && !logger_list->start.tv_nsec) || + ((logger_list->start.tv_sec <= buf.l.realtime.tv_sec) && + ((logger_list->start.tv_sec != buf.l.realtime.tv_sec) || + (logger_list->start.tv_nsec <= buf.l.realtime.tv_nsec)))) && + (!logger_list->pid || (logger_list->pid == buf.p.pid))) { + uid = get_best_effective_uid(); + is_system = uid_has_log_permission(uid); + if (is_system || (uid == buf.p.uid)) { + char* msg = is_system ? log_msg->entry_v4.msg : log_msg->entry_v3.msg; + *msg = buf.prio; fd = atomic_load(&transp->context.fd); if (fd <= 0) { - return -EBADF; + return -EBADF; } - current = TEMP_FAILURE_RETRY(lseek(fd, (off_t)0, SEEK_CUR)); - if (current < 0) { - return -errno; + ret = TEMP_FAILURE_RETRY( + read(fd, msg + sizeof(buf.prio), buf.p.len - sizeof(buf))); + if (ret < 0) { + return -errno; } - fd = atomic_load(&transp->context.fd); - if (fd <= 0) { - return -EBADF; + if (ret != (ssize_t)(buf.p.len - sizeof(buf))) { + return -EIO; } - next = TEMP_FAILURE_RETRY(lseek(fd, - (off_t)(buf.p.len - sizeof(buf)), - SEEK_CUR)); - if (next < 0) { - return -errno; - } - if ((next - current) != (ssize_t)(buf.p.len - sizeof(buf))) { - return -EIO; + + log_msg->entry_v4.len = buf.p.len - sizeof(buf) + sizeof(buf.prio); + log_msg->entry_v4.hdr_size = + is_system ? sizeof(log_msg->entry_v4) : sizeof(log_msg->entry_v3); + log_msg->entry_v4.pid = buf.p.pid; + log_msg->entry_v4.tid = buf.l.tid; + log_msg->entry_v4.sec = buf.l.realtime.tv_sec; + log_msg->entry_v4.nsec = buf.l.realtime.tv_nsec; + log_msg->entry_v4.lid = buf.l.id; + if (is_system) { + log_msg->entry_v4.uid = buf.p.uid; } - } -} -static void pmsgClose(struct android_log_logger_list *logger_list __unused, - struct android_log_transport_context *transp) { - int fd = atomic_exchange(&transp->context.fd, 0); - if (fd > 0) { - close (fd); + return ret + sizeof(buf.prio) + log_msg->entry_v4.hdr_size; + } } -} -LIBLOG_ABI_PRIVATE 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 ret; - struct android_log_logger_list logger_list; - struct android_log_transport_context transp; - struct content { - struct listnode node; - union { - 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; - }; - } *content; - struct names { - struct listnode node; - struct listnode content; - log_id_t id; - char prio; - char name[]; - } *names; - struct listnode name_list; - struct listnode *node, *n; - size_t len, prefix_len; - - if (!fn) { - return -EINVAL; + fd = atomic_load(&transp->context.fd); + if (fd <= 0) { + return -EBADF; } - - /* Add just enough clues in logger_list and transp to make API function */ - memset(&logger_list, 0, sizeof(logger_list)); - memset(&transp, 0, sizeof(transp)); - - logger_list.mode = ANDROID_LOG_PSTORE | - ANDROID_LOG_NONBLOCK | - ANDROID_LOG_RDONLY; - transp.logMask = (unsigned)-1; - if (logId != LOG_ID_ANY) { - transp.logMask = (1 << logId); + current = TEMP_FAILURE_RETRY(lseek(fd, (off_t)0, SEEK_CUR)); + if (current < 0) { + return -errno; } - transp.logMask &= ~((1 << LOG_ID_KERNEL) | - (1 << LOG_ID_EVENTS) | - (1 << LOG_ID_SECURITY)); - if (!transp.logMask) { - return -EINVAL; + fd = atomic_load(&transp->context.fd); + if (fd <= 0) { + return -EBADF; } + next = TEMP_FAILURE_RETRY( + lseek(fd, (off_t)(buf.p.len - sizeof(buf)), SEEK_CUR)); + if (next < 0) { + return -errno; + } + if ((next - current) != (ssize_t)(buf.p.len - sizeof(buf))) { + return -EIO; + } + } +} - /* Initialize name list */ - list_init(&name_list); +static void pmsgClose(struct android_log_logger_list* logger_list __unused, + struct android_log_transport_context* transp) { + int fd = atomic_exchange(&transp->context.fd, 0); + if (fd > 0) { + close(fd); + } +} - ret = SSIZE_MAX; +LIBLOG_ABI_PRIVATE 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 ret; + struct android_log_logger_list logger_list; + struct android_log_transport_context transp; + struct content { + struct listnode node; + union { + 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; + }; + } * content; + struct names { + struct listnode node; + struct listnode content; + log_id_t id; + char prio; + char name[]; + } * names; + struct listnode name_list; + struct listnode *node, *n; + size_t len, prefix_len; + + if (!fn) { + return -EINVAL; + } + + /* Add just enough clues in logger_list and transp to make API function */ + memset(&logger_list, 0, sizeof(logger_list)); + memset(&transp, 0, sizeof(transp)); + + logger_list.mode = + ANDROID_LOG_PSTORE | ANDROID_LOG_NONBLOCK | ANDROID_LOG_RDONLY; + transp.logMask = (unsigned)-1; + if (logId != LOG_ID_ANY) { + transp.logMask = (1 << logId); + } + transp.logMask &= + ~((1 << LOG_ID_KERNEL) | (1 << LOG_ID_EVENTS) | (1 << LOG_ID_SECURITY)); + if (!transp.logMask) { + return -EINVAL; + } + + /* Initialize name list */ + list_init(&name_list); + + ret = SSIZE_MAX; + + /* Validate incoming prefix, shift until it contains only 0 or 1 : or / */ + prefix_len = 0; + if (prefix) { + const char *prev = NULL, *last = NULL, *cp = prefix; + while ((cp = strpbrk(cp, "/:"))) { + prev = last; + last = cp; + cp = cp + 1; + } + if (prev) { + prefix = prev + 1; + } + prefix_len = strlen(prefix); + } + + /* Read the file content */ + while (pmsgRead(&logger_list, &transp, &transp.logMsg) > 0) { + char* cp; + size_t hdr_size = transp.logMsg.entry.hdr_size + ? transp.logMsg.entry.hdr_size + : sizeof(transp.logMsg.entry_v1); + char* msg = (char*)&transp.logMsg + hdr_size; + char* split = NULL; + + if ((hdr_size < sizeof(transp.logMsg.entry_v1)) || + (hdr_size > sizeof(transp.logMsg.entry))) { + continue; + } + /* Check for invalid sequence number */ + if ((transp.logMsg.entry.nsec % ANDROID_LOG_PMSG_FILE_SEQUENCE) || + ((transp.logMsg.entry.nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >= + ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE)) { + continue; + } - /* Validate incoming prefix, shift until it contains only 0 or 1 : or / */ - prefix_len = 0; - if (prefix) { - const char *prev = NULL, *last = NULL, *cp = prefix; - while ((cp = strpbrk(cp, "/:"))) { - prev = last; - last = cp; - cp = cp + 1; + /* Determine if it has <dirbase>:<filebase> format for tag */ + len = transp.logMsg.entry.len - sizeof(prio); + for (cp = msg + sizeof(prio); *cp && isprint(*cp) && !isspace(*cp) && --len; + ++cp) { + if (*cp == ':') { + if (split) { + break; } - if (prev) { - prefix = prev + 1; - } - prefix_len = strlen(prefix); + split = cp; + } + } + if (*cp || !split) { + continue; } - /* Read the file content */ - while (pmsgRead(&logger_list, &transp, &transp.logMsg) > 0) { - char *cp; - size_t hdr_size = transp.logMsg.entry.hdr_size ? - transp.logMsg.entry.hdr_size : sizeof(transp.logMsg.entry_v1); - char *msg = (char *)&transp.logMsg + hdr_size; - char *split = NULL; - - if ((hdr_size < sizeof(transp.logMsg.entry_v1)) || - (hdr_size > sizeof(transp.logMsg.entry))) { - continue; - } - /* Check for invalid sequence number */ - if ((transp.logMsg.entry.nsec % ANDROID_LOG_PMSG_FILE_SEQUENCE) || - ((transp.logMsg.entry.nsec / ANDROID_LOG_PMSG_FILE_SEQUENCE) >= - ANDROID_LOG_PMSG_FILE_MAX_SEQUENCE)) { - continue; - } + /* Filters */ + if (prefix_len && strncmp(msg + sizeof(prio), prefix, prefix_len)) { + size_t offset; + /* + * Allow : to be a synonym for / + * Things we do dealing with const char * and do not alloc + */ + split = strchr(prefix, ':'); + if (split) { + continue; + } + split = strchr(prefix, '/'); + if (!split) { + continue; + } + offset = split - prefix; + if ((msg[offset + sizeof(prio)] != ':') || + strncmp(msg + sizeof(prio), prefix, offset)) { + continue; + } + ++offset; + if ((prefix_len > offset) && strncmp(&msg[offset + sizeof(prio)], + split + 1, prefix_len - offset)) { + continue; + } + } - /* Determine if it has <dirbase>:<filebase> format for tag */ - len = transp.logMsg.entry.len - sizeof(prio); - for (cp = msg + sizeof(prio); - *cp && isprint(*cp) && !isspace(*cp) && --len; - ++cp) { - if (*cp == ':') { - if (split) { - break; - } - split = cp; - } - } - if (*cp || !split) { - continue; - } + if ((prio != ANDROID_LOG_ANY) && (*msg < prio)) { + continue; + } - /* Filters */ - if (prefix_len && strncmp(msg + sizeof(prio), prefix, prefix_len)) { - size_t offset; - /* - * Allow : to be a synonym for / - * Things we do dealing with const char * and do not alloc - */ - split = strchr(prefix, ':'); - if (split) { - continue; - } - split = strchr(prefix, '/'); - if (!split) { - continue; - } - offset = split - prefix; - if ((msg[offset + sizeof(prio)] != ':') || - strncmp(msg + sizeof(prio), prefix, offset)) { - continue; - } - ++offset; - if ((prefix_len > offset) && - strncmp(&msg[offset + sizeof(prio)], split + 1, prefix_len - offset)) { - continue; - } - } + /* check if there is an existing entry */ + list_for_each(node, &name_list) { + names = node_to_item(node, struct names, node); + if (!strcmp(names->name, msg + sizeof(prio)) && + (names->id == transp.logMsg.entry.lid) && (names->prio == *msg)) { + break; + } + } - if ((prio != ANDROID_LOG_ANY) && (*msg < prio)) { - continue; + /* We do not have an existing entry, create and add one */ + if (node == &name_list) { + static const char numbers[] = "0123456789"; + unsigned long long nl; + + len = strlen(msg + sizeof(prio)) + 1; + names = calloc(1, sizeof(*names) + len); + if (!names) { + ret = -ENOMEM; + break; + } + strcpy(names->name, msg + sizeof(prio)); + names->id = transp.logMsg.entry.lid; + names->prio = *msg; + list_init(&names->content); + /* + * Insert in reverse numeric _then_ alpha sorted order as + * representative of log rotation: + * + * log.10 + * klog.10 + * . . . + * log.2 + * klog.2 + * log.1 + * klog.1 + * log + * klog + * + * thus when we present the content, we are provided the oldest + * first, which when 'refreshed' could spill off the end of the + * pmsg FIFO but retaining the newest data for last with best + * chances to survive. + */ + nl = 0; + cp = strpbrk(names->name, numbers); + if (cp) { + nl = strtoull(cp, NULL, 10); + } + list_for_each_reverse(node, &name_list) { + struct names* a_name = node_to_item(node, struct names, node); + const char* r = a_name->name; + int compare = 0; + + unsigned long long nr = 0; + cp = strpbrk(r, numbers); + if (cp) { + nr = strtoull(cp, NULL, 10); } - - /* check if there is an existing entry */ - list_for_each(node, &name_list) { - names = node_to_item(node, struct names, node); - if (!strcmp(names->name, msg + sizeof(prio)) && - (names->id == transp.logMsg.entry.lid) && - (names->prio == *msg)) { - break; - } + if (nr != nl) { + compare = (nl > nr) ? 1 : -1; } - - /* We do not have an existing entry, create and add one */ - if (node == &name_list) { - static const char numbers[] = "0123456789"; - unsigned long long nl; - - len = strlen(msg + sizeof(prio)) + 1; - names = calloc(1, sizeof(*names) + len); - if (!names) { - ret = -ENOMEM; - break; - } - strcpy(names->name, msg + sizeof(prio)); - names->id = transp.logMsg.entry.lid; - names->prio = *msg; - list_init(&names->content); - /* - * Insert in reverse numeric _then_ alpha sorted order as - * representative of log rotation: - * - * log.10 - * klog.10 - * . . . - * log.2 - * klog.2 - * log.1 - * klog.1 - * log - * klog - * - * thus when we present the content, we are provided the oldest - * first, which when 'refreshed' could spill off the end of the - * pmsg FIFO but retaining the newest data for last with best - * chances to survive. - */ - nl = 0; - cp = strpbrk(names->name, numbers); - if (cp) { - nl = strtoull(cp, NULL, 10); - } - list_for_each_reverse(node, &name_list) { - struct names *a_name = node_to_item(node, struct names, node); - const char *r = a_name->name; - int compare = 0; - - unsigned long long nr = 0; - cp = strpbrk(r, numbers); - if (cp) { - nr = strtoull(cp, NULL, 10); - } - if (nr != nl) { - compare = (nl > nr) ? 1 : -1; - } - if (compare == 0) { - compare = strcmp(names->name, r); - } - if (compare <= 0) { - break; - } - } - list_add_head(node, &names->node); + if (compare == 0) { + compare = strcmp(names->name, r); } - - /* Remove any file fragments that match our sequence number */ - list_for_each_safe(node, n, &names->content) { - content = node_to_item(node, struct content, node); - if (transp.logMsg.entry.nsec == content->entry.nsec) { - list_remove(&content->node); - free(content); - } + if (compare <= 0) { + break; } + } + list_add_head(node, &names->node); + } + + /* Remove any file fragments that match our sequence number */ + list_for_each_safe(node, n, &names->content) { + content = node_to_item(node, struct content, node); + if (transp.logMsg.entry.nsec == content->entry.nsec) { + list_remove(&content->node); + free(content); + } + } - /* Add content */ - content = calloc(1, sizeof(content->node) + - hdr_size + transp.logMsg.entry.len); - if (!content) { - ret = -ENOMEM; - break; + /* Add content */ + content = + calloc(1, sizeof(content->node) + hdr_size + transp.logMsg.entry.len); + if (!content) { + ret = -ENOMEM; + break; + } + memcpy(&content->entry, &transp.logMsg.entry, + hdr_size + transp.logMsg.entry.len); + + /* Insert in sequence number sorted order, to ease reconstruction */ + list_for_each_reverse(node, &names->content) { + if ((node_to_item(node, struct content, node))->entry.nsec < + transp.logMsg.entry.nsec) { + break; + } + } + list_add_head(node, &content->node); + } + pmsgClose(&logger_list, &transp); + + /* Progress through all the collected files */ + list_for_each_safe(node, n, &name_list) { + struct listnode *content_node, *m; + char* buf; + size_t sequence, tag_len; + + names = node_to_item(node, struct names, node); + + /* Construct content into a linear buffer */ + buf = NULL; + len = 0; + sequence = 0; + tag_len = strlen(names->name) + sizeof(char); /* tag + nul */ + list_for_each_safe(content_node, m, &names->content) { + ssize_t add_len; + + content = node_to_item(content_node, struct content, node); + add_len = content->entry.len - tag_len - sizeof(prio); + if (add_len <= 0) { + list_remove(content_node); + free(content); + continue; + } + + if (!buf) { + buf = malloc(sizeof(char)); + if (!buf) { + ret = -ENOMEM; + list_remove(content_node); + free(content); + continue; } - memcpy(&content->entry, &transp.logMsg.entry, - hdr_size + transp.logMsg.entry.len); - - /* Insert in sequence number sorted order, to ease reconstruction */ - list_for_each_reverse(node, &names->content) { - if ((node_to_item(node, struct content, node))->entry.nsec < - transp.logMsg.entry.nsec) { - break; - } + *buf = '\0'; + } + + /* Missing sequence numbers */ + while (sequence < content->entry.nsec) { + /* plus space for enforced nul */ + buf = realloc(buf, len + sizeof(char) + sizeof(char)); + if (!buf) { + break; } - list_add_head(node, &content->node); + buf[len] = '\f'; /* Mark missing content with a form feed */ + buf[++len] = '\0'; + sequence += ANDROID_LOG_PMSG_FILE_SEQUENCE; + } + if (!buf) { + ret = -ENOMEM; + list_remove(content_node); + free(content); + continue; + } + /* plus space for enforced nul */ + buf = realloc(buf, len + add_len + sizeof(char)); + if (!buf) { + ret = -ENOMEM; + list_remove(content_node); + free(content); + continue; + } + memcpy(buf + len, + (char*)&content->entry + content->entry.hdr_size + tag_len + + sizeof(prio), + add_len); + len += add_len; + buf[len] = '\0'; /* enforce trailing hidden nul */ + sequence = content->entry.nsec + ANDROID_LOG_PMSG_FILE_SEQUENCE; + + list_remove(content_node); + free(content); } - pmsgClose(&logger_list, &transp); - - /* Progress through all the collected files */ - list_for_each_safe(node, n, &name_list) { - struct listnode *content_node, *m; - char *buf; - size_t sequence, tag_len; - - names = node_to_item(node, struct names, node); - - /* Construct content into a linear buffer */ - buf = NULL; - len = 0; - sequence = 0; - tag_len = strlen(names->name) + sizeof(char); /* tag + nul */ - list_for_each_safe(content_node, m, &names->content) { - ssize_t add_len; - - content = node_to_item(content_node, struct content, node); - add_len = content->entry.len - tag_len - sizeof(prio); - if (add_len <= 0) { - list_remove(content_node); - free(content); - continue; - } - - if (!buf) { - buf = malloc(sizeof(char)); - if (!buf) { - ret = -ENOMEM; - list_remove(content_node); - free(content); - continue; - } - *buf = '\0'; - } - - /* Missing sequence numbers */ - while (sequence < content->entry.nsec) { - /* plus space for enforced nul */ - buf = realloc(buf, len + sizeof(char) + sizeof(char)); - if (!buf) { - break; - } - buf[len] = '\f'; /* Mark missing content with a form feed */ - buf[++len] = '\0'; - sequence += ANDROID_LOG_PMSG_FILE_SEQUENCE; - } - if (!buf) { - ret = -ENOMEM; - list_remove(content_node); - free(content); - continue; - } - /* plus space for enforced nul */ - buf = realloc(buf, len + add_len + sizeof(char)); - if (!buf) { - ret = -ENOMEM; - list_remove(content_node); - free(content); - continue; - } - memcpy(buf + len, - (char *)&content->entry + content->entry.hdr_size + - tag_len + sizeof(prio), - add_len); - len += add_len; - buf[len] = '\0'; /* enforce trailing hidden nul */ - sequence = content->entry.nsec + ANDROID_LOG_PMSG_FILE_SEQUENCE; - - list_remove(content_node); - free(content); - } - if (buf) { - if (len) { - /* Buffer contains enforced trailing nul just beyond length */ - ssize_t r; - *strchr(names->name, ':') = '/'; /* Convert back to filename */ - r = (*fn)(names->id, names->prio, names->name, buf, len, arg); - if ((ret >= 0) && (r > 0)) { - if (ret == SSIZE_MAX) { - ret = r; - } else { - ret += r; - } - } else if (r < ret) { - ret = r; - } - } - free(buf); + if (buf) { + if (len) { + /* Buffer contains enforced trailing nul just beyond length */ + ssize_t r; + *strchr(names->name, ':') = '/'; /* Convert back to filename */ + r = (*fn)(names->id, names->prio, names->name, buf, len, arg); + if ((ret >= 0) && (r > 0)) { + if (ret == SSIZE_MAX) { + ret = r; + } else { + ret += r; + } + } else if (r < ret) { + ret = r; } - list_remove(node); - free(names); + } + free(buf); } - return (ret == SSIZE_MAX) ? -ENOENT : ret; + list_remove(node); + free(names); + } + return (ret == SSIZE_MAX) ? -ENOENT : ret; } diff --git a/liblog/pmsg_writer.c b/liblog/pmsg_writer.c index 5e4ff98b3..e71c176aa 100644 --- a/liblog/pmsg_writer.c +++ b/liblog/pmsg_writer.c @@ -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; - - 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); - } +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); } + } - 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; - } - 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; +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; } - 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; - - 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; - } +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 (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; - * }; - * }; - */ - - pmsgHeader.magic = LOGGER_MAGIC; - pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header); - pmsgHeader.uid = __android_log_uid(); - pmsgHeader.pid = getpid(); - - header.id = logId; - header.tid = gettid(); - header.realtime.tv_sec = ts->tv_sec; - header.realtime.tv_nsec = ts->tv_nsec; - - 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); - - 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; - } + } + + if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) { + return -EBADF; + } + + /* + * 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; + * }; + * }; + */ + + pmsgHeader.magic = LOGGER_MAGIC; + pmsgHeader.len = sizeof(pmsgHeader) + sizeof(header); + pmsgHeader.uid = __android_log_uid(); + pmsgHeader.pid = getpid(); + + header.id = logId; + header.tid = gettid(); + header.realtime.tv_sec = ts->tv_sec; + header.realtime.tv_nsec = ts->tv_nsec; + + 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); + + 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]; - - /* 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; +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; + } + + clock_gettime(android_log_clockid(), &ts); + + cp = strdup(filename); + if (!cp) { + return -ENOMEM; + } + + tag = cp; + slash = strrchr(cp, '/'); + if (slash) { + *slash = ':'; + slash = strrchr(cp, '/'); + if (slash) { + tag = slash + 1; } + } - clock_gettime(android_log_clockid(), &ts); + length = strlen(tag) + 1; + packet_len = LOGGER_ENTRY_MAX_PAYLOAD - sizeof(char) - length; - cp = strdup(filename); - if (!cp) { - return -ENOMEM; + 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; } - tag = cp; - slash = strrchr(cp, '/'); - if (slash) { - *slash = ':'; - slash = strrchr(cp, '/'); - if (slash) { - tag = slash + 1; - } + transfer = length; + if (transfer > packet_len) { + transfer = strnrchr(buf, packet_len - 1, '\n') - buf; + if ((transfer < length) && (buf[transfer] == '\n')) { + ++transfer; + } } - 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; + 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; + } } - if (weOpened) { + + 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; } diff --git a/liblog/properties.c b/liblog/properties.c index dda09e092..0b0ef5205 100644 --- a/liblog/properties.c +++ b/liblog/properties.c @@ -29,179 +29,173 @@ static pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER; -static int 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. - */ - /* - * Any contention, and we can turn around and use the non-cached method - * in less time than the system call associated with a mutex to deal with - * the contention. - */ - return pthread_mutex_trylock(&lock_loggable); +static int 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. + */ + /* + * Any contention, and we can turn around and use the non-cached method + * in less time than the system call associated with a mutex to deal with + * the contention. + */ + return pthread_mutex_trylock(&lock_loggable); } -static void unlock() -{ - pthread_mutex_unlock(&lock_loggable); +static void unlock() { + pthread_mutex_unlock(&lock_loggable); } struct cache { - const prop_info* pinfo; - uint32_t serial; + const prop_info* pinfo; + uint32_t serial; }; struct cache_char { - struct cache cache; - unsigned char c; + struct cache cache; + unsigned char c; }; -static int check_cache(struct cache* cache) -{ - return cache->pinfo - && __system_property_serial(cache->pinfo) != cache->serial; +static int check_cache(struct cache* cache) { + return cache->pinfo && __system_property_serial(cache->pinfo) != cache->serial; } #define BOOLEAN_TRUE 0xFF #define BOOLEAN_FALSE 0xFE -static void refresh_cache(struct cache_char* cache, const char* key) -{ - char buf[PROP_VALUE_MAX]; +static void refresh_cache(struct cache_char* cache, const char* key) { + char buf[PROP_VALUE_MAX]; + if (!cache->cache.pinfo) { + cache->cache.pinfo = __system_property_find(key); if (!cache->cache.pinfo) { - cache->cache.pinfo = __system_property_find(key); - if (!cache->cache.pinfo) { - return; - } - } - cache->cache.serial = __system_property_serial(cache->cache.pinfo); - __system_property_read(cache->cache.pinfo, 0, buf); - switch(buf[0]) { - case 't': case 'T': - cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE; - break; - case 'f': case 'F': - cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE; - break; + return; + } + } + cache->cache.serial = __system_property_serial(cache->cache.pinfo); + __system_property_read(cache->cache.pinfo, 0, buf); + switch (buf[0]) { + case 't': + case 'T': + cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE; + break; + case 'f': + case 'F': + cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE; + break; default: - cache->c = buf[0]; - } + cache->c = buf[0]; + } } -static int __android_log_level(const char* tag, size_t len, int default_prio) -{ - /* sizeof() is used on this array below */ - static const char log_namespace[] = "persist.log.tag."; - static const size_t base_offset = 8; /* skip "persist." */ - /* calculate the size of our key temporary buffer */ - const size_t taglen = tag ? len : 0; - /* sizeof(log_namespace) = strlen(log_namespace) + 1 */ - char key[sizeof(log_namespace) + taglen]; /* may be > PROP_NAME_MAX */ - char* kp; - size_t i; - char c = 0; +static int __android_log_level(const char* tag, size_t len, int default_prio) { + /* sizeof() is used on this array below */ + static const char log_namespace[] = "persist.log.tag."; + static const size_t base_offset = 8; /* skip "persist." */ + /* calculate the size of our key temporary buffer */ + const size_t taglen = tag ? len : 0; + /* sizeof(log_namespace) = strlen(log_namespace) + 1 */ + char key[sizeof(log_namespace) + taglen]; /* may be > PROP_NAME_MAX */ + char* kp; + size_t i; + char c = 0; + /* + * Single layer cache of four properties. Priorities are: + * log.tag.<tag> + * persist.log.tag.<tag> + * log.tag + * persist.log.tag + * Where the missing tag matches all tags and becomes the + * system global default. We do not support ro.log.tag* . + */ + static char last_tag[PROP_NAME_MAX]; + static uint32_t global_serial; + /* some compilers erroneously see uninitialized use. !not_locked */ + uint32_t current_global_serial = 0; + static struct cache_char tag_cache[2]; + static struct cache_char global_cache[2]; + int change_detected; + int global_change_detected; + int not_locked; + + strcpy(key, log_namespace); + + global_change_detected = change_detected = not_locked = lock(); + + if (!not_locked) { /* - * Single layer cache of four properties. Priorities are: - * log.tag.<tag> - * persist.log.tag.<tag> - * log.tag - * persist.log.tag - * Where the missing tag matches all tags and becomes the - * system global default. We do not support ro.log.tag* . + * check all known serial numbers to changes. */ - static char last_tag[PROP_NAME_MAX]; - static uint32_t global_serial; - /* some compilers erroneously see uninitialized use. !not_locked */ - uint32_t current_global_serial = 0; - static struct cache_char tag_cache[2]; - static struct cache_char global_cache[2]; - int change_detected; - int global_change_detected; - int not_locked; - - strcpy(key, log_namespace); + for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { + if (check_cache(&tag_cache[i].cache)) { + change_detected = 1; + } + } + for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { + if (check_cache(&global_cache[i].cache)) { + global_change_detected = 1; + } + } - global_change_detected = change_detected = not_locked = lock(); + current_global_serial = __system_property_area_serial(); + if (current_global_serial != global_serial) { + change_detected = 1; + global_change_detected = 1; + } + } + if (taglen) { + int local_change_detected = change_detected; if (!not_locked) { - /* - * check all known serial numbers to changes. - */ + if (!last_tag[0] || (last_tag[0] != tag[0]) || + strncmp( + last_tag + 1, tag + 1, + (len < sizeof(last_tag)) ? (len - 1) : (sizeof(last_tag) - 1)) || + ((len < sizeof(last_tag)) && last_tag[len])) { + /* invalidate log.tag.<tag> cache */ for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { - if (check_cache(&tag_cache[i].cache)) { - change_detected = 1; - } - } - for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { - if (check_cache(&global_cache[i].cache)) { - global_change_detected = 1; - } + tag_cache[i].cache.pinfo = NULL; + tag_cache[i].c = '\0'; } - - current_global_serial = __system_property_area_serial(); - if (current_global_serial != global_serial) { - change_detected = 1; - global_change_detected = 1; + last_tag[0] = '\0'; + local_change_detected = 1; + } + if (!last_tag[0]) { + if (len < sizeof(last_tag)) { + strncpy(last_tag, tag, len); + last_tag[len] = '\0'; + } else { + strncpy(last_tag, tag, sizeof(last_tag)); } - } - - if (taglen) { - int local_change_detected = change_detected; - if (!not_locked) { - if (!last_tag[0] - || (last_tag[0] != tag[0]) - || strncmp(last_tag + 1, tag + 1, - (len < sizeof(last_tag)) ? - (len - 1) : - (sizeof(last_tag) - 1)) - || ((len < sizeof(last_tag)) && last_tag[len])) { - /* invalidate log.tag.<tag> cache */ - for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { - tag_cache[i].cache.pinfo = NULL; - tag_cache[i].c = '\0'; - } - last_tag[0] = '\0'; - local_change_detected = 1; - } - if (!last_tag[0]) { - if (len < sizeof(last_tag)) { - strncpy(last_tag, tag, len); - last_tag[len] = '\0'; - } else { - strncpy(last_tag, tag, sizeof(last_tag)); - } - } - } - strncpy(key + sizeof(log_namespace) - 1, tag, len); - key[sizeof(log_namespace) - 1 + len] = '\0'; + } + } + strncpy(key + sizeof(log_namespace) - 1, tag, len); + key[sizeof(log_namespace) - 1 + len] = '\0'; + + kp = key; + for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { + struct cache_char* cache = &tag_cache[i]; + struct cache_char temp_cache; + + if (not_locked) { + temp_cache.cache.pinfo = NULL; + temp_cache.c = '\0'; + cache = &temp_cache; + } + if (local_change_detected) { + refresh_cache(cache, kp); + } + + if (cache->c) { + c = cache->c; + break; + } - kp = key; - for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { - struct cache_char* cache = &tag_cache[i]; - struct cache_char temp_cache; - - if (not_locked) { - temp_cache.cache.pinfo = NULL; - temp_cache.c = '\0'; - cache = &temp_cache; - } - if (local_change_detected) { - refresh_cache(cache, kp); - } - - if (cache->c) { - c = cache->c; - break; - } - - kp = key + base_offset; - } + kp = key + base_offset; } + } - switch (toupper(c)) { /* if invalid, resort to global */ + switch (toupper(c)) { /* if invalid, resort to global */ case 'V': case 'D': case 'I': @@ -211,44 +205,45 @@ static int __android_log_level(const char* tag, size_t len, int default_prio) case 'A': case 'S': case BOOLEAN_FALSE: /* Not officially supported */ - break; + break; default: - /* clear '.' after log.tag */ - key[sizeof(log_namespace) - 2] = '\0'; - - kp = key; - for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { - struct cache_char* cache = &global_cache[i]; - struct cache_char temp_cache; - - if (not_locked) { - temp_cache = *cache; - if (temp_cache.cache.pinfo != cache->cache.pinfo) { /* check atomic */ - temp_cache.cache.pinfo = NULL; - temp_cache.c = '\0'; - } - cache = &temp_cache; - } - if (global_change_detected) { - refresh_cache(cache, kp); - } - - if (cache->c) { - c = cache->c; - break; - } - - kp = key + base_offset; + /* clear '.' after log.tag */ + key[sizeof(log_namespace) - 2] = '\0'; + + kp = key; + for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { + struct cache_char* cache = &global_cache[i]; + struct cache_char temp_cache; + + if (not_locked) { + temp_cache = *cache; + if (temp_cache.cache.pinfo != cache->cache.pinfo) { /* check atomic */ + temp_cache.cache.pinfo = NULL; + temp_cache.c = '\0'; + } + cache = &temp_cache; + } + if (global_change_detected) { + refresh_cache(cache, kp); } - break; - } - if (!not_locked) { - global_serial = current_global_serial; - unlock(); - } + if (cache->c) { + c = cache->c; + break; + } - switch (toupper(c)) { + kp = key + base_offset; + } + break; + } + + if (!not_locked) { + global_serial = current_global_serial; + unlock(); + } + + switch (toupper(c)) { + /* clang-format off */ case 'V': return ANDROID_LOG_VERBOSE; case 'D': return ANDROID_LOG_DEBUG; case 'I': return ANDROID_LOG_INFO; @@ -258,57 +253,53 @@ static int __android_log_level(const char* tag, size_t len, int default_prio) case 'A': return ANDROID_LOG_FATAL; case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */ case 'S': return -1; /* ANDROID_LOG_SUPPRESS */ - } - return default_prio; + /* clang-format on */ + } + return default_prio; } -LIBLOG_ABI_PUBLIC int __android_log_is_loggable_len(int prio, - const char* tag, size_t len, - int default_prio) -{ - int logLevel = __android_log_level(tag, len, default_prio); - return logLevel >= 0 && prio >= logLevel; +LIBLOG_ABI_PUBLIC int __android_log_is_loggable_len(int prio, const char* tag, + size_t len, + int default_prio) { + int logLevel = __android_log_level(tag, len, default_prio); + return logLevel >= 0 && prio >= logLevel; } -LIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio, - const char* tag, - int default_prio) -{ - int logLevel = __android_log_level(tag, - (tag && *tag) ? strlen(tag) : 0, - default_prio); - return logLevel >= 0 && prio >= logLevel; +LIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio, const char* tag, + int default_prio) { + int logLevel = + __android_log_level(tag, (tag && *tag) ? strlen(tag) : 0, default_prio); + return logLevel >= 0 && prio >= logLevel; } -LIBLOG_ABI_PRIVATE int __android_log_is_debuggable() -{ - static uint32_t serial; - static struct cache_char tag_cache; - static const char key[] = "ro.debuggable"; - int ret; - - if (tag_cache.c) { /* ro property does not change after set */ - ret = tag_cache.c == '1'; - } else if (lock()) { - struct cache_char temp_cache = { { NULL, -1 }, '\0' }; - refresh_cache(&temp_cache, key); - ret = temp_cache.c == '1'; - } else { - int change_detected = check_cache(&tag_cache.cache); - uint32_t current_serial = __system_property_area_serial(); - if (current_serial != serial) { - change_detected = 1; - } - if (change_detected) { - refresh_cache(&tag_cache, key); - serial = current_serial; - } - ret = tag_cache.c == '1'; - - unlock(); +LIBLOG_ABI_PRIVATE int __android_log_is_debuggable() { + static uint32_t serial; + static struct cache_char tag_cache; + static const char key[] = "ro.debuggable"; + int ret; + + if (tag_cache.c) { /* ro property does not change after set */ + ret = tag_cache.c == '1'; + } else if (lock()) { + struct cache_char temp_cache = { { NULL, -1 }, '\0' }; + refresh_cache(&temp_cache, key); + ret = temp_cache.c == '1'; + } else { + int change_detected = check_cache(&tag_cache.cache); + uint32_t current_serial = __system_property_area_serial(); + if (current_serial != serial) { + change_detected = 1; } + if (change_detected) { + refresh_cache(&tag_cache, key); + serial = current_serial; + } + ret = tag_cache.c == '1'; + + unlock(); + } - return ret; + return ret; } /* @@ -317,100 +308,88 @@ LIBLOG_ABI_PRIVATE int __android_log_is_debuggable() * Use a separate lock from is_loggable to keep contention down b/25563384. */ struct cache2_char { - pthread_mutex_t lock; - uint32_t serial; - const char* key_persist; - struct cache_char cache_persist; - const char* key_ro; - struct cache_char cache_ro; - unsigned char (*const evaluate)(const struct cache2_char *self); + pthread_mutex_t lock; + uint32_t serial; + const char* key_persist; + struct cache_char cache_persist; + const char* key_ro; + struct cache_char cache_ro; + unsigned char (*const evaluate)(const struct cache2_char* self); }; -static inline unsigned char do_cache2_char(struct cache2_char *self) -{ - uint32_t current_serial; - int change_detected; - unsigned char c; - - if (pthread_mutex_trylock(&self->lock)) { - /* We are willing to accept some race in this context */ - return self->evaluate(self); - } - - change_detected = check_cache(&self->cache_persist.cache) - || check_cache(&self->cache_ro.cache); - current_serial = __system_property_area_serial(); - if (current_serial != self->serial) { - change_detected = 1; - } - if (change_detected) { - refresh_cache(&self->cache_persist, self->key_persist); - refresh_cache(&self->cache_ro, self->key_ro); - self->serial = current_serial; - } - c = self->evaluate(self); - - pthread_mutex_unlock(&self->lock); - - return c; +static inline unsigned char do_cache2_char(struct cache2_char* self) { + uint32_t current_serial; + int change_detected; + unsigned char c; + + if (pthread_mutex_trylock(&self->lock)) { + /* We are willing to accept some race in this context */ + return self->evaluate(self); + } + + change_detected = check_cache(&self->cache_persist.cache) || + check_cache(&self->cache_ro.cache); + current_serial = __system_property_area_serial(); + if (current_serial != self->serial) { + change_detected = 1; + } + if (change_detected) { + refresh_cache(&self->cache_persist, self->key_persist); + refresh_cache(&self->cache_ro, self->key_ro); + self->serial = current_serial; + } + c = self->evaluate(self); + + pthread_mutex_unlock(&self->lock); + + return c; } -static unsigned char evaluate_persist_ro(const struct cache2_char *self) -{ - unsigned char c = self->cache_persist.c; +static unsigned char evaluate_persist_ro(const struct cache2_char* self) { + unsigned char c = self->cache_persist.c; - if (c) { - return c; - } + if (c) { + return c; + } - return self->cache_ro.c; + return self->cache_ro.c; } /* * Timestamp state generally remains constant, but can change at any time * to handle developer requirements. */ -LIBLOG_ABI_PUBLIC clockid_t android_log_clockid() -{ - static struct cache2_char clockid = { - PTHREAD_MUTEX_INITIALIZER, - 0, - "persist.logd.timestamp", - { { NULL, -1 }, '\0' }, - "ro.logd.timestamp", - { { NULL, -1 }, '\0' }, - evaluate_persist_ro - }; - - return (tolower(do_cache2_char(&clockid)) == 'm') - ? CLOCK_MONOTONIC - : CLOCK_REALTIME; +LIBLOG_ABI_PUBLIC clockid_t android_log_clockid() { + static struct cache2_char clockid = { + PTHREAD_MUTEX_INITIALIZER, 0, + "persist.logd.timestamp", { { NULL, -1 }, '\0' }, + "ro.logd.timestamp", { { NULL, -1 }, '\0' }, + evaluate_persist_ro + }; + + return (tolower(do_cache2_char(&clockid)) == 'm') ? CLOCK_MONOTONIC + : CLOCK_REALTIME; } /* * Security state generally remains constant, but the DO must be able * to turn off logging should it become spammy after an attack is detected. */ -static unsigned char evaluate_security(const struct cache2_char *self) -{ - unsigned char c = self->cache_ro.c; +static unsigned char evaluate_security(const struct cache2_char* self) { + unsigned char c = self->cache_ro.c; - return (c != BOOLEAN_FALSE) && c && (self->cache_persist.c == BOOLEAN_TRUE); + return (c != BOOLEAN_FALSE) && c && (self->cache_persist.c == BOOLEAN_TRUE); } -LIBLOG_ABI_PUBLIC int __android_log_security() -{ - static struct cache2_char security = { - PTHREAD_MUTEX_INITIALIZER, - 0, - "persist.logd.security", - { { NULL, -1 }, BOOLEAN_FALSE }, - "ro.device_owner", - { { NULL, -1 }, BOOLEAN_FALSE }, - evaluate_security - }; - - return do_cache2_char(&security); +LIBLOG_ABI_PUBLIC int __android_log_security() { + static struct cache2_char security = { + PTHREAD_MUTEX_INITIALIZER, 0, + "persist.logd.security", { { NULL, -1 }, BOOLEAN_FALSE }, + "ro.device_owner", { { NULL, -1 }, BOOLEAN_FALSE }, + evaluate_security + }; + + return do_cache2_char(&security); } /* @@ -420,245 +399,240 @@ LIBLOG_ABI_PUBLIC int __android_log_security() /* Property helper */ static bool check_flag(const char* prop, const char* flag) { - const char* cp = strcasestr(prop, flag); - if (!cp) { - return false; - } - /* We only will document comma (,) */ - static const char sep[] = ",:;|+ \t\f"; - if ((cp != prop) && !strchr(sep, cp[-1])) { - return false; - } - cp += strlen(flag); - return !*cp || !!strchr(sep, *cp); + const char* cp = strcasestr(prop, flag); + if (!cp) { + return false; + } + /* We only will document comma (,) */ + static const char sep[] = ",:;|+ \t\f"; + if ((cp != prop) && !strchr(sep, cp[-1])) { + return false; + } + cp += strlen(flag); + return !*cp || !!strchr(sep, *cp); } /* cache structure */ struct cache_property { - struct cache cache; - char property[PROP_VALUE_MAX]; + struct cache cache; + char property[PROP_VALUE_MAX]; }; -static void refresh_cache_property(struct cache_property* cache, const char* key) -{ +static void refresh_cache_property(struct cache_property* cache, + const char* key) { + if (!cache->cache.pinfo) { + cache->cache.pinfo = __system_property_find(key); if (!cache->cache.pinfo) { - cache->cache.pinfo = __system_property_find(key); - if (!cache->cache.pinfo) { - return; - } + return; } - cache->cache.serial = __system_property_serial(cache->cache.pinfo); - __system_property_read(cache->cache.pinfo, 0, cache->property); + } + cache->cache.serial = __system_property_serial(cache->cache.pinfo); + __system_property_read(cache->cache.pinfo, 0, cache->property); } /* get boolean with the logger twist that supports eng adjustments */ LIBLOG_ABI_PRIVATE bool __android_logger_property_get_bool(const char* key, - int flag) -{ - struct cache_property property = { { NULL, -1 }, { 0 } }; - if (flag & BOOL_DEFAULT_FLAG_PERSIST) { - char newkey[PROP_NAME_MAX]; - snprintf(newkey, sizeof(newkey), "ro.%s", key); - refresh_cache_property(&property, newkey); - property.cache.pinfo = NULL; - property.cache.serial = -1; - snprintf(newkey, sizeof(newkey), "persist.%s", key); - refresh_cache_property(&property, newkey); - property.cache.pinfo = NULL; - property.cache.serial = -1; - } - - refresh_cache_property(&property, key); - - if (check_flag(property.property, "true")) { - return true; - } - if (check_flag(property.property, "false")) { - return false; - } - if (check_flag(property.property, "eng")) { - flag |= BOOL_DEFAULT_FLAG_ENG; - } - /* this is really a "not" flag */ - if (check_flag(property.property, "svelte")) { - flag |= BOOL_DEFAULT_FLAG_SVELTE; - } - - /* Sanity Check */ - if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) { - flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE; - flag |= BOOL_DEFAULT_TRUE; - } - - if ((flag & BOOL_DEFAULT_FLAG_SVELTE) - && __android_logger_property_get_bool("ro.config.low_ram", - BOOL_DEFAULT_FALSE)) { - return false; - } - if ((flag & BOOL_DEFAULT_FLAG_ENG) && !__android_log_is_debuggable()) { - return false; - } - - return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE; + int flag) { + struct cache_property property = { { NULL, -1 }, { 0 } }; + if (flag & BOOL_DEFAULT_FLAG_PERSIST) { + char newkey[PROP_NAME_MAX]; + snprintf(newkey, sizeof(newkey), "ro.%s", key); + refresh_cache_property(&property, newkey); + property.cache.pinfo = NULL; + property.cache.serial = -1; + snprintf(newkey, sizeof(newkey), "persist.%s", key); + refresh_cache_property(&property, newkey); + property.cache.pinfo = NULL; + property.cache.serial = -1; + } + + refresh_cache_property(&property, key); + + if (check_flag(property.property, "true")) { + return true; + } + if (check_flag(property.property, "false")) { + return false; + } + if (check_flag(property.property, "eng")) { + flag |= BOOL_DEFAULT_FLAG_ENG; + } + /* this is really a "not" flag */ + if (check_flag(property.property, "svelte")) { + flag |= BOOL_DEFAULT_FLAG_SVELTE; + } + + /* Sanity Check */ + if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) { + flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE; + flag |= BOOL_DEFAULT_TRUE; + } + + if ((flag & BOOL_DEFAULT_FLAG_SVELTE) && + __android_logger_property_get_bool("ro.config.low_ram", + BOOL_DEFAULT_FALSE)) { + return false; + } + if ((flag & BOOL_DEFAULT_FLAG_ENG) && !__android_log_is_debuggable()) { + return false; + } + + return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE; } -LIBLOG_ABI_PRIVATE bool __android_logger_valid_buffer_size(unsigned long value) -{ - static long pages, pagesize; - unsigned long maximum; +LIBLOG_ABI_PRIVATE bool __android_logger_valid_buffer_size(unsigned long value) { + static long pages, pagesize; + unsigned long maximum; - if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { - return false; - } + if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { + return false; + } - if (!pages) { - pages = sysconf(_SC_PHYS_PAGES); - } - if (pages < 1) { - return true; - } + if (!pages) { + pages = sysconf(_SC_PHYS_PAGES); + } + if (pages < 1) { + return true; + } - if (!pagesize) { - pagesize = sysconf(_SC_PAGESIZE); - if (pagesize <= 1) { - pagesize = PAGE_SIZE; - } + if (!pagesize) { + pagesize = sysconf(_SC_PAGESIZE); + if (pagesize <= 1) { + pagesize = PAGE_SIZE; } + } - /* maximum memory impact a somewhat arbitrary ~3% */ - pages = (pages + 31) / 32; - maximum = pages * pagesize; + /* maximum memory impact a somewhat arbitrary ~3% */ + pages = (pages + 31) / 32; + maximum = pages * pagesize; - if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { - return true; - } + if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { + return true; + } - return value <= maximum; + return value <= maximum; } struct cache2_property_size { - pthread_mutex_t lock; - uint32_t serial; - const char* key_persist; - struct cache_property cache_persist; - const char* key_ro; - struct cache_property cache_ro; - unsigned long (*const evaluate)(const struct cache2_property_size* self); + pthread_mutex_t lock; + uint32_t serial; + const char* key_persist; + struct cache_property cache_persist; + const char* key_ro; + struct cache_property cache_ro; + unsigned long (*const evaluate)(const struct cache2_property_size* self); }; -static inline unsigned long do_cache2_property_size(struct cache2_property_size* self) -{ - uint32_t current_serial; - int change_detected; - unsigned long v; - - if (pthread_mutex_trylock(&self->lock)) { - /* We are willing to accept some race in this context */ - return self->evaluate(self); - } - - change_detected = check_cache(&self->cache_persist.cache) - || check_cache(&self->cache_ro.cache); - current_serial = __system_property_area_serial(); - if (current_serial != self->serial) { - change_detected = 1; - } - if (change_detected) { - refresh_cache_property(&self->cache_persist, self->key_persist); - refresh_cache_property(&self->cache_ro, self->key_ro); - self->serial = current_serial; - } - v = self->evaluate(self); - - pthread_mutex_unlock(&self->lock); - - return v; +static inline unsigned long do_cache2_property_size( + struct cache2_property_size* self) { + uint32_t current_serial; + int change_detected; + unsigned long v; + + if (pthread_mutex_trylock(&self->lock)) { + /* We are willing to accept some race in this context */ + return self->evaluate(self); + } + + change_detected = check_cache(&self->cache_persist.cache) || + check_cache(&self->cache_ro.cache); + current_serial = __system_property_area_serial(); + if (current_serial != self->serial) { + change_detected = 1; + } + if (change_detected) { + refresh_cache_property(&self->cache_persist, self->key_persist); + refresh_cache_property(&self->cache_ro, self->key_ro); + self->serial = current_serial; + } + v = self->evaluate(self); + + pthread_mutex_unlock(&self->lock); + + return v; } -static unsigned long property_get_size_from_cache(const struct cache_property* cache) -{ - char* cp; - unsigned long value = strtoul(cache->property, &cp, 10); +static unsigned long property_get_size_from_cache( + const struct cache_property* cache) { + char* cp; + unsigned long value = strtoul(cache->property, &cp, 10); - switch(*cp) { + switch (*cp) { case 'm': case 'M': - value *= 1024; + value *= 1024; /* FALLTHRU */ case 'k': case 'K': - value *= 1024; + value *= 1024; /* FALLTHRU */ case '\0': - break; + break; default: - value = 0; - } + value = 0; + } - if (!__android_logger_valid_buffer_size(value)) { - value = 0; - } + if (!__android_logger_valid_buffer_size(value)) { + value = 0; + } - return value; + return value; } -static unsigned long evaluate_property_get_size(const struct cache2_property_size* self) -{ - unsigned long size = property_get_size_from_cache(&self->cache_persist); - if (size) { - return size; - } - return property_get_size_from_cache(&self->cache_ro); +static unsigned long evaluate_property_get_size( + const struct cache2_property_size* self) { + unsigned long size = property_get_size_from_cache(&self->cache_persist); + if (size) { + return size; + } + return property_get_size_from_cache(&self->cache_ro); } -LIBLOG_ABI_PRIVATE unsigned long __android_logger_get_buffer_size(log_id_t logId) -{ - static const char global_tunable[] = "persist.logd.size"; /* Settings App */ - static const char global_default[] = "ro.logd.size"; /* BoardConfig.mk */ - static struct cache2_property_size global = { - PTHREAD_MUTEX_INITIALIZER, - 0, - global_tunable, - { { NULL, -1 }, {} }, - global_default, - { { NULL, -1 }, {} }, - evaluate_property_get_size - }; - char key_persist[PROP_NAME_MAX]; - char key_ro[PROP_NAME_MAX]; - struct cache2_property_size local = { - PTHREAD_MUTEX_INITIALIZER, - 0, - key_persist, - { { NULL, -1 }, {} }, - key_ro, - { { NULL, -1 }, {} }, - evaluate_property_get_size - }; - unsigned long property_size, default_size; - - default_size = do_cache2_property_size(&global); - if (!default_size) { - default_size = __android_logger_property_get_bool("ro.config.low_ram", - BOOL_DEFAULT_FALSE) - ? LOG_BUFFER_MIN_SIZE /* 64K */ - : LOG_BUFFER_SIZE; /* 256K */ - } - - snprintf(key_persist, sizeof(key_persist), "%s.%s", - global_tunable, android_log_id_to_name(logId)); - snprintf(key_ro, sizeof(key_ro), "%s.%s", - global_default, android_log_id_to_name(logId)); - property_size = do_cache2_property_size(&local); - - if (!property_size) { - property_size = default_size; - } - - if (!property_size) { - property_size = LOG_BUFFER_SIZE; - } - - return property_size; +LIBLOG_ABI_PRIVATE unsigned long __android_logger_get_buffer_size(log_id_t logId) { + static const char global_tunable[] = "persist.logd.size"; /* Settings App */ + static const char global_default[] = "ro.logd.size"; /* BoardConfig.mk */ + static struct cache2_property_size global = { + /* clang-format off */ + PTHREAD_MUTEX_INITIALIZER, 0, + global_tunable, { { NULL, -1 }, {} }, + global_default, { { NULL, -1 }, {} }, + evaluate_property_get_size + /* clang-format on */ + }; + char key_persist[PROP_NAME_MAX]; + char key_ro[PROP_NAME_MAX]; + struct cache2_property_size local = { + /* clang-format off */ + PTHREAD_MUTEX_INITIALIZER, 0, + key_persist, { { NULL, -1 }, {} }, + key_ro, { { NULL, -1 }, {} }, + evaluate_property_get_size + /* clang-format on */ + }; + unsigned long property_size, default_size; + + default_size = do_cache2_property_size(&global); + if (!default_size) { + default_size = __android_logger_property_get_bool("ro.config.low_ram", + BOOL_DEFAULT_FALSE) + ? LOG_BUFFER_MIN_SIZE /* 64K */ + : LOG_BUFFER_SIZE; /* 256K */ + } + + snprintf(key_persist, sizeof(key_persist), "%s.%s", global_tunable, + android_log_id_to_name(logId)); + snprintf(key_ro, sizeof(key_ro), "%s.%s", global_default, + android_log_id_to_name(logId)); + property_size = do_cache2_property_size(&local); + + if (!property_size) { + property_size = default_size; + } + + if (!property_size) { + property_size = LOG_BUFFER_SIZE; + } + + return property_size; } diff --git a/liblog/stderr_write.c b/liblog/stderr_write.c index b73929923..291ce9322 100644 --- a/liblog/stderr_write.c +++ b/liblog/stderr_write.c @@ -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; - } -#endif + 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; - - 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(); +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; + + 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(); - - 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; + 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; + } - 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; } diff --git a/liblog/tests/benchmark_main.cpp b/liblog/tests/benchmark_main.cpp index e5ef970a5..7367f1b52 100644 --- a/liblog/tests/benchmark_main.cpp +++ b/liblog/tests/benchmark_main.cpp @@ -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); } diff --git a/liblog/tests/libc_test.cpp b/liblog/tests/libc_test.cpp index 8cea7dc72..329ba8585 100644 --- a/liblog/tests/libc_test.cpp +++ b/liblog/tests/libc_test.cpp @@ -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 } diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp index dac84ebe2..5ce9804eb 100644 --- a/liblog/tests/liblog_benchmark.cpp +++ b/liblog/tests/liblog_benchmark.cpp @@ -36,16 +36,15 @@ // non-syscall libs. Since we are benchmarking, or using this in the emergency // signal to stuff a terminating code, we do NOT want to introduce // a syscall or usleep on EAGAIN retry. -#define LOG_FAILURE_RETRY(exp) ({ \ - typeof (exp) _rc; \ - do { \ - _rc = (exp); \ - } while (((_rc == -1) \ - && ((errno == EINTR) \ - || (errno == EAGAIN))) \ - || (_rc == -EINTR) \ - || (_rc == -EAGAIN)); \ - _rc; }) +#define LOG_FAILURE_RETRY(exp) \ + ({ \ + typeof(exp) _rc; \ + do { \ + _rc = (exp); \ + } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \ + (_rc == -EINTR) || (_rc == -EAGAIN)); \ + _rc; \ + }) /* * Measure the fastest rate we can reliabley stuff print messages into @@ -53,15 +52,14 @@ * wakeup time (2ms?) */ static void BM_log_maximum_retry(int iters) { - StartBenchmarkTiming(); + StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - LOG_FAILURE_RETRY( - __android_log_print(ANDROID_LOG_INFO, - "BM_log_maximum_retry", "%d", i)); - } + for (int i = 0; i < iters; ++i) { + LOG_FAILURE_RETRY( + __android_log_print(ANDROID_LOG_INFO, "BM_log_maximum_retry", "%d", i)); + } - StopBenchmarkTiming(); + StopBenchmarkTiming(); } BENCHMARK(BM_log_maximum_retry); @@ -71,28 +69,28 @@ BENCHMARK(BM_log_maximum_retry); * time (2ms?) */ static void BM_log_maximum(int iters) { - StartBenchmarkTiming(); + StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - __android_log_print(ANDROID_LOG_INFO, "BM_log_maximum", "%d", i); - } + for (int i = 0; i < iters; ++i) { + __android_log_print(ANDROID_LOG_INFO, "BM_log_maximum", "%d", i); + } - StopBenchmarkTiming(); + StopBenchmarkTiming(); } BENCHMARK(BM_log_maximum); static void set_log_null() { - android_set_log_frontend(LOGGER_NULL); + android_set_log_frontend(LOGGER_NULL); } static void set_log_default() { - android_set_log_frontend(LOGGER_DEFAULT); + android_set_log_frontend(LOGGER_DEFAULT); } static void BM_log_maximum_null(int iters) { - set_log_null(); - BM_log_maximum(iters); - set_log_default(); + set_log_null(); + BM_log_maximum(iters); + set_log_default(); } BENCHMARK(BM_log_maximum_null); @@ -106,10 +104,10 @@ BENCHMARK(BM_log_maximum_null); * clock_gettime to be zero-syscall. */ static void BM_clock_overhead(int iters) { - for (int i = 0; i < iters; ++i) { - StartBenchmarkTiming(); - StopBenchmarkTiming(); - } + for (int i = 0; i < iters; ++i) { + StartBenchmarkTiming(); + StopBenchmarkTiming(); + } } BENCHMARK(BM_clock_overhead); @@ -117,75 +115,74 @@ BENCHMARK(BM_clock_overhead); * Measure the time it takes to submit the android logging data to pstore */ static void BM_pmsg_short(int iters) { - - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); - if (pstore_fd < 0) { - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // 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; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(android_log_clockid(), &ts); - - android_pmsg_log_header_t pmsg_header; - pmsg_header.magic = LOGGER_MAGIC; - pmsg_header.len = sizeof(android_pmsg_log_header_t) - + sizeof(android_log_header_t); - pmsg_header.uid = getuid(); - pmsg_header.pid = getpid(); - - android_log_header_t header; - header.tid = gettid(); - header.realtime.tv_sec = ts.tv_sec; - header.realtime.tv_nsec = ts.tv_nsec; - - static const unsigned nr = 1; - static const unsigned header_length = 2; - struct iovec newVec[nr + header_length]; - - newVec[0].iov_base = (unsigned char *) &pmsg_header; - newVec[0].iov_len = sizeof(pmsg_header); - newVec[1].iov_base = (unsigned char *) &header; - newVec[1].iov_len = sizeof(header); - - android_log_event_int_t buffer; - - header.id = LOG_ID_EVENTS; - buffer.header.tag = 0; - buffer.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; + int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); + if (pstore_fd < 0) { + return; + } + + /* + * struct { + * // what we provide to pstore + * android_pmsg_log_header_t pmsg_header; + * // 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; + * }; + * }; + */ + + struct timespec ts; + clock_gettime(android_log_clockid(), &ts); + + android_pmsg_log_header_t pmsg_header; + pmsg_header.magic = LOGGER_MAGIC; + pmsg_header.len = + sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); + pmsg_header.uid = getuid(); + pmsg_header.pid = getpid(); + + android_log_header_t header; + header.tid = gettid(); + header.realtime.tv_sec = ts.tv_sec; + header.realtime.tv_nsec = ts.tv_nsec; + + static const unsigned nr = 1; + static const unsigned header_length = 2; + struct iovec newVec[nr + header_length]; + + newVec[0].iov_base = (unsigned char*)&pmsg_header; + newVec[0].iov_len = sizeof(pmsg_header); + newVec[1].iov_base = (unsigned char*)&header; + newVec[1].iov_len = sizeof(header); + + android_log_event_int_t buffer; + + header.id = LOG_ID_EVENTS; + buffer.header.tag = 0; + buffer.payload.type = EVENT_TYPE_INT; + uint32_t snapshot = 0; + buffer.payload.data = htole32(snapshot); + + newVec[2].iov_base = &buffer; + newVec[2].iov_len = sizeof(buffer); + + StartBenchmarkTiming(); + for (int i = 0; i < iters; ++i) { + ++snapshot; buffer.payload.data = htole32(snapshot); - - newVec[2].iov_base = &buffer; - newVec[2].iov_len = sizeof(buffer); - - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - ++snapshot; - buffer.payload.data = htole32(snapshot); - writev(pstore_fd, newVec, nr); - } - StopBenchmarkTiming(); - close(pstore_fd); + writev(pstore_fd, newVec, nr); + } + StopBenchmarkTiming(); + close(pstore_fd); } BENCHMARK(BM_pmsg_short); @@ -194,74 +191,72 @@ BENCHMARK(BM_pmsg_short); * best case aligned single block. */ static void BM_pmsg_short_aligned(int iters) { - - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); - if (pstore_fd < 0) { - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // 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; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(android_log_clockid(), &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8]; - memset(buf, 0, sizeof(buf)); - struct packet *buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7); - if (((uintptr_t)&buffer->pmsg_header) & 7) { - fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t) - + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; + int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); + if (pstore_fd < 0) { + return; + } + + /* + * struct { + * // what we provide to pstore + * android_pmsg_log_header_t pmsg_header; + * // 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; + * }; + * }; + */ + + struct timespec ts; + clock_gettime(android_log_clockid(), &ts); + + struct packet { + android_pmsg_log_header_t pmsg_header; + android_log_header_t header; + android_log_event_int_t payload; + }; + alignas(8) char buf[sizeof(struct packet) + 8]; + memset(buf, 0, sizeof(buf)); + struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7); + if (((uintptr_t)&buffer->pmsg_header) & 7) { + fprintf(stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); + } + + buffer->pmsg_header.magic = LOGGER_MAGIC; + buffer->pmsg_header.len = + sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); + buffer->pmsg_header.uid = getuid(); + buffer->pmsg_header.pid = getpid(); + + buffer->header.tid = gettid(); + buffer->header.realtime.tv_sec = ts.tv_sec; + buffer->header.realtime.tv_nsec = ts.tv_nsec; + + buffer->header.id = LOG_ID_EVENTS; + buffer->payload.header.tag = 0; + buffer->payload.payload.type = EVENT_TYPE_INT; + uint32_t snapshot = 0; + buffer->payload.payload.data = htole32(snapshot); + + StartBenchmarkTiming(); + for (int i = 0; i < iters; ++i) { + ++snapshot; buffer->payload.payload.data = htole32(snapshot); - - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - ++snapshot; - buffer->payload.payload.data = htole32(snapshot); - write(pstore_fd, &buffer->pmsg_header, - sizeof(android_pmsg_log_header_t) + - sizeof(android_log_header_t) + - sizeof(android_log_event_int_t)); - } - StopBenchmarkTiming(); - close(pstore_fd); + write(pstore_fd, &buffer->pmsg_header, + sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) + + sizeof(android_log_event_int_t)); + } + StopBenchmarkTiming(); + close(pstore_fd); } BENCHMARK(BM_pmsg_short_aligned); @@ -270,74 +265,72 @@ BENCHMARK(BM_pmsg_short_aligned); * best case aligned single block. */ static void BM_pmsg_short_unaligned1(int iters) { - - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); - if (pstore_fd < 0) { - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // 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; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(android_log_clockid(), &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8]; - memset(buf, 0, sizeof(buf)); - struct packet *buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1); - if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) { - fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t) - + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; + int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); + if (pstore_fd < 0) { + return; + } + + /* + * struct { + * // what we provide to pstore + * android_pmsg_log_header_t pmsg_header; + * // 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; + * }; + * }; + */ + + struct timespec ts; + clock_gettime(android_log_clockid(), &ts); + + struct packet { + android_pmsg_log_header_t pmsg_header; + android_log_header_t header; + android_log_event_int_t payload; + }; + alignas(8) char buf[sizeof(struct packet) + 8]; + memset(buf, 0, sizeof(buf)); + struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1); + if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) { + fprintf(stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); + } + + buffer->pmsg_header.magic = LOGGER_MAGIC; + buffer->pmsg_header.len = + sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); + buffer->pmsg_header.uid = getuid(); + buffer->pmsg_header.pid = getpid(); + + buffer->header.tid = gettid(); + buffer->header.realtime.tv_sec = ts.tv_sec; + buffer->header.realtime.tv_nsec = ts.tv_nsec; + + buffer->header.id = LOG_ID_EVENTS; + buffer->payload.header.tag = 0; + buffer->payload.payload.type = EVENT_TYPE_INT; + uint32_t snapshot = 0; + buffer->payload.payload.data = htole32(snapshot); + + StartBenchmarkTiming(); + for (int i = 0; i < iters; ++i) { + ++snapshot; buffer->payload.payload.data = htole32(snapshot); - - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - ++snapshot; - buffer->payload.payload.data = htole32(snapshot); - write(pstore_fd, &buffer->pmsg_header, - sizeof(android_pmsg_log_header_t) + - sizeof(android_log_header_t) + - sizeof(android_log_event_int_t)); - } - StopBenchmarkTiming(); - close(pstore_fd); + write(pstore_fd, &buffer->pmsg_header, + sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t) + + sizeof(android_log_event_int_t)); + } + StopBenchmarkTiming(); + close(pstore_fd); } BENCHMARK(BM_pmsg_short_unaligned1); @@ -346,71 +339,70 @@ BENCHMARK(BM_pmsg_short_unaligned1); * best case aligned single block. */ static void BM_pmsg_long_aligned(int iters) { - - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); - if (pstore_fd < 0) { - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // 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; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(android_log_clockid(), &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD]; - memset(buf, 0, sizeof(buf)); - struct packet *buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7); - if (((uintptr_t)&buffer->pmsg_header) & 7) { - fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t) - + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; + int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); + if (pstore_fd < 0) { + return; + } + + /* + * struct { + * // what we provide to pstore + * android_pmsg_log_header_t pmsg_header; + * // 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; + * }; + * }; + */ + + struct timespec ts; + clock_gettime(android_log_clockid(), &ts); + + struct packet { + android_pmsg_log_header_t pmsg_header; + android_log_header_t header; + android_log_event_int_t payload; + }; + alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD]; + memset(buf, 0, sizeof(buf)); + struct packet* buffer = (struct packet*)(((uintptr_t)buf + 7) & ~7); + if (((uintptr_t)&buffer->pmsg_header) & 7) { + fprintf(stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); + } + + buffer->pmsg_header.magic = LOGGER_MAGIC; + buffer->pmsg_header.len = + sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); + buffer->pmsg_header.uid = getuid(); + buffer->pmsg_header.pid = getpid(); + + buffer->header.tid = gettid(); + buffer->header.realtime.tv_sec = ts.tv_sec; + buffer->header.realtime.tv_nsec = ts.tv_nsec; + + buffer->header.id = LOG_ID_EVENTS; + buffer->payload.header.tag = 0; + buffer->payload.payload.type = EVENT_TYPE_INT; + uint32_t snapshot = 0; + buffer->payload.payload.data = htole32(snapshot); + + StartBenchmarkTiming(); + for (int i = 0; i < iters; ++i) { + ++snapshot; buffer->payload.payload.data = htole32(snapshot); - - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - ++snapshot; - buffer->payload.payload.data = htole32(snapshot); - write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD); - } - StopBenchmarkTiming(); - close(pstore_fd); + write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD); + } + StopBenchmarkTiming(); + close(pstore_fd); } BENCHMARK(BM_pmsg_long_aligned); @@ -419,71 +411,70 @@ BENCHMARK(BM_pmsg_long_aligned); * best case aligned single block. */ static void BM_pmsg_long_unaligned1(int iters) { - - int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); - if (pstore_fd < 0) { - return; - } - - /* - * struct { - * // what we provide to pstore - * android_pmsg_log_header_t pmsg_header; - * // 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; - * }; - * }; - */ - - struct timespec ts; - clock_gettime(android_log_clockid(), &ts); - - struct packet { - android_pmsg_log_header_t pmsg_header; - android_log_header_t header; - android_log_event_int_t payload; - }; - alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD]; - memset(buf, 0, sizeof(buf)); - struct packet *buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1); - if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) { - fprintf (stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); - } - - buffer->pmsg_header.magic = LOGGER_MAGIC; - buffer->pmsg_header.len = sizeof(android_pmsg_log_header_t) - + sizeof(android_log_header_t); - buffer->pmsg_header.uid = getuid(); - buffer->pmsg_header.pid = getpid(); - - buffer->header.tid = gettid(); - buffer->header.realtime.tv_sec = ts.tv_sec; - buffer->header.realtime.tv_nsec = ts.tv_nsec; - - buffer->header.id = LOG_ID_EVENTS; - buffer->payload.header.tag = 0; - buffer->payload.payload.type = EVENT_TYPE_INT; - uint32_t snapshot = 0; + int pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY)); + if (pstore_fd < 0) { + return; + } + + /* + * struct { + * // what we provide to pstore + * android_pmsg_log_header_t pmsg_header; + * // 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; + * }; + * }; + */ + + struct timespec ts; + clock_gettime(android_log_clockid(), &ts); + + struct packet { + android_pmsg_log_header_t pmsg_header; + android_log_header_t header; + android_log_event_int_t payload; + }; + alignas(8) char buf[sizeof(struct packet) + 8 + LOGGER_ENTRY_MAX_PAYLOAD]; + memset(buf, 0, sizeof(buf)); + struct packet* buffer = (struct packet*)((((uintptr_t)buf + 7) & ~7) + 1); + if ((((uintptr_t)&buffer->pmsg_header) & 7) != 1) { + fprintf(stderr, "&buffer=0x%p iters=%d\n", &buffer->pmsg_header, iters); + } + + buffer->pmsg_header.magic = LOGGER_MAGIC; + buffer->pmsg_header.len = + sizeof(android_pmsg_log_header_t) + sizeof(android_log_header_t); + buffer->pmsg_header.uid = getuid(); + buffer->pmsg_header.pid = getpid(); + + buffer->header.tid = gettid(); + buffer->header.realtime.tv_sec = ts.tv_sec; + buffer->header.realtime.tv_nsec = ts.tv_nsec; + + buffer->header.id = LOG_ID_EVENTS; + buffer->payload.header.tag = 0; + buffer->payload.payload.type = EVENT_TYPE_INT; + uint32_t snapshot = 0; + buffer->payload.payload.data = htole32(snapshot); + + StartBenchmarkTiming(); + for (int i = 0; i < iters; ++i) { + ++snapshot; buffer->payload.payload.data = htole32(snapshot); - - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - ++snapshot; - buffer->payload.payload.data = htole32(snapshot); - write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD); - } - StopBenchmarkTiming(); - close(pstore_fd); + write(pstore_fd, &buffer->pmsg_header, LOGGER_ENTRY_MAX_PAYLOAD); + } + StopBenchmarkTiming(); + close(pstore_fd); } BENCHMARK(BM_pmsg_long_unaligned1); @@ -494,26 +485,26 @@ BENCHMARK(BM_pmsg_long_unaligned1); * time if zero-syscall time. */ /* helper function */ -static void test_print(const char *fmt, ...) { - va_list ap; - char buf[1024]; +static void test_print(const char* fmt, ...) { + va_list ap; + char buf[1024]; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); } -#define logd_yield() sched_yield() // allow logd to catch up -#define logd_sleep() usleep(50) // really allow logd to catch up +#define logd_yield() sched_yield() // allow logd to catch up +#define logd_sleep() usleep(50) // really allow logd to catch up /* performance test */ static void BM_sprintf_overhead(int iters) { - for (int i = 0; i < iters; ++i) { - StartBenchmarkTiming(); - test_print("BM_sprintf_overhead:%d", i); - StopBenchmarkTiming(); - logd_yield(); - } + for (int i = 0; i < iters; ++i) { + StartBenchmarkTiming(); + test_print("BM_sprintf_overhead:%d", i); + StopBenchmarkTiming(); + logd_yield(); + } } BENCHMARK(BM_sprintf_overhead); @@ -524,12 +515,12 @@ BENCHMARK(BM_sprintf_overhead); * syscall periods (40us) plus time to run *printf */ static void BM_log_print_overhead(int iters) { - for (int i = 0; i < iters; ++i) { - StartBenchmarkTiming(); - __android_log_print(ANDROID_LOG_INFO, "BM_log_overhead", "%d", i); - StopBenchmarkTiming(); - logd_yield(); - } + for (int i = 0; i < iters; ++i) { + StartBenchmarkTiming(); + __android_log_print(ANDROID_LOG_INFO, "BM_log_overhead", "%d", i); + StopBenchmarkTiming(); + logd_yield(); + } } BENCHMARK(BM_log_print_overhead); @@ -539,19 +530,19 @@ BENCHMARK(BM_log_print_overhead); * under light load. Expect this to be a dozen or so syscall periods (40us) */ static void BM_log_event_overhead(int iters) { - for (unsigned long long i = 0; i < (unsigned)iters; ++i) { - StartBenchmarkTiming(); - __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i)); - StopBenchmarkTiming(); - logd_yield(); - } + for (unsigned long long i = 0; i < (unsigned)iters; ++i) { + StartBenchmarkTiming(); + __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i)); + StopBenchmarkTiming(); + logd_yield(); + } } BENCHMARK(BM_log_event_overhead); static void BM_log_event_overhead_null(int iters) { - set_log_null(); - BM_log_event_overhead(iters); - set_log_default(); + set_log_null(); + BM_log_event_overhead(iters); + set_log_default(); } BENCHMARK(BM_log_event_overhead_null); @@ -561,40 +552,38 @@ BENCHMARK(BM_log_event_overhead_null); * under very-light load (<1% CPU utilization). */ static void BM_log_light_overhead(int iters) { - for (unsigned long long i = 0; i < (unsigned)iters; ++i) { - StartBenchmarkTiming(); - __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i)); - StopBenchmarkTiming(); - usleep(10000); - } + for (unsigned long long i = 0; i < (unsigned)iters; ++i) { + StartBenchmarkTiming(); + __android_log_btwrite(0, EVENT_TYPE_LONG, &i, sizeof(i)); + StopBenchmarkTiming(); + usleep(10000); + } } BENCHMARK(BM_log_light_overhead); static void BM_log_light_overhead_null(int iters) { - set_log_null(); - BM_log_light_overhead(iters); - set_log_default(); + set_log_null(); + BM_log_light_overhead(iters); + set_log_default(); } BENCHMARK(BM_log_light_overhead_null); -static void caught_latency(int /*signum*/) -{ - unsigned long long v = 0xDEADBEEFA55A5AA5ULL; +static void caught_latency(int /*signum*/) { + unsigned long long v = 0xDEADBEEFA55A5AA5ULL; - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); + LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); } -static unsigned long long caught_convert(char *cp) -{ - unsigned long long l = cp[0] & 0xFF; - l |= (unsigned long long) (cp[1] & 0xFF) << 8; - l |= (unsigned long long) (cp[2] & 0xFF) << 16; - l |= (unsigned long long) (cp[3] & 0xFF) << 24; - l |= (unsigned long long) (cp[4] & 0xFF) << 32; - l |= (unsigned long long) (cp[5] & 0xFF) << 40; - l |= (unsigned long long) (cp[6] & 0xFF) << 48; - l |= (unsigned long long) (cp[7] & 0xFF) << 56; - return l; +static unsigned long long caught_convert(char* cp) { + unsigned long long l = cp[0] & 0xFF; + l |= (unsigned long long)(cp[1] & 0xFF) << 8; + l |= (unsigned long long)(cp[2] & 0xFF) << 16; + l |= (unsigned long long)(cp[3] & 0xFF) << 24; + l |= (unsigned long long)(cp[4] & 0xFF) << 32; + l |= (unsigned long long)(cp[5] & 0xFF) << 40; + l |= (unsigned long long)(cp[6] & 0xFF) << 48; + l |= (unsigned long long)(cp[7] & 0xFF) << 56; + return l; } static const int alarm_time = 3; @@ -605,77 +594,75 @@ static const int alarm_time = 3; * 4 syscalls (3us). */ static void BM_log_latency(int iters) { - pid_t pid = getpid(); - - struct logger_list * logger_list = android_logger_list_open(LOG_ID_EVENTS, - ANDROID_LOG_RDONLY, 0, pid); - - if (!logger_list) { - fprintf(stderr, "Unable to open events log: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - signal(SIGALRM, caught_latency); - alarm(alarm_time); - - for (int j = 0, i = 0; i < iters && j < 10*iters; ++i, ++j) { - log_time ts; - LOG_FAILURE_RETRY(( - ts = log_time(CLOCK_REALTIME), - android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts)))); - - for (;;) { - log_msg log_msg; - int ret = android_logger_list_read(logger_list, &log_msg); - alarm(alarm_time); - - if (ret <= 0) { - iters = i; - break; - } - if ((log_msg.entry.len != (4 + 1 + 8)) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } - - char* eventData = log_msg.msg(); - - if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) { - continue; - } - log_time tx(eventData + 4 + 1); - if (ts != tx) { - if (0xDEADBEEFA55A5AA5ULL == caught_convert(eventData + 4 + 1)) { - iters = i; - break; - } - continue; - } - - uint64_t start = ts.nsec(); - uint64_t end = log_msg.nsec(); - if (end >= start) { - StartBenchmarkTiming(start); - StopBenchmarkTiming(end); - } else { - --i; - } - break; + pid_t pid = getpid(); + + struct logger_list* logger_list = + android_logger_list_open(LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 0, pid); + + if (!logger_list) { + fprintf(stderr, "Unable to open events log: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + signal(SIGALRM, caught_latency); + alarm(alarm_time); + + for (int j = 0, i = 0; i < iters && j < 10 * iters; ++i, ++j) { + log_time ts; + LOG_FAILURE_RETRY((ts = log_time(CLOCK_REALTIME), + android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts)))); + + for (;;) { + log_msg log_msg; + int ret = android_logger_list_read(logger_list, &log_msg); + alarm(alarm_time); + + if (ret <= 0) { + iters = i; + break; + } + if ((log_msg.entry.len != (4 + 1 + 8)) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; + } + + char* eventData = log_msg.msg(); + + if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) { + continue; + } + log_time tx(eventData + 4 + 1); + if (ts != tx) { + if (0xDEADBEEFA55A5AA5ULL == caught_convert(eventData + 4 + 1)) { + iters = i; + break; } + continue; + } + + uint64_t start = ts.nsec(); + uint64_t end = log_msg.nsec(); + if (end >= start) { + StartBenchmarkTiming(start); + StopBenchmarkTiming(end); + } else { + --i; + } + break; } + } - signal(SIGALRM, SIG_DFL); - alarm(0); + signal(SIGALRM, SIG_DFL); + alarm(0); - android_logger_list_free(logger_list); + android_logger_list_free(logger_list); } BENCHMARK(BM_log_latency); -static void caught_delay(int /*signum*/) -{ - unsigned long long v = 0xDEADBEEFA55A5AA6ULL; +static void caught_delay(int /*signum*/) { + unsigned long long v = 0xDEADBEEFA55A5AA6ULL; - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); + LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); } /* @@ -683,65 +670,64 @@ static void caught_delay(int /*signum*/) * the logs. Expect this to be less than double the process wakeup time (2ms). */ static void BM_log_delay(int iters) { - pid_t pid = getpid(); - - struct logger_list * logger_list = android_logger_list_open(LOG_ID_EVENTS, - ANDROID_LOG_RDONLY, 0, pid); - - if (!logger_list) { - fprintf(stderr, "Unable to open events log: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - - signal(SIGALRM, caught_delay); - alarm(alarm_time); - - StartBenchmarkTiming(); - - for (int i = 0; i < iters; ++i) { - log_time ts(CLOCK_REALTIME); - - LOG_FAILURE_RETRY( - android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - - for (;;) { - log_msg log_msg; - int ret = android_logger_list_read(logger_list, &log_msg); - alarm(alarm_time); - - if (ret <= 0) { - iters = i; - break; - } - if ((log_msg.entry.len != (4 + 1 + 8)) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } - - char* eventData = log_msg.msg(); - - if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) { - continue; - } - log_time tx(eventData + 4 + 1); - if (ts != tx) { - if (0xDEADBEEFA55A5AA6ULL == caught_convert(eventData + 4 + 1)) { - iters = i; - break; - } - continue; - } - - break; + pid_t pid = getpid(); + + struct logger_list* logger_list = + android_logger_list_open(LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 0, pid); + + if (!logger_list) { + fprintf(stderr, "Unable to open events log: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + + signal(SIGALRM, caught_delay); + alarm(alarm_time); + + StartBenchmarkTiming(); + + for (int i = 0; i < iters; ++i) { + log_time ts(CLOCK_REALTIME); + + LOG_FAILURE_RETRY(android_btWriteLog(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); + + for (;;) { + log_msg log_msg; + int ret = android_logger_list_read(logger_list, &log_msg); + alarm(alarm_time); + + if (ret <= 0) { + iters = i; + break; + } + if ((log_msg.entry.len != (4 + 1 + 8)) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; + } + + char* eventData = log_msg.msg(); + + if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) { + continue; + } + log_time tx(eventData + 4 + 1); + if (ts != tx) { + if (0xDEADBEEFA55A5AA6ULL == caught_convert(eventData + 4 + 1)) { + iters = i; + break; } + continue; + } + + break; } + } - signal(SIGALRM, SIG_DFL); - alarm(0); + signal(SIGALRM, SIG_DFL); + alarm(0); - StopBenchmarkTiming(); + StopBenchmarkTiming(); - android_logger_list_free(logger_list); + android_logger_list_free(logger_list); } BENCHMARK(BM_log_delay); @@ -749,17 +735,16 @@ BENCHMARK(BM_log_delay); * Measure the time it takes for __android_log_is_loggable. */ static void BM_is_loggable(int iters) { - static const char logd[] = "logd"; + static const char logd[] = "logd"; - StartBenchmarkTiming(); + StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - __android_log_is_loggable_len(ANDROID_LOG_WARN, - logd, strlen(logd), - ANDROID_LOG_VERBOSE); - } + for (int i = 0; i < iters; ++i) { + __android_log_is_loggable_len(ANDROID_LOG_WARN, logd, strlen(logd), + ANDROID_LOG_VERBOSE); + } - StopBenchmarkTiming(); + StopBenchmarkTiming(); } BENCHMARK(BM_is_loggable); @@ -767,13 +752,13 @@ BENCHMARK(BM_is_loggable); * Measure the time it takes for android_log_clockid. */ static void BM_clockid(int iters) { - StartBenchmarkTiming(); + StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - android_log_clockid(); - } + for (int i = 0; i < iters; ++i) { + android_log_clockid(); + } - StopBenchmarkTiming(); + StopBenchmarkTiming(); } BENCHMARK(BM_clockid); @@ -781,13 +766,13 @@ BENCHMARK(BM_clockid); * Measure the time it takes for __android_log_security. */ static void BM_security(int iters) { - StartBenchmarkTiming(); + StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - __android_log_security(); - } + for (int i = 0; i < iters; ++i) { + __android_log_security(); + } - StopBenchmarkTiming(); + StopBenchmarkTiming(); } BENCHMARK(BM_security); @@ -796,41 +781,40 @@ static std::unordered_set<uint32_t> set; static EventTagMap* map; static bool prechargeEventMap() { - if (map) return true; + if (map) return true; - fprintf(stderr, "Precharge: start\n"); + fprintf(stderr, "Precharge: start\n"); - map = android_openEventTagMap(NULL); - for (uint32_t tag = 1; tag < USHRT_MAX; ++tag) { - size_t len; - if (android_lookupEventTag_len(map, &len, tag) == NULL) continue; - set.insert(tag); - } + map = android_openEventTagMap(NULL); + for (uint32_t tag = 1; tag < USHRT_MAX; ++tag) { + size_t len; + if (android_lookupEventTag_len(map, &len, tag) == NULL) continue; + set.insert(tag); + } - fprintf(stderr, "Precharge: stop %zu\n", set.size()); + fprintf(stderr, "Precharge: stop %zu\n", set.size()); - return true; + return true; } /* * Measure the time it takes for android_lookupEventTag_len */ static void BM_lookupEventTag(int iters) { + prechargeEventMap(); - prechargeEventMap(); + std::unordered_set<uint32_t>::const_iterator it = set.begin(); - std::unordered_set<uint32_t>::const_iterator it = set.begin(); + StartBenchmarkTiming(); - StartBenchmarkTiming(); - - for (int i = 0; i < iters; ++i) { - size_t len; - android_lookupEventTag_len(map, &len, (*it)); - ++it; - if (it == set.end()) it = set.begin(); - } + for (int i = 0; i < iters; ++i) { + size_t len; + android_lookupEventTag_len(map, &len, (*it)); + ++it; + if (it == set.end()) it = set.begin(); + } - StopBenchmarkTiming(); + StopBenchmarkTiming(); } BENCHMARK(BM_lookupEventTag); @@ -840,25 +824,24 @@ BENCHMARK(BM_lookupEventTag); static uint32_t notTag = 1; static void BM_lookupEventTag_NOT(int iters) { + prechargeEventMap(); - prechargeEventMap(); - - while (set.find(notTag) != set.end()) { - ++notTag; - if (notTag >= USHRT_MAX) notTag = 1; - } + while (set.find(notTag) != set.end()) { + ++notTag; + if (notTag >= USHRT_MAX) notTag = 1; + } - StartBenchmarkTiming(); + StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { - size_t len; - android_lookupEventTag_len(map, &len, notTag); - } + for (int i = 0; i < iters; ++i) { + size_t len; + android_lookupEventTag_len(map, &len, notTag); + } - StopBenchmarkTiming(); + StopBenchmarkTiming(); - ++notTag; - if (notTag >= USHRT_MAX) notTag = 1; + ++notTag; + if (notTag >= USHRT_MAX) notTag = 1; } BENCHMARK(BM_lookupEventTag_NOT); @@ -866,21 +849,20 @@ BENCHMARK(BM_lookupEventTag_NOT); * Measure the time it takes for android_lookupEventFormat_len */ static void BM_lookupEventFormat(int iters) { + prechargeEventMap(); - prechargeEventMap(); + std::unordered_set<uint32_t>::const_iterator it = set.begin(); - std::unordered_set<uint32_t>::const_iterator it = set.begin(); + StartBenchmarkTiming(); - StartBenchmarkTiming(); + for (int i = 0; i < iters; ++i) { + size_t len; + android_lookupEventFormat_len(map, &len, (*it)); + ++it; + if (it == set.end()) it = set.begin(); + } - for (int i = 0; i < iters; ++i) { - size_t len; - android_lookupEventFormat_len(map, &len, (*it)); - ++it; - if (it == set.end()) it = set.begin(); - } - - StopBenchmarkTiming(); + StopBenchmarkTiming(); } BENCHMARK(BM_lookupEventFormat); @@ -888,137 +870,135 @@ BENCHMARK(BM_lookupEventFormat); * Measure the time it takes for android_lookupEventTagNum plus above */ static void BM_lookupEventTagNum(int iters) { + prechargeEventMap(); - prechargeEventMap(); - - std::unordered_set<uint32_t>::const_iterator it = set.begin(); - - for (int i = 0; i < iters; ++i) { - size_t len; - const char* name = android_lookupEventTag_len(map, &len, (*it)); - std::string Name(name, len); - const char* format = android_lookupEventFormat_len(map, &len, (*it)); - std::string Format(format, len); - StartBenchmarkTiming(); - android_lookupEventTagNum(map, Name.c_str(), Format.c_str(), - ANDROID_LOG_UNKNOWN); - StopBenchmarkTiming(); - ++it; - if (it == set.end()) it = set.begin(); - } + std::unordered_set<uint32_t>::const_iterator it = set.begin(); + for (int i = 0; i < iters; ++i) { + size_t len; + const char* name = android_lookupEventTag_len(map, &len, (*it)); + std::string Name(name, len); + const char* format = android_lookupEventFormat_len(map, &len, (*it)); + std::string Format(format, len); + StartBenchmarkTiming(); + android_lookupEventTagNum(map, Name.c_str(), Format.c_str(), + ANDROID_LOG_UNKNOWN); + StopBenchmarkTiming(); + ++it; + if (it == set.end()) it = set.begin(); + } } BENCHMARK(BM_lookupEventTagNum); // Must be functionally identical to liblog internal __send_log_msg. -static void send_to_control(char *buf, size_t len) -{ - int sock = socket_local_client("logd", - ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_STREAM); - if (sock < 0) return; - size_t writeLen = strlen(buf) + 1; - - ssize_t ret = TEMP_FAILURE_RETRY(write(sock, buf, writeLen)); - if (ret <= 0) { - close(sock); - return; - } - while ((ret = read(sock, buf, len)) > 0) { - if (((size_t)ret == len) || (len < PAGE_SIZE)) { - break; - } - len -= ret; - buf += ret; - - struct pollfd p = { - .fd = sock, - .events = POLLIN, - .revents = 0 - }; - - ret = poll(&p, 1, 20); - if ((ret <= 0) || !(p.revents & POLLIN)) { - break; - } - } +static void send_to_control(char* buf, size_t len) { + int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, + SOCK_STREAM); + if (sock < 0) return; + size_t writeLen = strlen(buf) + 1; + + ssize_t ret = TEMP_FAILURE_RETRY(write(sock, buf, writeLen)); + if (ret <= 0) { close(sock); -} - -static void BM_lookupEventTagNum_logd_new(int iters) { - fprintf(stderr, "WARNING: " - "This test can cause logd to grow in size and hit DOS limiter\n"); - // Make copies - static const char empty_event_log_tags[] = "# content owned by logd\n"; - static const char dev_event_log_tags_path[] = "/dev/event-log-tags"; - std::string dev_event_log_tags; - if (android::base::ReadFileToString(dev_event_log_tags_path, - &dev_event_log_tags) && - (dev_event_log_tags.length() == 0)) { - dev_event_log_tags = empty_event_log_tags; - } - static const char data_event_log_tags_path[] = "/data/misc/logd/event-log-tags"; - std::string data_event_log_tags; - if (android::base::ReadFileToString(data_event_log_tags_path, - &data_event_log_tags) && - (data_event_log_tags.length() == 0)) { - data_event_log_tags = empty_event_log_tags; + return; + } + while ((ret = read(sock, buf, len)) > 0) { + if (((size_t)ret == len) || (len < PAGE_SIZE)) { + break; } + len -= ret; + buf += ret; - for (int i = 0; i < iters; ++i) { - char buffer[256]; - memset(buffer, 0, sizeof(buffer)); - log_time now(CLOCK_MONOTONIC); - char name[64]; - snprintf(name, sizeof(name), "a%" PRIu64, now.nsec()); - snprintf(buffer, sizeof(buffer), - "getEventTag name=%s format=\"(new|1)\"", name); - StartBenchmarkTiming(); - send_to_control(buffer, sizeof(buffer)); - StopBenchmarkTiming(); - } + struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 }; - // Restore copies (logd still know about them, until crash or reboot) - if (dev_event_log_tags.length() && - !android::base::WriteStringToFile(dev_event_log_tags, - dev_event_log_tags_path)) { - fprintf(stderr, "WARNING: " - "failed to restore %s\n", dev_event_log_tags_path); - } - if (data_event_log_tags.length() && - !android::base::WriteStringToFile(data_event_log_tags, - data_event_log_tags_path)) { - fprintf(stderr, "WARNING: " - "failed to restore %s\n", data_event_log_tags_path); + ret = poll(&p, 1, 20); + if ((ret <= 0) || !(p.revents & POLLIN)) { + break; } - fprintf(stderr, "WARNING: " - "Restarting logd to make it forget what we just did\n"); - system("stop logd ; start logd"); + } + close(sock); +} + +static void BM_lookupEventTagNum_logd_new(int iters) { + fprintf(stderr, + "WARNING: " + "This test can cause logd to grow in size and hit DOS limiter\n"); + // Make copies + static const char empty_event_log_tags[] = "# content owned by logd\n"; + static const char dev_event_log_tags_path[] = "/dev/event-log-tags"; + std::string dev_event_log_tags; + if (android::base::ReadFileToString(dev_event_log_tags_path, + &dev_event_log_tags) && + (dev_event_log_tags.length() == 0)) { + dev_event_log_tags = empty_event_log_tags; + } + static const char data_event_log_tags_path[] = + "/data/misc/logd/event-log-tags"; + std::string data_event_log_tags; + if (android::base::ReadFileToString(data_event_log_tags_path, + &data_event_log_tags) && + (data_event_log_tags.length() == 0)) { + data_event_log_tags = empty_event_log_tags; + } + + for (int i = 0; i < iters; ++i) { + char buffer[256]; + memset(buffer, 0, sizeof(buffer)); + log_time now(CLOCK_MONOTONIC); + char name[64]; + snprintf(name, sizeof(name), "a%" PRIu64, now.nsec()); + snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"", + name); + StartBenchmarkTiming(); + send_to_control(buffer, sizeof(buffer)); + StopBenchmarkTiming(); + } + + // Restore copies (logd still know about them, until crash or reboot) + if (dev_event_log_tags.length() && + !android::base::WriteStringToFile(dev_event_log_tags, + dev_event_log_tags_path)) { + fprintf(stderr, + "WARNING: " + "failed to restore %s\n", + dev_event_log_tags_path); + } + if (data_event_log_tags.length() && + !android::base::WriteStringToFile(data_event_log_tags, + data_event_log_tags_path)) { + fprintf(stderr, + "WARNING: " + "failed to restore %s\n", + data_event_log_tags_path); + } + fprintf(stderr, + "WARNING: " + "Restarting logd to make it forget what we just did\n"); + system("stop logd ; start logd"); } BENCHMARK(BM_lookupEventTagNum_logd_new); static void BM_lookupEventTagNum_logd_existing(int iters) { - prechargeEventMap(); - - std::unordered_set<uint32_t>::const_iterator it = set.begin(); - - for (int i = 0; i < iters; ++i) { - size_t len; - const char* name = android_lookupEventTag_len(map, &len, (*it)); - std::string Name(name, len); - const char* format = android_lookupEventFormat_len(map, &len, (*it)); - std::string Format(format, len); - - char buffer[256]; - snprintf(buffer, sizeof(buffer), - "getEventTag name=%s format=\"%s\"", - Name.c_str(), Format.c_str()); - - StartBenchmarkTiming(); - send_to_control(buffer, sizeof(buffer)); - StopBenchmarkTiming(); - ++it; - if (it == set.end()) it = set.begin(); - } + prechargeEventMap(); + + std::unordered_set<uint32_t>::const_iterator it = set.begin(); + + for (int i = 0; i < iters; ++i) { + size_t len; + const char* name = android_lookupEventTag_len(map, &len, (*it)); + std::string Name(name, len); + const char* format = android_lookupEventFormat_len(map, &len, (*it)); + std::string Format(format, len); + + char buffer[256]; + snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"%s\"", + Name.c_str(), Format.c_str()); + + StartBenchmarkTiming(); + send_to_control(buffer, sizeof(buffer)); + StopBenchmarkTiming(); + ++it; + if (it == set.end()) it = set.begin(); + } } BENCHMARK(BM_lookupEventTagNum_logd_existing); diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp index 2537fac23..cb8c7c64b 100644 --- a/liblog/tests/liblog_test.cpp +++ b/liblog/tests/liblog_test.cpp @@ -31,24 +31,25 @@ #include <android-base/file.h> #include <android-base/stringprintf.h> -#ifdef __ANDROID__ // includes sys/properties.h which does not exist outside +#ifdef __ANDROID__ // includes sys/properties.h which does not exist outside #include <cutils/properties.h> #endif #include <gtest/gtest.h> -#include <log/logprint.h> #include <log/log_event_list.h> #include <log/log_frontend.h> +#include <log/logprint.h> #include <private/android_filesystem_config.h> #include <private/android_logger.h> #ifndef TEST_PREFIX -#ifdef __ANDROID__ // make sure we always run code if compiled for android +#ifdef __ANDROID__ // make sure we always run code if compiled for android #define TEST_PREFIX #endif #endif -#if (!defined(USING_LOGGER_DEFAULT) || !defined(USING_LOGGER_LOCAL) || !defined(USING_LOGGER_STDERR)) -#ifdef liblog // a binary clue that we are overriding the test names +#if (!defined(USING_LOGGER_DEFAULT) || !defined(USING_LOGGER_LOCAL) || \ + !defined(USING_LOGGER_STDERR)) +#ifdef liblog // a binary clue that we are overriding the test names // Does not support log reading blocking feature yet // Does not support LOG_ID_SECURITY (unless we set LOGGER_LOCAL | LOGGER_LOGD) // Assume some common aspects are tested by USING_LOGGER_DEFAULT: @@ -63,109 +64,104 @@ #endif #endif #ifdef USING_LOGGER_STDERR -# define SUPPORTS_END_TO_END 0 +#define SUPPORTS_END_TO_END 0 #else -# define SUPPORTS_END_TO_END 1 +#define SUPPORTS_END_TO_END 1 #endif // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and // non-syscall libs. Since we are only using this in the emergency of // a signal to stuff a terminating code into the logs, we will spin rather // than try a usleep. -#define LOG_FAILURE_RETRY(exp) ({ \ - typeof (exp) _rc; \ - do { \ - _rc = (exp); \ - } while (((_rc == -1) \ - && ((errno == EINTR) \ - || (errno == EAGAIN))) \ - || (_rc == -EINTR) \ - || (_rc == -EAGAIN)); \ - _rc; }) +#define LOG_FAILURE_RETRY(exp) \ + ({ \ + typeof(exp) _rc; \ + do { \ + _rc = (exp); \ + } while (((_rc == -1) && ((errno == EINTR) || (errno == EAGAIN))) || \ + (_rc == -EINTR) || (_rc == -EAGAIN)); \ + _rc; \ + }) TEST(liblog, __android_log_btwrite) { #ifdef TEST_PREFIX - TEST_PREFIX + TEST_PREFIX #endif - int intBuf = 0xDEADBEEF; - EXPECT_LT(0, __android_log_btwrite(0, - EVENT_TYPE_INT, - &intBuf, sizeof(intBuf))); - long long longBuf = 0xDEADBEEFA55A5AA5; - EXPECT_LT(0, __android_log_btwrite(0, - EVENT_TYPE_LONG, - &longBuf, sizeof(longBuf))); - usleep(1000); - char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5"; - EXPECT_LT(0, __android_log_btwrite(0, - EVENT_TYPE_STRING, - Buf, sizeof(Buf) - 1)); - usleep(1000); + int intBuf = 0xDEADBEEF; + EXPECT_LT(0, + __android_log_btwrite(0, EVENT_TYPE_INT, &intBuf, sizeof(intBuf))); + long long longBuf = 0xDEADBEEFA55A5AA5; + EXPECT_LT( + 0, __android_log_btwrite(0, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf))); + usleep(1000); + char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5"; + EXPECT_LT(0, + __android_log_btwrite(0, EVENT_TYPE_STRING, Buf, sizeof(Buf) - 1)); + usleep(1000); } #if (defined(__ANDROID__) && defined(USING_LOGGER_DEFAULT)) static std::string popenToString(std::string command) { - std::string ret; + std::string ret; - FILE* fp = popen(command.c_str(), "r"); - if (fp) { - if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = ""; - pclose(fp); - } - return ret; + FILE* fp = popen(command.c_str(), "r"); + if (fp) { + if (!android::base::ReadFdToString(fileno(fp), &ret)) ret = ""; + pclose(fp); + } + return ret; } static bool isPmsgActive() { - pid_t pid = getpid(); + pid_t pid = getpid(); - std::string myPidFds = popenToString(android::base::StringPrintf( - "ls -l /proc/%d/fd", pid)); - if (myPidFds.length() == 0) return true; // guess it is? + std::string myPidFds = + popenToString(android::base::StringPrintf("ls -l /proc/%d/fd", pid)); + if (myPidFds.length() == 0) return true; // guess it is? - return std::string::npos != myPidFds.find(" -> /dev/pmsg0"); + return std::string::npos != myPidFds.find(" -> /dev/pmsg0"); } static bool isLogdwActive() { - std::string logdwSignature = popenToString( - "grep /dev/socket/logdw /proc/net/unix"); - size_t beginning = logdwSignature.find(" "); - if (beginning == std::string::npos) return true; - beginning = logdwSignature.find(" ", beginning + 1); - if (beginning == std::string::npos) return true; - size_t end = logdwSignature.find(" ", beginning + 1); - if (end == std::string::npos) return true; - end = logdwSignature.find(" ", end + 1); - if (end == std::string::npos) return true; - end = logdwSignature.find(" ", end + 1); - if (end == std::string::npos) return true; - end = logdwSignature.find(" ", end + 1); - if (end == std::string::npos) return true; - std::string allLogdwEndpoints = popenToString( - "grep ' 00000002" + - logdwSignature.substr(beginning, end - beginning) + - " ' /proc/net/unix | " + - "sed -n 's/.* \\([0-9][0-9]*\\)$/ -> socket:[\\1]/p'"); - if (allLogdwEndpoints.length() == 0) return true; - - // NB: allLogdwEndpoints has some false positives in it, but those - // strangers do not overlap with the simplistic activities inside this - // test suite. - - pid_t pid = getpid(); - - std::string myPidFds = popenToString(android::base::StringPrintf( - "ls -l /proc/%d/fd", pid)); - if (myPidFds.length() == 0) return true; - - // NB: fgrep with multiple strings is broken in Android - for (beginning = 0; - (end = allLogdwEndpoints.find("\n", beginning)) != std::string::npos; - beginning = end + 1) { - if (myPidFds.find(allLogdwEndpoints.substr(beginning, - end - beginning)) != - std::string::npos) return true; - } - return false; + std::string logdwSignature = + popenToString("grep /dev/socket/logdw /proc/net/unix"); + size_t beginning = logdwSignature.find(" "); + if (beginning == std::string::npos) return true; + beginning = logdwSignature.find(" ", beginning + 1); + if (beginning == std::string::npos) return true; + size_t end = logdwSignature.find(" ", beginning + 1); + if (end == std::string::npos) return true; + end = logdwSignature.find(" ", end + 1); + if (end == std::string::npos) return true; + end = logdwSignature.find(" ", end + 1); + if (end == std::string::npos) return true; + end = logdwSignature.find(" ", end + 1); + if (end == std::string::npos) return true; + std::string allLogdwEndpoints = popenToString( + "grep ' 00000002" + logdwSignature.substr(beginning, end - beginning) + + " ' /proc/net/unix | " + + "sed -n 's/.* \\([0-9][0-9]*\\)$/ -> socket:[\\1]/p'"); + if (allLogdwEndpoints.length() == 0) return true; + + // NB: allLogdwEndpoints has some false positives in it, but those + // strangers do not overlap with the simplistic activities inside this + // test suite. + + pid_t pid = getpid(); + + std::string myPidFds = + popenToString(android::base::StringPrintf("ls -l /proc/%d/fd", pid)); + if (myPidFds.length() == 0) return true; + + // NB: fgrep with multiple strings is broken in Android + for (beginning = 0; + (end = allLogdwEndpoints.find("\n", beginning)) != std::string::npos; + beginning = end + 1) { + if (myPidFds.find(allLogdwEndpoints.substr(beginning, end - beginning)) != + std::string::npos) + return true; + } + return false; } static bool tested__android_log_close; @@ -173,134 +169,136 @@ static bool tested__android_log_close; TEST(liblog, __android_log_btwrite__android_logger_list_read) { #if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL)) - struct logger_list *logger_list; + struct logger_list* logger_list; - pid_t pid = getpid(); + pid_t pid = getpid(); - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); - log_time ts(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); + log_time ts(CLOCK_MONOTONIC); + EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); #ifdef USING_LOGGER_DEFAULT - // Check that we can close and reopen the logger - bool pmsgActiveAfter__android_log_btwrite; - bool logdwActiveAfter__android_log_btwrite; - if (getuid() == AID_ROOT) { - tested__android_log_close = true; - pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - logdwActiveAfter__android_log_btwrite = isLogdwActive(); - EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); - EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); - } else if (!tested__android_log_close) { - fprintf(stderr, "WARNING: can not test __android_log_close()\n"); - } - __android_log_close(); - if (getuid() == AID_ROOT) { - bool pmsgActiveAfter__android_log_close = isPmsgActive(); - bool logdwActiveAfter__android_log_close = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_close); - EXPECT_FALSE(logdwActiveAfter__android_log_close); - } + // Check that we can close and reopen the logger + bool pmsgActiveAfter__android_log_btwrite; + bool logdwActiveAfter__android_log_btwrite; + if (getuid() == AID_ROOT) { + tested__android_log_close = true; + pmsgActiveAfter__android_log_btwrite = isPmsgActive(); + logdwActiveAfter__android_log_btwrite = isLogdwActive(); + EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); + EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); + } else if (!tested__android_log_close) { + fprintf(stderr, "WARNING: can not test __android_log_close()\n"); + } + __android_log_close(); + if (getuid() == AID_ROOT) { + bool pmsgActiveAfter__android_log_close = isPmsgActive(); + bool logdwActiveAfter__android_log_close = isLogdwActive(); + EXPECT_FALSE(pmsgActiveAfter__android_log_close); + EXPECT_FALSE(logdwActiveAfter__android_log_close); + } #endif - log_time ts1(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); + log_time ts1(CLOCK_MONOTONIC); + EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1))); #ifdef USING_LOGGER_DEFAULT - if (getuid() == AID_ROOT) { - pmsgActiveAfter__android_log_btwrite = isPmsgActive(); - logdwActiveAfter__android_log_btwrite = isLogdwActive(); - EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); - EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); - } + if (getuid() == AID_ROOT) { + pmsgActiveAfter__android_log_btwrite = isPmsgActive(); + logdwActiveAfter__android_log_btwrite = isLogdwActive(); + EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite); + EXPECT_TRUE(logdwActiveAfter__android_log_btwrite); + } #endif - usleep(1000000); + usleep(1000000); - int count = 0; - int second_count = 0; + int count = 0; + int second_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); + EXPECT_EQ(log_msg.entry.pid, pid); - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } + if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; + } - android_log_event_long_t* eventData; - eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); + android_log_event_long_t* eventData; + eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } + if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { + continue; + } - log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); - if (ts == tx) { - ++count; - } else if (ts1 == tx) { - ++second_count; - } + log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); + if (ts == tx) { + ++count; + } else if (ts1 == tx) { + ++second_count; } + } - EXPECT_EQ(SUPPORTS_END_TO_END, count); - EXPECT_EQ(SUPPORTS_END_TO_END, second_count); + EXPECT_EQ(SUPPORTS_END_TO_END, count); + EXPECT_EQ(SUPPORTS_END_TO_END, second_count); - 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 } #if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL)) static void print_frontend(const char* prefix, int logger) { - static const char orstr[] = " | "; - - if (!prefix) { - prefix = ""; - } - if (logger < 0) { - fprintf(stderr, "%s%s\n", prefix, strerror(-logger)); - return; - } - - if (logger == LOGGER_DEFAULT) { - fprintf(stderr, "%sLOGGER_DEFAULT", prefix); - prefix = orstr; - } - if (logger & LOGGER_LOGD) { - fprintf(stderr, "%sLOGGER_LOGD", prefix); - prefix = orstr; - } - if (logger & LOGGER_KERNEL) { - fprintf(stderr, "%sLOGGER_KERNEL", prefix); - prefix = orstr; - } - if (logger & LOGGER_NULL) { - fprintf(stderr, "%sLOGGER_NULL", prefix); - prefix = orstr; - } - if (logger & LOGGER_LOCAL) { - fprintf(stderr, "%sLOGGER_LOCAL", prefix); - prefix = orstr; - } - if (logger & LOGGER_STDERR) { - fprintf(stderr, "%sLOGGER_STDERR", prefix); - prefix = orstr; - } - logger &= ~(LOGGER_LOGD | LOGGER_KERNEL | LOGGER_NULL | LOGGER_LOCAL | - LOGGER_STDERR); - if (logger) { - fprintf(stderr, "%s0x%x", prefix, logger); - prefix = orstr; - } - if (prefix == orstr) { - fprintf(stderr, "\n"); - } + static const char orstr[] = " | "; + + if (!prefix) { + prefix = ""; + } + if (logger < 0) { + fprintf(stderr, "%s%s\n", prefix, strerror(-logger)); + return; + } + + if (logger == LOGGER_DEFAULT) { + fprintf(stderr, "%sLOGGER_DEFAULT", prefix); + prefix = orstr; + } + if (logger & LOGGER_LOGD) { + fprintf(stderr, "%sLOGGER_LOGD", prefix); + prefix = orstr; + } + if (logger & LOGGER_KERNEL) { + fprintf(stderr, "%sLOGGER_KERNEL", prefix); + prefix = orstr; + } + if (logger & LOGGER_NULL) { + fprintf(stderr, "%sLOGGER_NULL", prefix); + prefix = orstr; + } + if (logger & LOGGER_LOCAL) { + fprintf(stderr, "%sLOGGER_LOCAL", prefix); + prefix = orstr; + } + if (logger & LOGGER_STDERR) { + fprintf(stderr, "%sLOGGER_STDERR", prefix); + prefix = orstr; + } + logger &= ~(LOGGER_LOGD | LOGGER_KERNEL | LOGGER_NULL | LOGGER_LOCAL | + LOGGER_STDERR); + if (logger) { + fprintf(stderr, "%s0x%x", prefix, logger); + prefix = orstr; + } + if (prefix == orstr) { + fprintf(stderr, "\n"); + } } #endif @@ -310,311 +308,316 @@ static void print_frontend(const char* prefix, int logger) { TEST(liblog, android_set_log_frontend) { #if (defined(__ANDROID__) || defined(USING_LOGGER_LOCAL)) #ifdef TEST_PREFIX - TEST_PREFIX + TEST_PREFIX #endif - int logger = android_get_log_frontend(); - print_frontend("android_get_log_frontend = ", logger); - EXPECT_NE(LOGGER_NULL, logger); + int logger = android_get_log_frontend(); + print_frontend("android_get_log_frontend = ", logger); + EXPECT_NE(LOGGER_NULL, logger); - int ret; - EXPECT_EQ(LOGGER_NULL, ret = android_set_log_frontend(LOGGER_NULL)); - print_frontend("android_set_log_frontend = ", ret); - EXPECT_EQ(LOGGER_NULL, ret = android_get_log_frontend()); - print_frontend("android_get_log_frontend = ", ret); + int ret; + EXPECT_EQ(LOGGER_NULL, ret = android_set_log_frontend(LOGGER_NULL)); + print_frontend("android_set_log_frontend = ", ret); + EXPECT_EQ(LOGGER_NULL, ret = android_get_log_frontend()); + print_frontend("android_get_log_frontend = ", ret); - pid_t pid = getpid(); + pid_t pid = getpid(); - struct logger_list *logger_list; - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + struct logger_list* logger_list; + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); - log_time ts(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); + log_time ts(CLOCK_MONOTONIC); + EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - usleep(1000000); + usleep(1000000); - 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); + EXPECT_EQ(log_msg.entry.pid, pid); - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } + if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; + } - android_log_event_long_t* eventData; - eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); + android_log_event_long_t* eventData; + eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } + if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { + continue; + } - log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); - if (ts == tx) { - ++count; - } + log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); + if (ts == tx) { + ++count; } + } - android_logger_list_close(logger_list); + android_logger_list_close(logger_list); + + EXPECT_EQ(logger, ret = android_set_log_frontend(logger)); + print_frontend("android_set_log_frontend = ", ret); + EXPECT_EQ(logger, ret = android_get_log_frontend()); + print_frontend("android_get_log_frontend = ", ret); - EXPECT_EQ(logger, ret = android_set_log_frontend(logger)); - print_frontend("android_set_log_frontend = ", ret); - EXPECT_EQ(logger, ret = android_get_log_frontend()); - print_frontend("android_get_log_frontend = ", ret); - - // False negative if liblog.__android_log_btwrite__android_logger_list_read - // fails above, so we will likely succeed. But we will have so many - // failures elsewhere that it is probably not worthwhile for us to - // highlight yet another disappointment. - EXPECT_EQ(0, count); - // We also expect failures in the following tests if the set does not - // react in an appropriate manner internally, yet passes, so we depend - // on this test being in the middle of a series of tests performed in - // the same process. + // False negative if liblog.__android_log_btwrite__android_logger_list_read + // fails above, so we will likely succeed. But we will have so many + // failures elsewhere that it is probably not worthwhile for us to + // highlight yet another disappointment. + // + // We also expect failures in the following tests if the set does not + // react in an appropriate manner internally, yet passes, so we depend + // on this test being in the middle of a series of tests performed in + // the same process. + EXPECT_EQ(0, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } #ifdef TEST_PREFIX static inline uint32_t get4LE(const uint8_t* src) { - return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); } static inline uint32_t get4LE(const char* src) { - return get4LE(reinterpret_cast<const uint8_t*>(src)); + return get4LE(reinterpret_cast<const uint8_t*>(src)); } #endif -static void bswrite_test(const char *message) { +static void bswrite_test(const char* message) { #ifdef TEST_PREFIX - TEST_PREFIX - struct logger_list *logger_list; + TEST_PREFIX + struct logger_list* logger_list; - pid_t pid = getpid(); + pid_t pid = getpid(); - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); #ifdef __ANDROID__ - log_time ts(android_log_clockid()); + log_time ts(android_log_clockid()); #else - log_time ts(CLOCK_REALTIME); + log_time ts(CLOCK_REALTIME); #endif - EXPECT_LT(0, __android_log_bswrite(0, message)); - size_t num_lines = 1, size = 0, length = 0, total = 0; - const char *cp = message; - while (*cp) { - if (*cp == '\n') { - if (cp[1]) { - ++num_lines; - } + EXPECT_LT(0, __android_log_bswrite(0, message)); + size_t num_lines = 1, size = 0, length = 0, total = 0; + const char* cp = message; + while (*cp) { + if (*cp == '\n') { + if (cp[1]) { + ++num_lines; + } + } else { + ++size; + } + ++cp; + ++total; + ++length; + if ((LOGGER_ENTRY_MAX_PAYLOAD - 4 - 1 - 4) <= length) { + break; + } + } + while (*cp) { + ++cp; + ++total; + } + usleep(1000000); + + int count = 0; + + for (;;) { + log_msg log_msg; + if (android_logger_list_read(logger_list, &log_msg) <= 0) { + break; + } + + EXPECT_EQ(log_msg.entry.pid, pid); + + if ((log_msg.entry.sec < (ts.tv_sec - 1)) || + ((ts.tv_sec + 1) < log_msg.entry.sec) || + ((size_t)log_msg.entry.len != + (sizeof(android_log_event_string_t) + length)) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; + } + + android_log_event_string_t* eventData; + eventData = reinterpret_cast<android_log_event_string_t*>(log_msg.msg()); + + if (!eventData || (eventData->type != EVENT_TYPE_STRING)) { + continue; + } + + size_t len = get4LE(reinterpret_cast<char*>(&eventData->length)); + if (len == total) { + ++count; + + AndroidLogFormat* logformat = android_log_format_new(); + EXPECT_TRUE(NULL != logformat); + AndroidLogEntry entry; + char msgBuf[1024]; + if (length != total) { + fprintf(stderr, "Expect \"Binary log entry conversion failed\"\n"); + } + int processBinaryLogBuffer = android_log_processBinaryLogBuffer( + &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf)); + EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer); + if ((processBinaryLogBuffer == 0) || entry.message) { + size_t line_overhead = 20; + if (pid > 99999) ++line_overhead; + if (pid > 999999) ++line_overhead; + fflush(stderr); + if (processBinaryLogBuffer) { + EXPECT_GT((int)((line_overhead * num_lines) + size), + android_log_printLogLine(logformat, fileno(stderr), &entry)); } else { - ++size; - } - ++cp; - ++total; - ++length; - if ((LOGGER_ENTRY_MAX_PAYLOAD - 4 - 1 - 4) <= length) { - break; + EXPECT_EQ((int)((line_overhead * num_lines) + size), + android_log_printLogLine(logformat, fileno(stderr), &entry)); } + } + android_log_format_free(logformat); } - while (*cp) { - ++cp; - ++total; - } - usleep(1000000); - - int count = 0; - - for (;;) { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) { - break; - } - - EXPECT_EQ(log_msg.entry.pid, pid); - - if ((log_msg.entry.sec < (ts.tv_sec - 1)) - || ((ts.tv_sec + 1) < log_msg.entry.sec) - || ((size_t)log_msg.entry.len != (sizeof(android_log_event_string_t) + - length)) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } - - android_log_event_string_t* eventData; - eventData = reinterpret_cast<android_log_event_string_t*>(log_msg.msg()); - - if (!eventData || (eventData->type != EVENT_TYPE_STRING)) { - continue; - } + } - size_t len = get4LE(reinterpret_cast<char*>(&eventData->length)); - if (len == total) { - ++count; + EXPECT_EQ(SUPPORTS_END_TO_END, count); - AndroidLogFormat *logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - char msgBuf[1024]; - if (length != total) { - fprintf(stderr, "Expect \"Binary log entry conversion failed\"\n"); - } - int processBinaryLogBuffer = android_log_processBinaryLogBuffer( - &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf)); - EXPECT_EQ((length == total) ? 0 : -1, processBinaryLogBuffer); - if ((processBinaryLogBuffer == 0) || entry.message) { - size_t line_overhead = 20; - if (pid > 99999) ++line_overhead; - if (pid > 999999) ++line_overhead; - fflush(stderr); - if (processBinaryLogBuffer) { - EXPECT_GT((int)((line_overhead * num_lines) + size), - android_log_printLogLine(logformat, - fileno(stderr), &entry)); - } else { - EXPECT_EQ((int)((line_overhead * num_lines) + size), - android_log_printLogLine(logformat, - fileno(stderr), &entry)); - } - } - android_log_format_free(logformat); - } - } - - EXPECT_EQ(SUPPORTS_END_TO_END, count); - - android_logger_list_close(logger_list); + android_logger_list_close(logger_list); #else - message = NULL; - GTEST_LOG_(INFO) << "This test does nothing.\n"; + message = NULL; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, __android_log_bswrite_and_print) { - bswrite_test("Hello World"); + bswrite_test("Hello World"); } TEST(liblog, __android_log_bswrite_and_print__empty_string) { - bswrite_test(""); + bswrite_test(""); } TEST(liblog, __android_log_bswrite_and_print__newline_prefix) { - bswrite_test("\nHello World\n"); + bswrite_test("\nHello World\n"); } TEST(liblog, __android_log_bswrite_and_print__newline_space_prefix) { - bswrite_test("\n Hello World \n"); + bswrite_test("\n Hello World \n"); } TEST(liblog, __android_log_bswrite_and_print__multiple_newline) { - bswrite_test("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten"); + bswrite_test("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten"); } -static void buf_write_test(const char *message) { +static void buf_write_test(const char* message) { #ifdef TEST_PREFIX - TEST_PREFIX - struct logger_list *logger_list; + TEST_PREFIX + struct logger_list* logger_list; - pid_t pid = getpid(); + pid_t pid = getpid(); - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + ASSERT_TRUE( + NULL != + (logger_list = android_logger_list_open( + LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); - static const char tag[] = "TEST__android_log_buf_write"; + static const char tag[] = "TEST__android_log_buf_write"; #ifdef __ANDROID__ - log_time ts(android_log_clockid()); + log_time ts(android_log_clockid()); #else - log_time ts(CLOCK_REALTIME); + log_time ts(CLOCK_REALTIME); #endif - EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, - tag, message)); - size_t num_lines = 1, size = 0, length = 0; - const char *cp = message; - while (*cp) { - if (*cp == '\n') { - if (cp[1]) { - ++num_lines; - } - } else { - ++size; - } - ++length; - if ((LOGGER_ENTRY_MAX_PAYLOAD - 2 - sizeof(tag)) <= length) { - break; - } - ++cp; + EXPECT_LT( + 0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, tag, message)); + size_t num_lines = 1, size = 0, length = 0; + const char* cp = message; + while (*cp) { + if (*cp == '\n') { + if (cp[1]) { + ++num_lines; + } + } else { + ++size; } - usleep(1000000); + ++length; + if ((LOGGER_ENTRY_MAX_PAYLOAD - 2 - sizeof(tag)) <= length) { + break; + } + ++cp; + } + usleep(1000000); - 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; + } - ASSERT_EQ(log_msg.entry.pid, pid); + ASSERT_EQ(log_msg.entry.pid, pid); - if ((log_msg.entry.sec < (ts.tv_sec - 1)) - || ((ts.tv_sec + 1) < log_msg.entry.sec) - || ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2)) - || (log_msg.id() != LOG_ID_MAIN)) { - continue; - } + if ((log_msg.entry.sec < (ts.tv_sec - 1)) || + ((ts.tv_sec + 1) < log_msg.entry.sec) || + ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2)) || + (log_msg.id() != LOG_ID_MAIN)) { + continue; + } + + ++count; - ++count; - - AndroidLogFormat *logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1, - &entry); - EXPECT_EQ(0, processLogBuffer); - if (processLogBuffer == 0) { - size_t line_overhead = 11; - if (pid > 99999) ++line_overhead; - if (pid > 999999) ++line_overhead; - fflush(stderr); - EXPECT_EQ((int)(((line_overhead + sizeof(tag)) * num_lines) + size), + AndroidLogFormat* logformat = android_log_format_new(); + EXPECT_TRUE(NULL != logformat); + AndroidLogEntry entry; + int processLogBuffer = + android_log_processLogBuffer(&log_msg.entry_v1, &entry); + EXPECT_EQ(0, processLogBuffer); + if (processLogBuffer == 0) { + size_t line_overhead = 11; + if (pid > 99999) ++line_overhead; + if (pid > 999999) ++line_overhead; + fflush(stderr); + EXPECT_EQ((int)(((line_overhead + sizeof(tag)) * num_lines) + size), android_log_printLogLine(logformat, fileno(stderr), &entry)); - } - android_log_format_free(logformat); } + android_log_format_free(logformat); + } - EXPECT_EQ(SUPPORTS_END_TO_END, count); + EXPECT_EQ(SUPPORTS_END_TO_END, count); - android_logger_list_close(logger_list); + android_logger_list_close(logger_list); #else - message = NULL; - GTEST_LOG_(INFO) << "This test does nothing.\n"; + message = NULL; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, __android_log_buf_write_and_print__empty) { - buf_write_test(""); + buf_write_test(""); } TEST(liblog, __android_log_buf_write_and_print__newline_prefix) { - buf_write_test("\nHello World\n"); + buf_write_test("\nHello World\n"); } TEST(liblog, __android_log_buf_write_and_print__newline_space_prefix) { - buf_write_test("\n Hello World \n"); + buf_write_test("\n Hello World \n"); } -#ifndef USING_LOGGER_LOCAL // requires blocking reader functionality +#ifndef USING_LOGGER_LOCAL // requires blocking reader functionality #ifdef TEST_PREFIX static unsigned signaled; static log_time signal_time; @@ -625,148 +628,147 @@ static log_time signal_time; * should catch any regressions in that effort. The odds of a logged message * in a signal handler causing a lockup problem should be _very_ small. */ -static void caught_blocking_signal(int /*signum*/) -{ - unsigned long long v = 0xDEADBEEFA55A0000ULL; +static void caught_blocking_signal(int /*signum*/) { + unsigned long long v = 0xDEADBEEFA55A0000ULL; - v += getpid() & 0xFFFF; + v += getpid() & 0xFFFF; - ++signaled; - if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) { - signal_time = log_time(CLOCK_MONOTONIC); - signal_time.tv_sec += 2; - } + ++signaled; + if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) { + signal_time = log_time(CLOCK_MONOTONIC); + signal_time.tv_sec += 2; + } - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); + LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); } // Fill in current process user and system time in 10ms increments -static void get_ticks(unsigned long long *uticks, unsigned long long *sticks) -{ +static void get_ticks(unsigned long long* uticks, unsigned long long* sticks) { + *uticks = *sticks = 0; + + pid_t pid = getpid(); + + char buffer[512]; + snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid); + + FILE* fp = fopen(buffer, "r"); + if (!fp) { + return; + } + + char* cp = fgets(buffer, sizeof(buffer), fp); + fclose(fp); + if (!cp) { + return; + } + + pid_t d; + char s[sizeof(buffer)]; + char c; + long long ll; + unsigned long long ull; + + if (15 != sscanf(buffer, + "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu " + "%llu %llu ", + &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, + &ull, uticks, sticks)) { *uticks = *sticks = 0; - - pid_t pid = getpid(); - - char buffer[512]; - snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid); - - FILE *fp = fopen(buffer, "r"); - if (!fp) { - return; - } - - char *cp = fgets(buffer, sizeof(buffer), fp); - fclose(fp); - if (!cp) { - return; - } - - pid_t d; - char s[sizeof(buffer)]; - char c; - long long ll; - unsigned long long ull; - - if (15 != sscanf(buffer, - "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu %llu %llu ", - &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, &ull, - uticks, sticks)) { - *uticks = *sticks = 0; - } + } } #endif TEST(liblog, android_logger_list_read__cpu_signal) { #ifdef TEST_PREFIX - TEST_PREFIX - struct logger_list *logger_list; - unsigned long long v = 0xDEADBEEFA55A0000ULL; + TEST_PREFIX + struct logger_list* logger_list; + unsigned long long v = 0xDEADBEEFA55A0000ULL; - pid_t pid = getpid(); + pid_t pid = getpid(); - v += pid & 0xFFFF; + v += pid & 0xFFFF; - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid))); + ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid))); - int count = 0; + int count = 0; - int signals = 0; + int signals = 0; - unsigned long long uticks_start; - unsigned long long sticks_start; - get_ticks(&uticks_start, &sticks_start); + unsigned long long uticks_start; + unsigned long long sticks_start; + get_ticks(&uticks_start, &sticks_start); - const unsigned alarm_time = 10; + const unsigned alarm_time = 10; - memset(&signal_time, 0, sizeof(signal_time)); + memset(&signal_time, 0, sizeof(signal_time)); - signal(SIGALRM, caught_blocking_signal); - alarm(alarm_time); + signal(SIGALRM, caught_blocking_signal); + alarm(alarm_time); - signaled = 0; + signaled = 0; - do { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) { - break; - } + do { + log_msg log_msg; + if (android_logger_list_read(logger_list, &log_msg) <= 0) { + break; + } - alarm(alarm_time); + alarm(alarm_time); - ++count; + ++count; - ASSERT_EQ(log_msg.entry.pid, pid); + ASSERT_EQ(log_msg.entry.pid, pid); - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } + if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; + } - android_log_event_long_t* eventData; - eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); + android_log_event_long_t* eventData; + eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } + if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { + continue; + } - char* cp = reinterpret_cast<char*>(&eventData->payload.data); - unsigned long long l = cp[0] & 0xFF; - l |= (unsigned long long) (cp[1] & 0xFF) << 8; - l |= (unsigned long long) (cp[2] & 0xFF) << 16; - l |= (unsigned long long) (cp[3] & 0xFF) << 24; - l |= (unsigned long long) (cp[4] & 0xFF) << 32; - l |= (unsigned long long) (cp[5] & 0xFF) << 40; - l |= (unsigned long long) (cp[6] & 0xFF) << 48; - l |= (unsigned long long) (cp[7] & 0xFF) << 56; - - if (l == v) { - ++signals; - break; - } - } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time)); - alarm(0); - signal(SIGALRM, SIG_DFL); + char* cp = reinterpret_cast<char*>(&eventData->payload.data); + unsigned long long l = cp[0] & 0xFF; + l |= (unsigned long long)(cp[1] & 0xFF) << 8; + l |= (unsigned long long)(cp[2] & 0xFF) << 16; + l |= (unsigned long long)(cp[3] & 0xFF) << 24; + l |= (unsigned long long)(cp[4] & 0xFF) << 32; + l |= (unsigned long long)(cp[5] & 0xFF) << 40; + l |= (unsigned long long)(cp[6] & 0xFF) << 48; + l |= (unsigned long long)(cp[7] & 0xFF) << 56; - EXPECT_LE(1, count); + if (l == v) { + ++signals; + break; + } + } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time)); + alarm(0); + signal(SIGALRM, SIG_DFL); - EXPECT_EQ(1, signals); + EXPECT_LE(1, count); - android_logger_list_close(logger_list); + EXPECT_EQ(1, signals); + + android_logger_list_close(logger_list); - unsigned long long uticks_end; - unsigned long long sticks_end; - get_ticks(&uticks_end, &sticks_end); - - // Less than 1% in either user or system time, or both - const unsigned long long one_percent_ticks = alarm_time; - unsigned long long user_ticks = uticks_end - uticks_start; - unsigned long long system_ticks = sticks_end - sticks_start; - EXPECT_GT(one_percent_ticks, user_ticks); - EXPECT_GT(one_percent_ticks, system_ticks); - EXPECT_GT(one_percent_ticks, user_ticks + system_ticks); + unsigned long long uticks_end; + unsigned long long sticks_end; + get_ticks(&uticks_end, &sticks_end); + + // Less than 1% in either user or system time, or both + const unsigned long long one_percent_ticks = alarm_time; + unsigned long long user_ticks = uticks_end - uticks_start; + unsigned long long system_ticks = sticks_end - sticks_start; + EXPECT_GT(one_percent_ticks, user_ticks); + EXPECT_GT(one_percent_ticks, system_ticks); + EXPECT_GT(one_percent_ticks, user_ticks + system_ticks); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } @@ -778,165 +780,164 @@ TEST(liblog, android_logger_list_read__cpu_signal) { */ static sem_t thread_trigger; -static void caught_blocking_thread(int /*signum*/) -{ - sem_post(&thread_trigger); +static void caught_blocking_thread(int /*signum*/) { + sem_post(&thread_trigger); } -static void *running_thread(void *) { - unsigned long long v = 0xDEADBEAFA55A0000ULL; +static void* running_thread(void*) { + unsigned long long v = 0xDEADBEAFA55A0000ULL; - v += getpid() & 0xFFFF; + v += getpid() & 0xFFFF; - struct timespec timeout; - clock_gettime(CLOCK_REALTIME, &timeout); - timeout.tv_sec += 55; - sem_timedwait(&thread_trigger, &timeout); + struct timespec timeout; + clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_sec += 55; + sem_timedwait(&thread_trigger, &timeout); - ++signaled; - if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) { - signal_time = log_time(CLOCK_MONOTONIC); - signal_time.tv_sec += 2; - } + ++signaled; + if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) { + signal_time = log_time(CLOCK_MONOTONIC); + signal_time.tv_sec += 2; + } - LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); + LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v))); - return NULL; + return NULL; } -static int start_thread() -{ - sem_init(&thread_trigger, 0, 0); +static int start_thread() { + sem_init(&thread_trigger, 0, 0); - pthread_attr_t attr; - if (pthread_attr_init(&attr)) { - return -1; - } - - struct sched_param param; + pthread_attr_t attr; + if (pthread_attr_init(&attr)) { + return -1; + } - memset(¶m, 0, sizeof(param)); - pthread_attr_setschedparam(&attr, ¶m); - pthread_attr_setschedpolicy(&attr, SCHED_BATCH); + struct sched_param param; - if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { - pthread_attr_destroy(&attr); - return -1; - } + memset(¶m, 0, sizeof(param)); + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setschedpolicy(&attr, SCHED_BATCH); - pthread_t thread; - if (pthread_create(&thread, &attr, running_thread, NULL)) { - pthread_attr_destroy(&attr); - return -1; - } + if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) { + pthread_attr_destroy(&attr); + return -1; + } + pthread_t thread; + if (pthread_create(&thread, &attr, running_thread, NULL)) { pthread_attr_destroy(&attr); - return 0; + return -1; + } + + pthread_attr_destroy(&attr); + return 0; } #endif TEST(liblog, android_logger_list_read__cpu_thread) { #ifdef TEST_PREFIX - TEST_PREFIX - struct logger_list *logger_list; - unsigned long long v = 0xDEADBEAFA55A0000ULL; + TEST_PREFIX + struct logger_list* logger_list; + unsigned long long v = 0xDEADBEAFA55A0000ULL; - pid_t pid = getpid(); + pid_t pid = getpid(); - v += pid & 0xFFFF; + v += pid & 0xFFFF; - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid))); + ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid))); - int count = 0; + int count = 0; - int signals = 0; + int signals = 0; - unsigned long long uticks_start; - unsigned long long sticks_start; - get_ticks(&uticks_start, &sticks_start); + unsigned long long uticks_start; + unsigned long long sticks_start; + get_ticks(&uticks_start, &sticks_start); - const unsigned alarm_time = 10; + const unsigned alarm_time = 10; - memset(&signal_time, 0, sizeof(signal_time)); + memset(&signal_time, 0, sizeof(signal_time)); - signaled = 0; - EXPECT_EQ(0, start_thread()); + signaled = 0; + EXPECT_EQ(0, start_thread()); + + signal(SIGALRM, caught_blocking_thread); + alarm(alarm_time); + + do { + log_msg log_msg; + if (LOG_FAILURE_RETRY(android_logger_list_read(logger_list, &log_msg)) <= 0) { + break; + } - signal(SIGALRM, caught_blocking_thread); alarm(alarm_time); - do { - log_msg log_msg; - if (LOG_FAILURE_RETRY(android_logger_list_read(logger_list, &log_msg)) <= 0) { - break; - } + ++count; - alarm(alarm_time); + ASSERT_EQ(log_msg.entry.pid, pid); - ++count; + if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; + } - ASSERT_EQ(log_msg.entry.pid, pid); + android_log_event_long_t* eventData; + eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } + if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { + continue; + } - android_log_event_long_t* eventData; - eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); + char* cp = reinterpret_cast<char*>(&eventData->payload.data); + unsigned long long l = cp[0] & 0xFF; + l |= (unsigned long long)(cp[1] & 0xFF) << 8; + l |= (unsigned long long)(cp[2] & 0xFF) << 16; + l |= (unsigned long long)(cp[3] & 0xFF) << 24; + l |= (unsigned long long)(cp[4] & 0xFF) << 32; + l |= (unsigned long long)(cp[5] & 0xFF) << 40; + l |= (unsigned long long)(cp[6] & 0xFF) << 48; + l |= (unsigned long long)(cp[7] & 0xFF) << 56; - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } + if (l == v) { + ++signals; + break; + } + } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time)); + alarm(0); + signal(SIGALRM, SIG_DFL); - char* cp = reinterpret_cast<char*>(&eventData->payload.data); - unsigned long long l = cp[0] & 0xFF; - l |= (unsigned long long) (cp[1] & 0xFF) << 8; - l |= (unsigned long long) (cp[2] & 0xFF) << 16; - l |= (unsigned long long) (cp[3] & 0xFF) << 24; - l |= (unsigned long long) (cp[4] & 0xFF) << 32; - l |= (unsigned long long) (cp[5] & 0xFF) << 40; - l |= (unsigned long long) (cp[6] & 0xFF) << 48; - l |= (unsigned long long) (cp[7] & 0xFF) << 56; - - if (l == v) { - ++signals; - break; - } - } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time)); - alarm(0); - signal(SIGALRM, SIG_DFL); + EXPECT_LE(1, count); - EXPECT_LE(1, count); + EXPECT_EQ(1, signals); - EXPECT_EQ(1, signals); + android_logger_list_close(logger_list); - android_logger_list_close(logger_list); + unsigned long long uticks_end; + unsigned long long sticks_end; + get_ticks(&uticks_end, &sticks_end); - unsigned long long uticks_end; - unsigned long long sticks_end; - get_ticks(&uticks_end, &sticks_end); - - // Less than 1% in either user or system time, or both - const unsigned long long one_percent_ticks = alarm_time; - unsigned long long user_ticks = uticks_end - uticks_start; - unsigned long long system_ticks = sticks_end - sticks_start; - EXPECT_GT(one_percent_ticks, user_ticks); - EXPECT_GT(one_percent_ticks, system_ticks); - EXPECT_GT(one_percent_ticks, user_ticks + system_ticks); + // Less than 1% in either user or system time, or both + const unsigned long long one_percent_ticks = alarm_time; + unsigned long long user_ticks = uticks_end - uticks_start; + unsigned long long system_ticks = sticks_end - sticks_start; + EXPECT_GT(one_percent_ticks, user_ticks); + EXPECT_GT(one_percent_ticks, system_ticks); + EXPECT_GT(one_percent_ticks, user_ticks + system_ticks); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#endif // !USING_LOGGER_LOCAL +#endif // !USING_LOGGER_LOCAL #ifdef TEST_PREFIX static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX"; -#define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \ - sizeof(max_payload_tag) - 1) +#define SIZEOF_MAX_PAYLOAD_BUF \ + (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(max_payload_tag) - 1) #endif -static const char max_payload_buf[] = "LEONATO\n\ +static const char max_payload_buf[] = + "LEONATO\n\ I learn in this letter that Don Peter of Arragon\n\ comes this night to Messina\n\ MESSENGER\n\ @@ -1069,332 +1070,342 @@ takes his leave."; TEST(liblog, max_payload) { #ifdef TEST_PREFIX - TEST_PREFIX - pid_t pid = getpid(); - char tag[sizeof(max_payload_tag)]; - memcpy(tag, max_payload_tag, sizeof(tag)); - snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF); + TEST_PREFIX + pid_t pid = getpid(); + char tag[sizeof(max_payload_tag)]; + memcpy(tag, max_payload_tag, sizeof(tag)); + snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF); - LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, - tag, max_payload_buf)); - sleep(2); + LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO, + tag, max_payload_buf)); + sleep(2); - struct logger_list *logger_list; + struct logger_list* logger_list; - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0))); + ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( + LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0))); - bool matches = false; - ssize_t max_len = 0; + bool matches = false; + ssize_t max_len = 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; + } - if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) { - continue; - } + if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) { + continue; + } - char *data = log_msg.msg(); + char* data = log_msg.msg(); - if (!data || strcmp(++data, tag)) { - continue; - } + if (!data || strcmp(++data, tag)) { + continue; + } - data += strlen(data) + 1; + data += strlen(data) + 1; - const char *left = data; - const char *right = max_payload_buf; - while (*left && *right && (*left == *right)) { - ++left; - ++right; - } + const char* left = data; + const char* right = max_payload_buf; + while (*left && *right && (*left == *right)) { + ++left; + ++right; + } - if (max_len <= (left - data)) { - max_len = left - data + 1; - } + if (max_len <= (left - data)) { + max_len = left - data + 1; + } - if (max_len > 512) { - matches = true; - break; - } + if (max_len > 512) { + matches = true; + break; } + } - android_logger_list_close(logger_list); + android_logger_list_close(logger_list); #if SUPPORTS_END_TO_END - EXPECT_EQ(true, matches); + EXPECT_EQ(true, matches); - EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len)); + EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len)); #else - EXPECT_EQ(false, matches); + EXPECT_EQ(false, matches); #endif #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, __android_log_buf_print__maxtag) { #ifdef TEST_PREFIX - TEST_PREFIX - struct logger_list *logger_list; + TEST_PREFIX + struct logger_list* logger_list; - pid_t pid = getpid(); + pid_t pid = getpid(); - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + ASSERT_TRUE( + NULL != + (logger_list = android_logger_list_open( + LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); #ifdef __ANDROID__ - log_time ts(android_log_clockid()); + log_time ts(android_log_clockid()); #else - log_time ts(CLOCK_REALTIME); + log_time ts(CLOCK_REALTIME); #endif - EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, - max_payload_buf, max_payload_buf)); - usleep(1000000); + EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, + max_payload_buf, max_payload_buf)); + usleep(1000000); - 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; + } - ASSERT_EQ(log_msg.entry.pid, pid); + ASSERT_EQ(log_msg.entry.pid, pid); - if ((log_msg.entry.sec < (ts.tv_sec - 1)) - || ((ts.tv_sec + 1) < log_msg.entry.sec) - || ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD) - || (log_msg.id() != LOG_ID_MAIN)) { - continue; - } + if ((log_msg.entry.sec < (ts.tv_sec - 1)) || + ((ts.tv_sec + 1) < log_msg.entry.sec) || + ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD) || + (log_msg.id() != LOG_ID_MAIN)) { + continue; + } - ++count; - - AndroidLogFormat *logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1, - &entry); - EXPECT_EQ(0, processLogBuffer); - if (processLogBuffer == 0) { - fflush(stderr); - int printLogLine = - android_log_printLogLine(logformat, fileno(stderr), &entry); - // Legacy tag truncation - EXPECT_LE(128, printLogLine); - // Measured maximum if we try to print part of the tag as message - EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine); - } - android_log_format_free(logformat); + ++count; + + AndroidLogFormat* logformat = android_log_format_new(); + EXPECT_TRUE(NULL != logformat); + AndroidLogEntry entry; + int processLogBuffer = + android_log_processLogBuffer(&log_msg.entry_v1, &entry); + EXPECT_EQ(0, processLogBuffer); + if (processLogBuffer == 0) { + fflush(stderr); + int printLogLine = + android_log_printLogLine(logformat, fileno(stderr), &entry); + // Legacy tag truncation + EXPECT_LE(128, printLogLine); + // Measured maximum if we try to print part of the tag as message + EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine); } + android_log_format_free(logformat); + } - EXPECT_EQ(SUPPORTS_END_TO_END, count); + EXPECT_EQ(SUPPORTS_END_TO_END, count); - 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 } TEST(liblog, too_big_payload) { #ifdef TEST_PREFIX - TEST_PREFIX - pid_t pid = getpid(); - static const char big_payload_tag[] = "TEST_big_payload_XXXX"; - char tag[sizeof(big_payload_tag)]; - memcpy(tag, big_payload_tag, sizeof(tag)); - snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF); + TEST_PREFIX + pid_t pid = getpid(); + static const char big_payload_tag[] = "TEST_big_payload_XXXX"; + char tag[sizeof(big_payload_tag)]; + memcpy(tag, big_payload_tag, sizeof(tag)); + snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF); - std::string longString(3266519, 'x'); + std::string longString(3266519, 'x'); - ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, - ANDROID_LOG_INFO, tag, longString.c_str())); + ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write( + LOG_ID_SYSTEM, ANDROID_LOG_INFO, tag, longString.c_str())); - struct logger_list *logger_list; + struct logger_list* logger_list; - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_SYSTEM, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0))); + ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( + LOG_ID_SYSTEM, + ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0))); - ssize_t max_len = 0; + ssize_t max_len = 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; + } - if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) { - continue; - } + if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) { + continue; + } - char *data = log_msg.msg(); + char* data = log_msg.msg(); - if (!data || strcmp(++data, tag)) { - continue; - } + if (!data || strcmp(++data, tag)) { + continue; + } - data += strlen(data) + 1; + data += strlen(data) + 1; - const char *left = data; - const char *right = longString.c_str(); - while (*left && *right && (*left == *right)) { - ++left; - ++right; - } + const char* left = data; + const char* right = longString.c_str(); + while (*left && *right && (*left == *right)) { + ++left; + ++right; + } - if (max_len <= (left - data)) { - max_len = left - data + 1; - } + if (max_len <= (left - data)) { + max_len = left - data + 1; } + } - android_logger_list_close(logger_list); + android_logger_list_close(logger_list); #if !SUPPORTS_END_TO_END - max_len = max_len ? - max_len : - LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag); + max_len = + max_len ? max_len : LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag); #endif - EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag), - static_cast<size_t>(max_len)); - - // SLOP: Allow the underlying interface to optionally place a - // terminating nul at the LOGGER_ENTRY_MAX_PAYLOAD's last byte - // or not. - if (ret == (max_len + static_cast<ssize_t>(sizeof(big_payload_tag)) - 1)) { - --max_len; - } - EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag))); + EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag), + static_cast<size_t>(max_len)); + + // SLOP: Allow the underlying interface to optionally place a + // terminating nul at the LOGGER_ENTRY_MAX_PAYLOAD's last byte + // or not. + if (ret == (max_len + static_cast<ssize_t>(sizeof(big_payload_tag)) - 1)) { + --max_len; + } + EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag))); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, dual_reader) { #ifdef TEST_PREFIX - TEST_PREFIX + TEST_PREFIX - static const int num = 25; + static const int num = 25; - for (int i = 25; i > 0; --i) { - static const char fmt[] = "dual_reader %02d"; - char buffer[sizeof(fmt) + 8]; - snprintf(buffer, sizeof(buffer), fmt, i); - LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_MAIN, - ANDROID_LOG_INFO, - "liblog", buffer)); - } - usleep(1000000); + for (int i = 25; i > 0; --i) { + static const char fmt[] = "dual_reader %02d"; + char buffer[sizeof(fmt) + 8]; + snprintf(buffer, sizeof(buffer), fmt, i); + LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, + "liblog", buffer)); + } + usleep(1000000); - struct logger_list *logger_list1; - ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open( - LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, num, 0))); + struct logger_list* logger_list1; + ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open( + LOG_ID_MAIN, + ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, num, 0))); - struct logger_list *logger_list2; + struct logger_list* logger_list2; - if (NULL == (logger_list2 = android_logger_list_open( - LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, num - 10, 0))) { - android_logger_list_close(logger_list1); - ASSERT_TRUE(NULL != logger_list2); - } + if (NULL == (logger_list2 = android_logger_list_open( + LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + num - 10, 0))) { + android_logger_list_close(logger_list1); + ASSERT_TRUE(NULL != logger_list2); + } - int count1 = 0; - bool done1 = false; - int count2 = 0; - bool done2 = false; + int count1 = 0; + bool done1 = false; + int count2 = 0; + bool done2 = false; - do { - log_msg log_msg; + do { + log_msg log_msg; - if (!done1) { - if (android_logger_list_read(logger_list1, &log_msg) <= 0) { - done1 = true; - } else { - ++count1; - } - } + if (!done1) { + if (android_logger_list_read(logger_list1, &log_msg) <= 0) { + done1 = true; + } else { + ++count1; + } + } - if (!done2) { - if (android_logger_list_read(logger_list2, &log_msg) <= 0) { - done2 = true; - } else { - ++count2; - } - } - } while ((!done1) || (!done2)); + if (!done2) { + if (android_logger_list_read(logger_list2, &log_msg) <= 0) { + done2 = true; + } else { + ++count2; + } + } + } while ((!done1) || (!done2)); - android_logger_list_close(logger_list1); - android_logger_list_close(logger_list2); + android_logger_list_close(logger_list1); + android_logger_list_close(logger_list2); - EXPECT_EQ(num * SUPPORTS_END_TO_END, count1); - EXPECT_EQ((num - 10) * SUPPORTS_END_TO_END, count2); + EXPECT_EQ(num * SUPPORTS_END_TO_END, count1); + EXPECT_EQ((num - 10) * SUPPORTS_END_TO_END, count2); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#ifdef USING_LOGGER_DEFAULT // Do not retest logprint -static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) { - return android_log_shouldPrintLine(p_format, tag, pri) - && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1)); +#ifdef USING_LOGGER_DEFAULT // Do not retest logprint +static bool checkPriForTag(AndroidLogFormat* p_format, const char* tag, + android_LogPriority pri) { + return android_log_shouldPrintLine(p_format, tag, pri) && + !android_log_shouldPrintLine(p_format, tag, + (android_LogPriority)(pri - 1)); } TEST(liblog, filterRule) { - static const char tag[] = "random"; - - AndroidLogFormat *p_format = android_log_format_new(); - - android_log_addFilterRule(p_format,"*:i"); - - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - android_log_addFilterRule(p_format, "*"); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "*:v"); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "*:i"); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - - android_log_addFilterRule(p_format, tag); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:v"); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:d"); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:w"); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - - android_log_addFilterRule(p_format, "crap:*"); - EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0); - - // invalid expression - EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0); - EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); - EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - - // Issue #550946 - EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); - - // note trailing space - EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0); - EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); - - EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0); - -#if 0 // bitrot, seek update + static const char tag[] = "random"; + + AndroidLogFormat* p_format = android_log_format_new(); + + android_log_addFilterRule(p_format, "*:i"); + + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == + 0); + android_log_addFilterRule(p_format, "*"); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); + android_log_addFilterRule(p_format, "*:v"); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); + android_log_addFilterRule(p_format, "*:i"); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == + 0); + + android_log_addFilterRule(p_format, tag); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); + android_log_addFilterRule(p_format, "random:v"); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); + android_log_addFilterRule(p_format, "random:d"); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); + android_log_addFilterRule(p_format, "random:w"); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == + 0); + + android_log_addFilterRule(p_format, "crap:*"); + EXPECT_TRUE(checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE)); + EXPECT_TRUE( + android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0); + + // invalid expression + EXPECT_TRUE(android_log_addFilterRule(p_format, "random:z") < 0); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); + EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == + 0); + + // Issue #550946 + EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN)); + + // note trailing space + EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0); + EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG)); + + EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0); + +#if 0 // bitrot, seek update char defaultBuffer[512]; android_log_formatLogLine(p_format, @@ -1404,310 +1415,299 @@ TEST(liblog, filterRule) { fprintf(stderr, "%s\n", defaultBuffer); #endif - android_log_format_free(p_format); + android_log_format_free(p_format); } -#endif // USING_LOGGER_DEFAULT +#endif // USING_LOGGER_DEFAULT -#ifdef USING_LOGGER_DEFAULT // Do not retest property handling +#ifdef USING_LOGGER_DEFAULT // Do not retest property handling TEST(liblog, is_loggable) { #ifdef __ANDROID__ - static const char tag[] = "is_loggable"; - static const char log_namespace[] = "persist.log.tag."; - static const size_t base_offset = 8; /* skip "persist." */ - // sizeof("string") = strlen("string") + 1 - char key[sizeof(log_namespace) + sizeof(tag) - 1]; - char hold[4][PROP_VALUE_MAX]; - static const struct { - int level; - char type; - } levels[] = { - { ANDROID_LOG_VERBOSE, 'v' }, - { ANDROID_LOG_DEBUG , 'd' }, - { ANDROID_LOG_INFO , 'i' }, - { ANDROID_LOG_WARN , 'w' }, - { ANDROID_LOG_ERROR , 'e' }, - { ANDROID_LOG_FATAL , 'a' }, - { -1 , 's' }, - { -2 , 'g' }, // Illegal value, resort to default - }; - - // Set up initial test condition - memset(hold, 0, sizeof(hold)); - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - property_get(key, hold[0], ""); - property_set(key, ""); - property_get(key + base_offset, hold[1], ""); - property_set(key + base_offset, ""); - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - property_get(key, hold[2], ""); - property_set(key, ""); - property_get(key, hold[3], ""); - property_set(key + base_offset, ""); - - // All combinations of level and defaults - for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { - if (levels[i].level == -2) { - continue; - } - for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { - if (levels[j].level == -2) { - continue; - } - fprintf(stderr, "i=%zu j=%zu\r", i, j); - bool android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), levels[j].level); - if ((levels[i].level < levels[j].level) - || (levels[j].level == -1)) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), levels[j].level)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), levels[j].level)); - } - } - } - } - - // All combinations of level and tag and global properties - for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { - if (levels[i].level == -2) { - continue; - } - for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { - char buf[2]; - buf[0] = levels[j].type; - buf[1] = '\0'; - - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", - i, j, key, buf); - usleep(20000); - property_set(key, buf); - bool android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) - || (levels[j].level == -1) - || ((levels[i].level < ANDROID_LOG_DEBUG) - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key, ""); - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", - i, j, key + base_offset, buf); - property_set(key + base_offset, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) - || (levels[j].level == -1) - || ((levels[i].level < ANDROID_LOG_DEBUG) - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key + base_offset, ""); - - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", - i, j, key, buf); - property_set(key, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) - || (levels[j].level == -1) - || ((levels[i].level < ANDROID_LOG_DEBUG) - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key, ""); - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", - i, j, key + base_offset, buf); - property_set(key + base_offset, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) - || (levels[j].level == -1) - || ((levels[i].level < ANDROID_LOG_DEBUG) - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key + base_offset, ""); - } - } - - // All combinations of level and tag properties, but with global set to INFO - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - usleep(20000); - property_set(key, "I"); - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { - if (levels[i].level == -2) { - continue; - } - for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { - char buf[2]; - buf[0] = levels[j].type; - buf[1] = '\0'; - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", - i, j, key, buf); - usleep(20000); - property_set(key, buf); - bool android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) - || (levels[j].level == -1) - || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key, ""); - - fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", - i, j, key + base_offset, buf); - property_set(key + base_offset, buf); - android_log_is_loggable = __android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); - if ((levels[i].level < levels[j].level) - || (levels[j].level == -1) - || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO - && (levels[j].level == -2))) { - if (android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_FALSE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_FALSE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } else { - if (!android_log_is_loggable) { - fprintf(stderr, "\n"); - } - EXPECT_TRUE(android_log_is_loggable); - for(size_t k = 10; k; --k) { - EXPECT_TRUE(__android_log_is_loggable_len( - levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); - } - } - usleep(20000); - property_set(key + base_offset, ""); - } - } - - // reset parms - snprintf(key, sizeof(key), "%s%s", log_namespace, tag); - usleep(20000); - property_set(key, hold[0]); - property_set(key + base_offset, hold[1]); - strcpy(key, log_namespace); - key[sizeof(log_namespace) - 2] = '\0'; - property_set(key, hold[2]); - property_set(key + base_offset, hold[3]); + static const char tag[] = "is_loggable"; + static const char log_namespace[] = "persist.log.tag."; + static const size_t base_offset = 8; /* skip "persist." */ + // sizeof("string") = strlen("string") + 1 + char key[sizeof(log_namespace) + sizeof(tag) - 1]; + char hold[4][PROP_VALUE_MAX]; + static const struct { + int level; + char type; + } levels[] = { + { ANDROID_LOG_VERBOSE, 'v' }, + { ANDROID_LOG_DEBUG, 'd' }, + { ANDROID_LOG_INFO, 'i' }, + { ANDROID_LOG_WARN, 'w' }, + { ANDROID_LOG_ERROR, 'e' }, + { ANDROID_LOG_FATAL, 'a' }, + { -1, 's' }, + { -2, 'g' }, // Illegal value, resort to default + }; + + // Set up initial test condition + memset(hold, 0, sizeof(hold)); + snprintf(key, sizeof(key), "%s%s", log_namespace, tag); + property_get(key, hold[0], ""); + property_set(key, ""); + property_get(key + base_offset, hold[1], ""); + property_set(key + base_offset, ""); + strcpy(key, log_namespace); + key[sizeof(log_namespace) - 2] = '\0'; + property_get(key, hold[2], ""); + property_set(key, ""); + property_get(key, hold[3], ""); + property_set(key + base_offset, ""); + + // All combinations of level and defaults + for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { + if (levels[i].level == -2) { + continue; + } + for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { + if (levels[j].level == -2) { + continue; + } + fprintf(stderr, "i=%zu j=%zu\r", i, j); + bool android_log_is_loggable = __android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), levels[j].level); + if ((levels[i].level < levels[j].level) || (levels[j].level == -1)) { + if (android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_FALSE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_FALSE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), levels[j].level)); + } + } else { + if (!android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_TRUE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_TRUE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), levels[j].level)); + } + } + } + } + + // All combinations of level and tag and global properties + for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { + if (levels[i].level == -2) { + continue; + } + for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { + char buf[2]; + buf[0] = levels[j].type; + buf[1] = '\0'; + + snprintf(key, sizeof(key), "%s%s", log_namespace, tag); + fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key, + buf); + usleep(20000); + property_set(key, buf); + bool android_log_is_loggable = __android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); + if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || + ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { + if (android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_FALSE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_FALSE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } else { + if (!android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_TRUE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_TRUE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } + usleep(20000); + property_set(key, ""); + + fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, + key + base_offset, buf); + property_set(key + base_offset, buf); + android_log_is_loggable = __android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); + if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || + ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { + if (android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_FALSE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_FALSE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } else { + if (!android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_TRUE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_TRUE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } + usleep(20000); + property_set(key + base_offset, ""); + + strcpy(key, log_namespace); + key[sizeof(log_namespace) - 2] = '\0'; + fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key, + buf); + property_set(key, buf); + android_log_is_loggable = __android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); + if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || + ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { + if (android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_FALSE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_FALSE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } else { + if (!android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_TRUE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_TRUE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } + usleep(20000); + property_set(key, ""); + + fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, + key + base_offset, buf); + property_set(key + base_offset, buf); + android_log_is_loggable = __android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); + if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || + ((levels[i].level < ANDROID_LOG_DEBUG) && (levels[j].level == -2))) { + if (android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_FALSE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_FALSE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } else { + if (!android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_TRUE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_TRUE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } + usleep(20000); + property_set(key + base_offset, ""); + } + } + + // All combinations of level and tag properties, but with global set to INFO + strcpy(key, log_namespace); + key[sizeof(log_namespace) - 2] = '\0'; + usleep(20000); + property_set(key, "I"); + snprintf(key, sizeof(key), "%s%s", log_namespace, tag); + for (size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) { + if (levels[i].level == -2) { + continue; + } + for (size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) { + char buf[2]; + buf[0] = levels[j].type; + buf[1] = '\0'; + + fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, key, + buf); + usleep(20000); + property_set(key, buf); + bool android_log_is_loggable = __android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); + if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || + ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO + && (levels[j].level == -2))) { + if (android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_FALSE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_FALSE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } else { + if (!android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_TRUE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_TRUE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } + usleep(20000); + property_set(key, ""); + + fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r", i, j, + key + base_offset, buf); + property_set(key + base_offset, buf); + android_log_is_loggable = __android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG); + if ((levels[i].level < levels[j].level) || (levels[j].level == -1) || + ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO + && (levels[j].level == -2))) { + if (android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_FALSE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_FALSE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } else { + if (!android_log_is_loggable) { + fprintf(stderr, "\n"); + } + EXPECT_TRUE(android_log_is_loggable); + for (size_t k = 10; k; --k) { + EXPECT_TRUE(__android_log_is_loggable_len( + levels[i].level, tag, strlen(tag), ANDROID_LOG_DEBUG)); + } + } + usleep(20000); + property_set(key + base_offset, ""); + } + } + + // reset parms + snprintf(key, sizeof(key), "%s%s", log_namespace, tag); + usleep(20000); + property_set(key, hold[0]); + property_set(key + base_offset, hold[1]); + strcpy(key, log_namespace); + key[sizeof(log_namespace) - 2] = '\0'; + property_set(key, hold[2]); + property_set(key + base_offset, hold[3]); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#endif // USING_LOGGER_DEFAULT +#endif // USING_LOGGER_DEFAULT // Following tests the specific issues surrounding error handling wrt logd. // Kills logd and toss all collected data, equivalent to logcat -b all -c, @@ -1716,104 +1716,103 @@ TEST(liblog, is_loggable) { #ifdef TEST_PREFIX // helper to liblog.enoent to count end-to-end matching logging messages. static int count_matching_ts(log_time ts) { - usleep(1000000); + usleep(1000000); - pid_t pid = getpid(); + pid_t pid = getpid(); - struct logger_list* logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid); + struct logger_list* logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid); - int count = 0; - if (logger_list == NULL) return count; + int count = 0; + if (logger_list == NULL) return count; - 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; - if (log_msg.entry.len != sizeof(android_log_event_long_t)) continue; - if (log_msg.id() != LOG_ID_EVENTS) continue; + if (log_msg.entry.len != sizeof(android_log_event_long_t)) continue; + if (log_msg.id() != LOG_ID_EVENTS) continue; - android_log_event_long_t* eventData; - eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); - if (!eventData) continue; - if (eventData->payload.type != EVENT_TYPE_LONG) continue; + android_log_event_long_t* eventData; + eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); + if (!eventData) continue; + if (eventData->payload.type != EVENT_TYPE_LONG) continue; - log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); - if (ts != tx) continue; + log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); + if (ts != tx) continue; - // found event message with matching timestamp signature in payload - ++count; - } - android_logger_list_close(logger_list); + // found event message with matching timestamp signature in payload + ++count; + } + android_logger_list_close(logger_list); - return count; + return count; } // meant to be handed to ASSERT_TRUE / EXPECT_TRUE only to expand the message -static testing::AssertionResult IsOk(bool ok, std::string &message) { - return ok ? - testing::AssertionSuccess() : - (testing::AssertionFailure() << message); +static testing::AssertionResult IsOk(bool ok, std::string& message) { + return ok ? testing::AssertionSuccess() + : (testing::AssertionFailure() << message); } -#endif // TEST_PREFIX +#endif // TEST_PREFIX TEST(liblog, enoent) { #ifdef TEST_PREFIX - TEST_PREFIX - log_time ts(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts)); - - // This call will fail if we are setuid(AID_SYSTEM), beware of any - // test prior to this one playing with setuid and causing interference. - // We need to run before these tests so that they do not interfere with - // this test. - // - // Stopping the logger can affect some other test's expectations as they - // count on the log buffers filled with existing content, and this - // effectively does a logcat -c emptying it. So we want this test to be - // as near as possible to the bottom of the file. For example - // liblog.android_logger_get_ is one of those tests that has no recourse - // and that would be adversely affected by emptying the log if it was run - // right after this test. - system("stop logd"); - usleep(1000000); - - // A clean stop like we are testing returns -ENOENT, but in the _real_ - // world we could get -ENOTCONN or -ECONNREFUSED depending on timing. - // Alas we can not test these other return values; accept that they - // are treated equally within the open-retry logic in liblog. - ts = log_time(CLOCK_MONOTONIC); - int ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)); - std::string content = android::base::StringPrintf( - "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n", - ret, strerror(-ret)); - EXPECT_TRUE(IsOk((ret == -ENOENT) || - (ret == -ENOTCONN) || - (ret == -ECONNREFUSED), content)); - ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)); - content = android::base::StringPrintf( - "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n", - ret, strerror(-ret)); - EXPECT_TRUE(IsOk((ret == -ENOENT) || - (ret == -ENOTCONN) || - (ret == -ECONNREFUSED), content)); - EXPECT_EQ(0, count_matching_ts(ts)); - - system("start logd"); - usleep(1000000); - - EXPECT_EQ(0, count_matching_ts(ts)); - - ts = log_time(CLOCK_MONOTONIC); - EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); - EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts)); + TEST_PREFIX + log_time ts(CLOCK_MONOTONIC); + EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); + EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts)); + + // This call will fail if we are setuid(AID_SYSTEM), beware of any + // test prior to this one playing with setuid and causing interference. + // We need to run before these tests so that they do not interfere with + // this test. + // + // Stopping the logger can affect some other test's expectations as they + // count on the log buffers filled with existing content, and this + // effectively does a logcat -c emptying it. So we want this test to be + // as near as possible to the bottom of the file. For example + // liblog.android_logger_get_ is one of those tests that has no recourse + // and that would be adversely affected by emptying the log if it was run + // right after this test. + system("stop logd"); + usleep(1000000); + + // A clean stop like we are testing returns -ENOENT, but in the _real_ + // world we could get -ENOTCONN or -ECONNREFUSED depending on timing. + // Alas we can not test these other return values; accept that they + // are treated equally within the open-retry logic in liblog. + ts = log_time(CLOCK_MONOTONIC); + int ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)); + std::string content = android::base::StringPrintf( + "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n", + ret, strerror(-ret)); + EXPECT_TRUE( + IsOk((ret == -ENOENT) || (ret == -ENOTCONN) || (ret == -ECONNREFUSED), + content)); + ret = __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)); + content = android::base::StringPrintf( + "__android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)) = %d %s\n", + ret, strerror(-ret)); + EXPECT_TRUE( + IsOk((ret == -ENOENT) || (ret == -ENOTCONN) || (ret == -ECONNREFUSED), + content)); + EXPECT_EQ(0, count_matching_ts(ts)); + + system("start logd"); + usleep(1000000); + + EXPECT_EQ(0, count_matching_ts(ts)); + + ts = log_time(CLOCK_MONOTONIC); + EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts))); + EXPECT_EQ(SUPPORTS_END_TO_END, count_matching_ts(ts)); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#endif // USING_LOCAL_LOGD +#endif // USING_LOCAL_LOGD // Below this point we run risks of setuid(AID_SYSTEM) which may affect others. @@ -1821,1413 +1820,1406 @@ TEST(liblog, enoent) { #ifdef USING_LOGGER_DEFAULT TEST(liblog, __security) { #ifdef __ANDROID__ - static const char persist_key[] = "persist.logd.security"; - static const char readonly_key[] = "ro.device_owner"; - // A silly default value that can never be in readonly_key so - // that it can be determined the property is not set. - static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_"; - char persist[PROP_VALUE_MAX]; - char readonly[PROP_VALUE_MAX]; - - property_get(persist_key, persist, ""); - property_get(readonly_key, readonly, nothing_val); - - if (!strcmp(readonly, nothing_val)) { - EXPECT_FALSE(__android_log_security()); - fprintf(stderr, "Warning, setting ro.device_owner to a domain\n"); - property_set(readonly_key, "com.google.android.SecOps.DeviceOwner"); - } else if (!strcasecmp(readonly, "false") || !readonly[0]) { - EXPECT_FALSE(__android_log_security()); - return; - } - - if (!strcasecmp(persist, "true")) { - EXPECT_TRUE(__android_log_security()); - } else { - EXPECT_FALSE(__android_log_security()); - } - property_set(persist_key, "TRUE"); - EXPECT_TRUE(__android_log_security()); - property_set(persist_key, "FALSE"); + static const char persist_key[] = "persist.logd.security"; + static const char readonly_key[] = "ro.device_owner"; + // A silly default value that can never be in readonly_key so + // that it can be determined the property is not set. + static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_"; + char persist[PROP_VALUE_MAX]; + char readonly[PROP_VALUE_MAX]; + + property_get(persist_key, persist, ""); + property_get(readonly_key, readonly, nothing_val); + + if (!strcmp(readonly, nothing_val)) { EXPECT_FALSE(__android_log_security()); - property_set(persist_key, "true"); - EXPECT_TRUE(__android_log_security()); - property_set(persist_key, "false"); + fprintf(stderr, "Warning, setting ro.device_owner to a domain\n"); + property_set(readonly_key, "com.google.android.SecOps.DeviceOwner"); + } else if (!strcasecmp(readonly, "false") || !readonly[0]) { EXPECT_FALSE(__android_log_security()); - property_set(persist_key, ""); + return; + } + + if (!strcasecmp(persist, "true")) { + EXPECT_TRUE(__android_log_security()); + } else { EXPECT_FALSE(__android_log_security()); - property_set(persist_key, persist); + } + property_set(persist_key, "TRUE"); + EXPECT_TRUE(__android_log_security()); + property_set(persist_key, "FALSE"); + EXPECT_FALSE(__android_log_security()); + property_set(persist_key, "true"); + EXPECT_TRUE(__android_log_security()); + property_set(persist_key, "false"); + EXPECT_FALSE(__android_log_security()); + property_set(persist_key, ""); + EXPECT_FALSE(__android_log_security()); + property_set(persist_key, persist); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, __security_buffer) { #ifdef __ANDROID__ - struct logger_list *logger_list; - android_event_long_t buffer; + struct logger_list* logger_list; + android_event_long_t buffer; - static const char persist_key[] = "persist.logd.security"; - char persist[PROP_VALUE_MAX]; - bool set_persist = false; - bool allow_security = false; + static const char persist_key[] = "persist.logd.security"; + char persist[PROP_VALUE_MAX]; + bool set_persist = false; + bool allow_security = false; - if (__android_log_security()) { + if (__android_log_security()) { + allow_security = true; + } else { + property_get(persist_key, persist, ""); + if (strcasecmp(persist, "true")) { + property_set(persist_key, "TRUE"); + if (__android_log_security()) { allow_security = true; - } else { - property_get(persist_key, persist, ""); - if (strcasecmp(persist, "true")) { - property_set(persist_key, "TRUE"); - if (__android_log_security()) { - allow_security = true; - set_persist = true; - } else { - property_set(persist_key, persist); - } - } + set_persist = true; + } else { + property_set(persist_key, persist); + } } + } + + if (!allow_security) { + fprintf(stderr, + "WARNING: " + "security buffer disabled, bypassing end-to-end test\n"); - if (!allow_security) { - fprintf(stderr, "WARNING: " - "security buffer disabled, bypassing end-to-end test\n"); - - log_time ts(CLOCK_MONOTONIC); - - buffer.type = EVENT_TYPE_LONG; - buffer.data = *(static_cast<uint64_t *>((void *)&ts)); - - // expect failure! - ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); - - return; - } - - /* Matches clientHasLogCredentials() in logd */ - uid_t uid = getuid(); - gid_t gid = getgid(); - bool clientHasLogCredentials = true; - if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG) - && (gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { - uid_t euid = geteuid(); - if ((euid != AID_SYSTEM) && (euid != AID_ROOT) && (euid != AID_LOG)) { - gid_t egid = getegid(); - if ((egid != AID_SYSTEM) && (egid != AID_ROOT) && (egid != AID_LOG)) { - int num_groups = getgroups(0, NULL); - if (num_groups > 0) { - gid_t groups[num_groups]; - num_groups = getgroups(num_groups, groups); - while (num_groups > 0) { - if (groups[num_groups - 1] == AID_LOG) { - break; - } - --num_groups; - } - } - if (num_groups <= 0) { - clientHasLogCredentials = false; - } + log_time ts(CLOCK_MONOTONIC); + + buffer.type = EVENT_TYPE_LONG; + buffer.data = *(static_cast<uint64_t*>((void*)&ts)); + + // expect failure! + ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); + + return; + } + + /* Matches clientHasLogCredentials() in logd */ + uid_t uid = getuid(); + gid_t gid = getgid(); + bool clientHasLogCredentials = true; + if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG) && + (gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) { + uid_t euid = geteuid(); + if ((euid != AID_SYSTEM) && (euid != AID_ROOT) && (euid != AID_LOG)) { + gid_t egid = getegid(); + if ((egid != AID_SYSTEM) && (egid != AID_ROOT) && (egid != AID_LOG)) { + int num_groups = getgroups(0, NULL); + if (num_groups > 0) { + gid_t groups[num_groups]; + num_groups = getgroups(num_groups, groups); + while (num_groups > 0) { + if (groups[num_groups - 1] == AID_LOG) { + break; } + --num_groups; + } } + if (num_groups <= 0) { + clientHasLogCredentials = false; + } + } } - if (!clientHasLogCredentials) { - fprintf(stderr, "WARNING: " - "not in system context, bypassing end-to-end test\n"); - - log_time ts(CLOCK_MONOTONIC); + } + if (!clientHasLogCredentials) { + fprintf(stderr, + "WARNING: " + "not in system context, bypassing end-to-end test\n"); - buffer.type = EVENT_TYPE_LONG; - buffer.data = *(static_cast<uint64_t *>((void *)&ts)); + log_time ts(CLOCK_MONOTONIC); - // expect failure! - ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); + buffer.type = EVENT_TYPE_LONG; + buffer.data = *(static_cast<uint64_t*>((void*)&ts)); - return; - } + // expect failure! + ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); - EXPECT_EQ(0, setuid(AID_SYSTEM)); // only one that can read security buffer + return; + } - pid_t pid = getpid(); + EXPECT_EQ(0, setuid(AID_SYSTEM)); // only one that can read security buffer - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_SECURITY, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, - 1000, pid))); + pid_t pid = getpid(); - log_time ts(CLOCK_MONOTONIC); + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_SECURITY, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); - buffer.type = EVENT_TYPE_LONG; - buffer.data = *(static_cast<uint64_t *>((void *)&ts)); + log_time ts(CLOCK_MONOTONIC); - ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); - usleep(1000000); + buffer.type = EVENT_TYPE_LONG; + buffer.data = *(static_cast<uint64_t*>((void*)&ts)); - int count = 0; + ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer))); + usleep(1000000); - for (;;) { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) { - break; - } + int count = 0; - ASSERT_EQ(log_msg.entry.pid, pid); + for (;;) { + log_msg log_msg; + if (android_logger_list_read(logger_list, &log_msg) <= 0) { + break; + } - if ((log_msg.entry.len != sizeof(android_log_event_long_t)) - || (log_msg.id() != LOG_ID_SECURITY)) { - continue; - } + ASSERT_EQ(log_msg.entry.pid, pid); - android_log_event_long_t* eventData; - eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); + if ((log_msg.entry.len != sizeof(android_log_event_long_t)) || + (log_msg.id() != LOG_ID_SECURITY)) { + continue; + } - if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { - continue; - } + android_log_event_long_t* eventData; + eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg()); - log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); - if (ts == tx) { - ++count; - } + if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) { + continue; } - if (set_persist) { - property_set(persist_key, persist); + log_time tx(reinterpret_cast<char*>(&eventData->payload.data)); + if (ts == tx) { + ++count; } + } - android_logger_list_close(logger_list); + if (set_persist) { + property_set(persist_key, persist); + } - bool clientHasSecurityCredentials = (uid == AID_SYSTEM) || (gid == AID_SYSTEM); - if (!clientHasSecurityCredentials) { - fprintf(stderr, "WARNING: " - "not system, content submitted but can not check end-to-end\n"); - } - EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count); + android_logger_list_close(logger_list); + + bool clientHasSecurityCredentials = (uid == AID_SYSTEM) || (gid == AID_SYSTEM); + if (!clientHasSecurityCredentials) { + fprintf(stderr, + "WARNING: " + "not system, content submitted but can not check end-to-end\n"); + } + EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#endif // USING_LOGGER_DEFAULT +#endif // USING_LOGGER_DEFAULT #ifdef TEST_PREFIX static void android_errorWriteWithInfoLog_helper(int TAG, const char* SUBTAG, int UID, const char* payload, int DATA_LEN, int& count) { - TEST_PREFIX - struct logger_list *logger_list; + TEST_PREFIX + struct logger_list* logger_list; - pid_t pid = getpid(); + pid_t pid = getpid(); - count = 0; + count = 0; - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); - - int retval_android_errorWriteWithinInfoLog = android_errorWriteWithInfoLog( - TAG, SUBTAG, UID, payload, DATA_LEN); - if (payload) { - ASSERT_LT(0, retval_android_errorWriteWithinInfoLog); - } else { - ASSERT_GT(0, retval_android_errorWriteWithinInfoLog); - } + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); - sleep(2); + int retval_android_errorWriteWithinInfoLog = + android_errorWriteWithInfoLog(TAG, SUBTAG, UID, payload, DATA_LEN); + if (payload) { + ASSERT_LT(0, retval_android_errorWriteWithinInfoLog); + } else { + ASSERT_GT(0, retval_android_errorWriteWithinInfoLog); + } - for (;;) { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) { - break; - } + sleep(2); - char *eventData = log_msg.msg(); - if (!eventData) { - continue; - } + for (;;) { + log_msg log_msg; + if (android_logger_list_read(logger_list, &log_msg) <= 0) { + break; + } - char *original = eventData; + char* eventData = log_msg.msg(); + if (!eventData) { + continue; + } - // Tag - int tag = get4LE(eventData); - eventData += 4; + char* original = eventData; - if (tag != TAG) { - continue; - } + // Tag + int tag = get4LE(eventData); + eventData += 4; - if (!payload) { - // This tag should not have been written because the data was null - ++count; - break; - } + if (tag != TAG) { + continue; + } - // List type - ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]); - eventData++; + if (!payload) { + // This tag should not have been written because the data was null + ++count; + break; + } - // Number of elements in list - ASSERT_EQ(3, eventData[0]); - eventData++; + // List type + ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]); + eventData++; - // Element #1: string type for subtag - ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]); - eventData++; + // Number of elements in list + ASSERT_EQ(3, eventData[0]); + eventData++; - unsigned subtag_len = strlen(SUBTAG); - if (subtag_len > 32) subtag_len = 32; - ASSERT_EQ(subtag_len, get4LE(eventData)); - eventData += 4; + // Element #1: string type for subtag + ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]); + eventData++; - if (memcmp(SUBTAG, eventData, subtag_len)) { - continue; - } - eventData += subtag_len; + unsigned subtag_len = strlen(SUBTAG); + if (subtag_len > 32) subtag_len = 32; + ASSERT_EQ(subtag_len, get4LE(eventData)); + eventData += 4; - // Element #2: int type for uid - ASSERT_EQ(EVENT_TYPE_INT, eventData[0]); - eventData++; + if (memcmp(SUBTAG, eventData, subtag_len)) { + continue; + } + eventData += subtag_len; - ASSERT_EQ(UID, (int)get4LE(eventData)); - eventData += 4; + // Element #2: int type for uid + ASSERT_EQ(EVENT_TYPE_INT, eventData[0]); + eventData++; - // Element #3: string type for data - ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]); - eventData++; + ASSERT_EQ(UID, (int)get4LE(eventData)); + eventData += 4; - size_t dataLen = get4LE(eventData); - eventData += 4; - if (DATA_LEN < 512) ASSERT_EQ(DATA_LEN, (int)dataLen); + // Element #3: string type for data + ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]); + eventData++; - if (memcmp(payload, eventData, dataLen)) { - continue; - } + size_t dataLen = get4LE(eventData); + eventData += 4; + if (DATA_LEN < 512) ASSERT_EQ(DATA_LEN, (int)dataLen); - if (DATA_LEN >= 512) { - eventData += dataLen; - // 4 bytes for the tag, and max_payload_buf should be truncated. - ASSERT_LE(4 + 512, eventData - original); // worst expectations - ASSERT_GT(4 + DATA_LEN, eventData - original); // must be truncated - } + if (memcmp(payload, eventData, dataLen)) { + continue; + } - ++count; + if (DATA_LEN >= 512) { + eventData += dataLen; + // 4 bytes for the tag, and max_payload_buf should be truncated. + ASSERT_LE(4 + 512, eventData - original); // worst expectations + ASSERT_GT(4 + DATA_LEN, eventData - original); // must be truncated } - android_logger_list_close(logger_list); + ++count; + } + + android_logger_list_close(logger_list); } #endif TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) { #ifdef TEST_PREFIX - int count; - android_errorWriteWithInfoLog_helper( - 123456781, - "test-subtag", - -1, - max_payload_buf, - 200, - count); - EXPECT_EQ(SUPPORTS_END_TO_END, count); + int count; + android_errorWriteWithInfoLog_helper(123456781, "test-subtag", -1, + max_payload_buf, 200, count); + EXPECT_EQ(SUPPORTS_END_TO_END, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) { +TEST(liblog, + android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) { #ifdef TEST_PREFIX - int count; - android_errorWriteWithInfoLog_helper( - 123456782, - "test-subtag", - -1, - max_payload_buf, - sizeof(max_payload_buf), - count); - EXPECT_EQ(SUPPORTS_END_TO_END, count); + int count; + android_errorWriteWithInfoLog_helper(123456782, "test-subtag", -1, + max_payload_buf, sizeof(max_payload_buf), + count); + EXPECT_EQ(SUPPORTS_END_TO_END, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__null_data) { +TEST(liblog, + android_errorWriteWithInfoLog__android_logger_list_read__null_data) { #ifdef TEST_PREFIX - int count; - android_errorWriteWithInfoLog_helper( - 123456783, - "test-subtag", - -1, - NULL, - 200, - count); - EXPECT_EQ(0, count); + int count; + android_errorWriteWithInfoLog_helper(123456783, "test-subtag", -1, NULL, 200, + count); + EXPECT_EQ(0, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) { +TEST(liblog, + android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) { #ifdef TEST_PREFIX - int count; - android_errorWriteWithInfoLog_helper( - 123456784, - "abcdefghijklmnopqrstuvwxyz now i know my abc", - -1, - max_payload_buf, - 200, - count); - EXPECT_EQ(SUPPORTS_END_TO_END, count); + int count; + android_errorWriteWithInfoLog_helper( + 123456784, "abcdefghijklmnopqrstuvwxyz now i know my abc", -1, + max_payload_buf, 200, count); + EXPECT_EQ(SUPPORTS_END_TO_END, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, __android_log_bswrite_and_print___max) { - bswrite_test(max_payload_buf); + bswrite_test(max_payload_buf); } TEST(liblog, __android_log_buf_write_and_print__max) { - buf_write_test(max_payload_buf); + buf_write_test(max_payload_buf); } #ifdef TEST_PREFIX -static void android_errorWriteLog_helper(int TAG, const char *SUBTAG, int& count) { - TEST_PREFIX - struct logger_list *logger_list; +static void android_errorWriteLog_helper(int TAG, const char* SUBTAG, + int& count) { + TEST_PREFIX + struct logger_list* logger_list; - pid_t pid = getpid(); + pid_t pid = getpid(); - count = 0; + count = 0; - // Do a Before and After on the count to measure the effect. Decrement - // what we find in Before to set the stage. - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + // Do a Before and After on the count to measure the effect. Decrement + // what we find in Before to set the stage. + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); - 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; - char *eventData = log_msg.msg(); - if (!eventData) continue; + char* eventData = log_msg.msg(); + if (!eventData) continue; - // Tag - int tag = get4LE(eventData); - eventData += 4; + // Tag + int tag = get4LE(eventData); + eventData += 4; - if (tag != TAG) continue; + if (tag != TAG) continue; - if (!SUBTAG) { - // This tag should not have been written because the data was null - --count; - break; - } + if (!SUBTAG) { + // This tag should not have been written because the data was null + --count; + break; + } - // List type - eventData++; - // Number of elements in list - eventData++; - // Element #1: string type for subtag - eventData++; + // List type + eventData++; + // Number of elements in list + eventData++; + // Element #1: string type for subtag + eventData++; - eventData +=4; + eventData += 4; - if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) continue; - --count; - } + if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) continue; + --count; + } - android_logger_list_close(logger_list); + android_logger_list_close(logger_list); - // Do an After on the count to measure the effect. - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + // Do an After on the count to measure the effect. + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); - int retval_android_errorWriteLog = android_errorWriteLog(TAG, SUBTAG); - if (SUBTAG) { - ASSERT_LT(0, retval_android_errorWriteLog); - } else { - ASSERT_GT(0, retval_android_errorWriteLog); - } + int retval_android_errorWriteLog = android_errorWriteLog(TAG, SUBTAG); + if (SUBTAG) { + ASSERT_LT(0, retval_android_errorWriteLog); + } else { + ASSERT_GT(0, retval_android_errorWriteLog); + } - sleep(2); + sleep(2); - 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; + } - char *eventData = log_msg.msg(); - if (!eventData) { - continue; - } + char* eventData = log_msg.msg(); + if (!eventData) { + continue; + } - // Tag - int tag = get4LE(eventData); - eventData += 4; + // Tag + int tag = get4LE(eventData); + eventData += 4; - if (tag != TAG) { - continue; - } + if (tag != TAG) { + continue; + } - if (!SUBTAG) { - // This tag should not have been written because the data was null - ++count; - break; - } + if (!SUBTAG) { + // This tag should not have been written because the data was null + ++count; + break; + } - // List type - ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]); - eventData++; + // List type + ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]); + eventData++; - // Number of elements in list - ASSERT_EQ(3, eventData[0]); - eventData++; + // Number of elements in list + ASSERT_EQ(3, eventData[0]); + eventData++; - // Element #1: string type for subtag - ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]); - eventData++; + // Element #1: string type for subtag + ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]); + eventData++; - ASSERT_EQ(strlen(SUBTAG), get4LE(eventData)); - eventData +=4; + ASSERT_EQ(strlen(SUBTAG), get4LE(eventData)); + eventData += 4; - if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) { - continue; - } - ++count; + if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) { + continue; } + ++count; + } - android_logger_list_close(logger_list); + android_logger_list_close(logger_list); } #endif TEST(liblog, android_errorWriteLog__android_logger_list_read__success) { #ifdef TEST_PREFIX - int count; - android_errorWriteLog_helper(123456785, "test-subtag", count); - EXPECT_EQ(SUPPORTS_END_TO_END, count); + int count; + android_errorWriteLog_helper(123456785, "test-subtag", count); + EXPECT_EQ(SUPPORTS_END_TO_END, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) { #ifdef TEST_PREFIX - int count; - android_errorWriteLog_helper(123456786, NULL, count); - EXPECT_EQ(0, count); + int count; + android_errorWriteLog_helper(123456786, NULL, count); + EXPECT_EQ(0, count); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } // Do not retest logger list handling #if (defined(TEST_PREFIX) || !defined(USING_LOGGER_LOCAL)) static int is_real_element(int type) { - return ((type == EVENT_TYPE_INT) || - (type == EVENT_TYPE_LONG) || - (type == EVENT_TYPE_STRING) || - (type == EVENT_TYPE_FLOAT)); + return ((type == EVENT_TYPE_INT) || (type == EVENT_TYPE_LONG) || + (type == EVENT_TYPE_STRING) || (type == EVENT_TYPE_FLOAT)); } -static int android_log_buffer_to_string(const char *msg, size_t len, - char *strOut, size_t strOutLen) { - android_log_context context = create_android_log_parser(msg, len); - android_log_list_element elem; - bool overflow = false; - /* Reserve 1 byte for null terminator. */ - size_t origStrOutLen = strOutLen--; +static int android_log_buffer_to_string(const char* msg, size_t len, + char* strOut, size_t strOutLen) { + android_log_context context = create_android_log_parser(msg, len); + android_log_list_element elem; + bool overflow = false; + /* Reserve 1 byte for null terminator. */ + size_t origStrOutLen = strOutLen--; - if (!context) { - return -EBADF; - } + if (!context) { + return -EBADF; + } - memset(&elem, 0, sizeof(elem)); + memset(&elem, 0, sizeof(elem)); - size_t outCount; + size_t outCount; - do { - elem = android_log_read_next(context); - switch ((int)elem.type) { - case EVENT_TYPE_LIST: - if (strOutLen == 0) { - overflow = true; - } else { - *strOut++ = '['; - strOutLen--; - } - break; - - case EVENT_TYPE_LIST_STOP: - if (strOutLen == 0) { - overflow = true; - } else { - *strOut++ = ']'; - strOutLen--; - } - break; - - case EVENT_TYPE_INT: - /* - * snprintf also requires room for the null terminator, which - * we don't care about but we have allocated enough room for - * that - */ - outCount = snprintf(strOut, strOutLen + 1, - "%" PRId32, elem.data.int32); - if (outCount <= strOutLen) { - strOut += outCount; - strOutLen -= outCount; - } else { - overflow = true; - } - break; - - case EVENT_TYPE_LONG: - /* - * snprintf also requires room for the null terminator, which - * we don't care about but we have allocated enough room for - * that - */ - outCount = snprintf(strOut, strOutLen + 1, - "%" PRId64, elem.data.int64); - if (outCount <= strOutLen) { - strOut += outCount; - strOutLen -= outCount; - } else { - overflow = true; - } - break; - - case EVENT_TYPE_FLOAT: - /* - * snprintf also requires room for the null terminator, which - * we don't care about but we have allocated enough room for - * that - */ - outCount = snprintf(strOut, strOutLen + 1, "%f", elem.data.float32); - if (outCount <= strOutLen) { - strOut += outCount; - strOutLen -= outCount; - } else { - overflow = true; - } - break; + do { + elem = android_log_read_next(context); + switch ((int)elem.type) { + case EVENT_TYPE_LIST: + if (strOutLen == 0) { + overflow = true; + } else { + *strOut++ = '['; + strOutLen--; + } + break; + + case EVENT_TYPE_LIST_STOP: + if (strOutLen == 0) { + overflow = true; + } else { + *strOut++ = ']'; + strOutLen--; + } + break; + + case EVENT_TYPE_INT: + /* + * snprintf also requires room for the null terminator, which + * we don't care about but we have allocated enough room for + * that + */ + outCount = snprintf(strOut, strOutLen + 1, "%" PRId32, elem.data.int32); + if (outCount <= strOutLen) { + strOut += outCount; + strOutLen -= outCount; + } else { + overflow = true; + } + break; + + case EVENT_TYPE_LONG: + /* + * snprintf also requires room for the null terminator, which + * we don't care about but we have allocated enough room for + * that + */ + outCount = snprintf(strOut, strOutLen + 1, "%" PRId64, elem.data.int64); + if (outCount <= strOutLen) { + strOut += outCount; + strOutLen -= outCount; + } else { + overflow = true; + } + break; + + case EVENT_TYPE_FLOAT: + /* + * snprintf also requires room for the null terminator, which + * we don't care about but we have allocated enough room for + * that + */ + outCount = snprintf(strOut, strOutLen + 1, "%f", elem.data.float32); + if (outCount <= strOutLen) { + strOut += outCount; + strOutLen -= outCount; + } else { + overflow = true; + } + break; - default: - elem.complete = true; - break; + default: + elem.complete = true; + break; - case EVENT_TYPE_UNKNOWN: -#if 0 // Ideal purity in the test, we want to complain about UNKNOWN showing up + case EVENT_TYPE_UNKNOWN: +#if 0 // Ideal purity in the test, we want to complain about UNKNOWN showing up if (elem.complete) { break; } #endif - elem.data.string = const_cast<char *>("<unknown>"); - elem.len = strlen(elem.data.string); - /* FALLTHRU */ - case EVENT_TYPE_STRING: - if (elem.len <= strOutLen) { - memcpy(strOut, elem.data.string, elem.len); - strOut += elem.len; - strOutLen -= elem.len; - } else if (strOutLen > 0) { - /* copy what we can */ - memcpy(strOut, elem.data.string, strOutLen); - strOut += strOutLen; - strOutLen = 0; - overflow = true; - } - break; - } - - if (elem.complete) { - break; - } - /* Determine whether to put a comma or not. */ - if (!overflow && (is_real_element(elem.type) || - (elem.type == EVENT_TYPE_LIST_STOP))) { - android_log_list_element next = android_log_peek_next(context); - if (!next.complete && (is_real_element(next.type) || - (next.type == EVENT_TYPE_LIST))) { - if (strOutLen == 0) { - overflow = true; - } else { - *strOut++ = ','; - strOutLen--; - } - } - } - } while ((elem.type != EVENT_TYPE_UNKNOWN) && !overflow && !elem.complete); - - android_log_destroy(&context); - - if (overflow) { - if (strOutLen < origStrOutLen) { - /* leave an indicator */ - *(strOut-1) = '!'; + elem.data.string = const_cast<char*>("<unknown>"); + elem.len = strlen(elem.data.string); + /* FALLTHRU */ + case EVENT_TYPE_STRING: + if (elem.len <= strOutLen) { + memcpy(strOut, elem.data.string, elem.len); + strOut += elem.len; + strOutLen -= elem.len; + } else if (strOutLen > 0) { + /* copy what we can */ + memcpy(strOut, elem.data.string, strOutLen); + strOut += strOutLen; + strOutLen = 0; + overflow = true; + } + break; + } + + if (elem.complete) { + break; + } + /* Determine whether to put a comma or not. */ + if (!overflow && + (is_real_element(elem.type) || (elem.type == EVENT_TYPE_LIST_STOP))) { + android_log_list_element next = android_log_peek_next(context); + if (!next.complete && + (is_real_element(next.type) || (next.type == EVENT_TYPE_LIST))) { + if (strOutLen == 0) { + overflow = true; } else { - /* nothing was written at all */ - *strOut++ = '!'; + *strOut++ = ','; + strOutLen--; } + } } - *strOut++ = '\0'; - - if ((elem.type == EVENT_TYPE_UNKNOWN) && !elem.complete) { - fprintf(stderr, "Binary log entry conversion failed\n"); - return -EINVAL; - } - - return 0; -} -#endif // TEST_PREFIX || !USING_LOGGER_LOCAL - -#ifdef TEST_PREFIX -static const char *event_test_int32(uint32_t tag, size_t &expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint32_t); - - return "1076895760"; -} - -static const char *event_test_int64(uint32_t tag, size_t &expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint64_t); + } while ((elem.type != EVENT_TYPE_UNKNOWN) && !overflow && !elem.complete); - return "-9191740941672636400"; -} - -static const char *event_test_list_int64(uint32_t tag, size_t &expected_len) { - android_log_context ctx; + android_log_destroy(&context); - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; + if (overflow) { + if (strOutLen < origStrOutLen) { + /* leave an indicator */ + *(strOut - 1) = '!'; + } else { + /* nothing was written at all */ + *strOut++ = '!'; } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); + } + *strOut++ = '\0'; - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint64_t); + if ((elem.type == EVENT_TYPE_UNKNOWN) && !elem.complete) { + fprintf(stderr, "Binary log entry conversion failed\n"); + return -EINVAL; + } - return "[-9191740941672636400]"; + return 0; } +#endif // TEST_PREFIX || !USING_LOGGER_LOCAL -static const char *event_test_simple_automagic_list(uint32_t tag, size_t &expected_len) { - android_log_context ctx; +#ifdef TEST_PREFIX +static const char* event_test_int32(uint32_t tag, size_t& expected_len) { + android_log_context ctx; - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - // The convenience API where we allow a simple list to be - // created without explicit begin or end calls. - EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010)); - EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010)); + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint64_t); + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t); - return "[1076895760,-9191740941672636400]"; + return "1076895760"; } -static const char *event_test_list_empty(uint32_t tag, size_t &expected_len) { - android_log_context ctx; +static const char* event_test_int64(uint32_t tag, size_t& expected_len) { + android_log_context ctx; - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint8_t); + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint64_t); - return "[]"; + return "-9191740941672636400"; } -static const char *event_test_complex_nested_list(uint32_t tag, size_t &expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - - EXPECT_LE(0, android_log_write_list_begin(ctx)); // [ - EXPECT_LE(0, android_log_write_int32(ctx, 0x01020304)); - EXPECT_LE(0, android_log_write_int64(ctx, 0x0102030405060708)); - EXPECT_LE(0, android_log_write_string8(ctx, "Hello World")); - EXPECT_LE(0, android_log_write_list_begin(ctx)); // [ - EXPECT_LE(0, android_log_write_int32(ctx, 1)); - EXPECT_LE(0, android_log_write_int32(ctx, 2)); - EXPECT_LE(0, android_log_write_int32(ctx, 3)); - EXPECT_LE(0, android_log_write_int32(ctx, 4)); - EXPECT_LE(0, android_log_write_list_end(ctx)); // ] - EXPECT_LE(0, android_log_write_float32(ctx, 1.0102030405060708)); - EXPECT_LE(0, android_log_write_list_end(ctx)); // ] - - // - // This one checks for the automagic list creation because a list - // begin and end was missing for it! This is actually an <oops> corner - // case, and not the behavior we morally support. The automagic API is to - // allow for a simple case of a series of objects in a single list. e.g. - // int32,int32,int32,string -> [int32,int32,int32,string] - // - EXPECT_LE(0, android_log_write_string8(ctx, "dlroW olleH")); +static const char* event_test_list_int64(uint32_t tag, size_t& expected_len) { + android_log_context ctx; - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint64_t) + - sizeof(uint8_t) + sizeof(uint32_t) + - sizeof("Hello World") - 1 + - sizeof(uint8_t) + sizeof(uint8_t) + - 4 * (sizeof(uint8_t) + sizeof(uint32_t)) + - sizeof(uint8_t) + sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint32_t) + - sizeof("dlroW olleH") - 1; + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint8_t) + sizeof(uint64_t); - return "[[16909060,72623859790382856,Hello World,[1,2,3,4],1.010203],dlroW olleH]"; + return "[-9191740941672636400]"; } -static const char *event_test_7_level_prefix(uint32_t tag, size_t &expected_len) { - android_log_context ctx; +static const char* event_test_simple_automagic_list(uint32_t tag, + size_t& expected_len) { + android_log_context ctx; - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 1)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 2)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 3)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 4)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 5)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 6)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 7)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + // The convenience API where we allow a simple list to be + // created without explicit begin or end calls. + EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010)); + EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010)); + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); - expected_len = sizeof(uint32_t) + 7 * - (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t)); + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) + + sizeof(uint64_t); - return "[[[[[[[1],2],3],4],5],6],7]"; + return "[1076895760,-9191740941672636400]"; } -static const char *event_test_7_level_suffix(uint32_t tag, size_t &expected_len) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); - if (!ctx) { - return NULL; - } - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 1)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 2)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 3)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 4)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 5)); - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, 6)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list_end(ctx)); - EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - - expected_len = sizeof(uint32_t) + 6 * - (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t)); +static const char* event_test_list_empty(uint32_t tag, size_t& expected_len) { + android_log_context ctx; - return "[1,[2,[3,[4,[5,[6]]]]]]"; -} - -static const char *event_test_android_log_error_write(uint32_t tag, size_t &expected_len) { - EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11)); + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 + - sizeof(uint8_t) + sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof("dlroW olleH") - 1; + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t); - return "[Hello World,42,dlroW olleH]"; + return "[]"; } -static const char *event_test_android_log_error_write_null(uint32_t tag, size_t &expected_len) { - EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0)); +static const char* event_test_complex_nested_list(uint32_t tag, + size_t& expected_len) { + android_log_context ctx; - expected_len = sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint8_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 + - sizeof(uint8_t) + sizeof(uint32_t) + - sizeof(uint8_t) + sizeof(uint32_t) + sizeof("") - 1; - - return "[Hello World,42,]"; + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + + EXPECT_LE(0, android_log_write_list_begin(ctx)); // [ + EXPECT_LE(0, android_log_write_int32(ctx, 0x01020304)); + EXPECT_LE(0, android_log_write_int64(ctx, 0x0102030405060708)); + EXPECT_LE(0, android_log_write_string8(ctx, "Hello World")); + EXPECT_LE(0, android_log_write_list_begin(ctx)); // [ + EXPECT_LE(0, android_log_write_int32(ctx, 1)); + EXPECT_LE(0, android_log_write_int32(ctx, 2)); + EXPECT_LE(0, android_log_write_int32(ctx, 3)); + EXPECT_LE(0, android_log_write_int32(ctx, 4)); + EXPECT_LE(0, android_log_write_list_end(ctx)); // ] + EXPECT_LE(0, android_log_write_float32(ctx, 1.0102030405060708)); + EXPECT_LE(0, android_log_write_list_end(ctx)); // ] + + // + // This one checks for the automagic list creation because a list + // begin and end was missing for it! This is actually an <oops> corner + // case, and not the behavior we morally support. The automagic API is to + // allow for a simple case of a series of objects in a single list. e.g. + // int32,int32,int32,string -> [int32,int32,int32,string] + // + EXPECT_LE(0, android_log_write_string8(ctx, "dlroW olleH")); + + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); + + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint64_t) + + sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - + 1 + sizeof(uint8_t) + sizeof(uint8_t) + + 4 * (sizeof(uint8_t) + sizeof(uint32_t)) + sizeof(uint8_t) + + sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t) + + sizeof("dlroW olleH") - 1; + + return "[[16909060,72623859790382856,Hello World,[1,2,3,4],1.010203],dlroW " + "olleH]"; +} + +static const char* event_test_7_level_prefix(uint32_t tag, + size_t& expected_len) { + android_log_context ctx; + + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 1)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 2)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 3)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 4)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 5)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 6)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 7)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); + + expected_len = sizeof(uint32_t) + 7 * (sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint8_t) + sizeof(uint32_t)); + + return "[[[[[[[1],2],3],4],5],6],7]"; +} + +static const char* event_test_7_level_suffix(uint32_t tag, + size_t& expected_len) { + android_log_context ctx; + + EXPECT_TRUE(NULL != (ctx = create_android_logger(tag))); + if (!ctx) { + return NULL; + } + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 1)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 2)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 3)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 4)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 5)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, 6)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list_end(ctx)); + EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS)); + EXPECT_LE(0, android_log_destroy(&ctx)); + EXPECT_TRUE(NULL == ctx); + + expected_len = sizeof(uint32_t) + 6 * (sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint8_t) + sizeof(uint32_t)); + + return "[1,[2,[3,[4,[5,[6]]]]]]"; +} + +static const char* event_test_android_log_error_write(uint32_t tag, + size_t& expected_len) { + EXPECT_LE( + 0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11)); + + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - + 1 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) + + sizeof(uint32_t) + sizeof("dlroW olleH") - 1; + + return "[Hello World,42,dlroW olleH]"; +} + +static const char* event_test_android_log_error_write_null(uint32_t tag, + size_t& expected_len) { + EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0)); + + expected_len = sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint8_t) + + sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - + 1 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t) + + sizeof(uint32_t) + sizeof("") - 1; + + return "[Hello World,42,]"; } // make sure all user buffers are flushed static void print_barrier() { - std::cout.flush(); - fflush(stdout); - std::cerr.flush(); - fflush(stderr); // everything else is paranoia ... + std::cout.flush(); + fflush(stdout); + std::cerr.flush(); + fflush(stderr); // everything else is paranoia ... } -static void create_android_logger(const char *(*fn)(uint32_t tag, size_t &expected_len)) { - TEST_PREFIX - struct logger_list *logger_list; +static void create_android_logger(const char* (*fn)(uint32_t tag, + size_t& expected_len)) { + TEST_PREFIX + struct logger_list* logger_list; - pid_t pid = getpid(); + pid_t pid = getpid(); - ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( - LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); + ASSERT_TRUE(NULL != + (logger_list = android_logger_list_open( + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, + 1000, pid))); #ifdef __ANDROID__ - log_time ts(android_log_clockid()); + log_time ts(android_log_clockid()); #else - log_time ts(CLOCK_REALTIME); + log_time ts(CLOCK_REALTIME); #endif - size_t expected_len; - const char *expected_string = (*fn)(1005, expected_len); - - if (!expected_string) { - android_logger_list_close(logger_list); - return; - } + size_t expected_len; + const char* expected_string = (*fn)(1005, expected_len); - usleep(1000000); + if (!expected_string) { + android_logger_list_close(logger_list); + return; + } - int count = 0; + usleep(1000000); - for (;;) { - log_msg log_msg; - if (android_logger_list_read(logger_list, &log_msg) <= 0) { - break; - } + int count = 0; - ASSERT_EQ(log_msg.entry.pid, pid); + for (;;) { + log_msg log_msg; + if (android_logger_list_read(logger_list, &log_msg) <= 0) { + break; + } - if ((log_msg.entry.sec < (ts.tv_sec - 1)) - || ((ts.tv_sec + 1) < log_msg.entry.sec) - || ((size_t)log_msg.entry.len != expected_len) - || (log_msg.id() != LOG_ID_EVENTS)) { - continue; - } + ASSERT_EQ(log_msg.entry.pid, pid); - char *eventData = log_msg.msg(); - - ++count; - - AndroidLogFormat *logformat = android_log_format_new(); - EXPECT_TRUE(NULL != logformat); - AndroidLogEntry entry; - char msgBuf[1024]; - int processBinaryLogBuffer = android_log_processBinaryLogBuffer( - &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf)); - EXPECT_EQ(0, processBinaryLogBuffer); - if (processBinaryLogBuffer == 0) { - int line_overhead = 20; - if (pid > 99999) ++line_overhead; - if (pid > 999999) ++line_overhead; - print_barrier(); - int printLogLine = android_log_printLogLine( - logformat, fileno(stderr), &entry); - print_barrier(); - EXPECT_EQ(line_overhead + (int)strlen(expected_string), - printLogLine); - } - android_log_format_free(logformat); - - // test buffer reading API - int buffer_to_string = -1; - if (eventData) { - snprintf(msgBuf, sizeof(msgBuf), - "I/[%" PRIu32 "]", get4LE(eventData)); - print_barrier(); - fprintf(stderr, "%-10s(%5u): ", msgBuf, pid); - memset(msgBuf, 0, sizeof(msgBuf)); - buffer_to_string = android_log_buffer_to_string( - eventData + sizeof(uint32_t), - log_msg.entry.len - sizeof(uint32_t), - msgBuf, sizeof(msgBuf)); - fprintf(stderr, "%s\n", msgBuf); - print_barrier(); - } - EXPECT_EQ(0, buffer_to_string); - EXPECT_EQ(strlen(expected_string), strlen(msgBuf)); - EXPECT_EQ(0, strcmp(expected_string, msgBuf)); + if ((log_msg.entry.sec < (ts.tv_sec - 1)) || + ((ts.tv_sec + 1) < log_msg.entry.sec) || + ((size_t)log_msg.entry.len != expected_len) || + (log_msg.id() != LOG_ID_EVENTS)) { + continue; } - EXPECT_EQ(SUPPORTS_END_TO_END, count); + char* eventData = log_msg.msg(); - android_logger_list_close(logger_list); + ++count; + + AndroidLogFormat* logformat = android_log_format_new(); + EXPECT_TRUE(NULL != logformat); + AndroidLogEntry entry; + char msgBuf[1024]; + int processBinaryLogBuffer = android_log_processBinaryLogBuffer( + &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf)); + EXPECT_EQ(0, processBinaryLogBuffer); + if (processBinaryLogBuffer == 0) { + int line_overhead = 20; + if (pid > 99999) ++line_overhead; + if (pid > 999999) ++line_overhead; + print_barrier(); + int printLogLine = + android_log_printLogLine(logformat, fileno(stderr), &entry); + print_barrier(); + EXPECT_EQ(line_overhead + (int)strlen(expected_string), printLogLine); + } + android_log_format_free(logformat); + + // test buffer reading API + int buffer_to_string = -1; + if (eventData) { + snprintf(msgBuf, sizeof(msgBuf), "I/[%" PRIu32 "]", get4LE(eventData)); + print_barrier(); + fprintf(stderr, "%-10s(%5u): ", msgBuf, pid); + memset(msgBuf, 0, sizeof(msgBuf)); + buffer_to_string = android_log_buffer_to_string( + eventData + sizeof(uint32_t), log_msg.entry.len - sizeof(uint32_t), + msgBuf, sizeof(msgBuf)); + fprintf(stderr, "%s\n", msgBuf); + print_barrier(); + } + EXPECT_EQ(0, buffer_to_string); + EXPECT_EQ(strlen(expected_string), strlen(msgBuf)); + EXPECT_EQ(0, strcmp(expected_string, msgBuf)); + } + + EXPECT_EQ(SUPPORTS_END_TO_END, count); + + android_logger_list_close(logger_list); } #endif TEST(liblog, create_android_logger_int32) { #ifdef TEST_PREFIX - create_android_logger(event_test_int32); + create_android_logger(event_test_int32); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_int64) { #ifdef TEST_PREFIX - create_android_logger(event_test_int64); + create_android_logger(event_test_int64); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_list_int64) { #ifdef TEST_PREFIX - create_android_logger(event_test_list_int64); + create_android_logger(event_test_list_int64); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_simple_automagic_list) { #ifdef TEST_PREFIX - create_android_logger(event_test_simple_automagic_list); + create_android_logger(event_test_simple_automagic_list); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_list_empty) { #ifdef TEST_PREFIX - create_android_logger(event_test_list_empty); + create_android_logger(event_test_list_empty); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_complex_nested_list) { #ifdef TEST_PREFIX - create_android_logger(event_test_complex_nested_list); + create_android_logger(event_test_complex_nested_list); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_7_level_prefix) { #ifdef TEST_PREFIX - create_android_logger(event_test_7_level_prefix); + create_android_logger(event_test_7_level_prefix); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_7_level_suffix) { #ifdef TEST_PREFIX - create_android_logger(event_test_7_level_suffix); + create_android_logger(event_test_7_level_suffix); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_android_log_error_write) { #ifdef TEST_PREFIX - create_android_logger(event_test_android_log_error_write); + create_android_logger(event_test_android_log_error_write); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } TEST(liblog, create_android_logger_android_log_error_write_null) { #ifdef TEST_PREFIX - create_android_logger(event_test_android_log_error_write_null); + create_android_logger(event_test_android_log_error_write_null); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#ifdef USING_LOGGER_DEFAULT // Do not retest logger list handling +#ifdef USING_LOGGER_DEFAULT // Do not retest logger list handling TEST(liblog, create_android_logger_overflow) { - android_log_context ctx; - - EXPECT_TRUE(NULL != (ctx = create_android_logger(1005))); - if (ctx) { - for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) { - EXPECT_LE(0, android_log_write_list_begin(ctx)); - } - EXPECT_GT(0, android_log_write_list_begin(ctx)); - /* One more for good measure, must be permanently unhappy */ - EXPECT_GT(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_destroy(&ctx)); - EXPECT_TRUE(NULL == ctx); - } + android_log_context ctx; - ASSERT_TRUE(NULL != (ctx = create_android_logger(1005))); + EXPECT_TRUE(NULL != (ctx = create_android_logger(1005))); + if (ctx) { for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) { - EXPECT_LE(0, android_log_write_list_begin(ctx)); - EXPECT_LE(0, android_log_write_int32(ctx, i)); + EXPECT_LE(0, android_log_write_list_begin(ctx)); } EXPECT_GT(0, android_log_write_list_begin(ctx)); /* One more for good measure, must be permanently unhappy */ EXPECT_GT(0, android_log_write_list_begin(ctx)); EXPECT_LE(0, android_log_destroy(&ctx)); - ASSERT_TRUE(NULL == ctx); -} - -TEST(liblog, android_log_write_list_buffer) { - __android_log_event_list ctx(1005); - ctx << 1005 << "tag_def" << "(tag|1),(name|3),(format|3)"; - std::string buffer(ctx); - ctx.close(); + EXPECT_TRUE(NULL == ctx); + } - char msgBuf[1024]; - memset(msgBuf, 0, sizeof(msgBuf)); - EXPECT_EQ(android_log_buffer_to_string(buffer.data(), buffer.length(), - msgBuf, sizeof(msgBuf)), 0); - EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]"); + ASSERT_TRUE(NULL != (ctx = create_android_logger(1005))); + for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) { + EXPECT_LE(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_write_int32(ctx, i)); + } + EXPECT_GT(0, android_log_write_list_begin(ctx)); + /* One more for good measure, must be permanently unhappy */ + EXPECT_GT(0, android_log_write_list_begin(ctx)); + EXPECT_LE(0, android_log_destroy(&ctx)); + ASSERT_TRUE(NULL == ctx); } -#endif // USING_LOGGER_DEFAULT -#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality +TEST(liblog, android_log_write_list_buffer) { + __android_log_event_list ctx(1005); + ctx << 1005 << "tag_def" + << "(tag|1),(name|3),(format|3)"; + std::string buffer(ctx); + ctx.close(); + + char msgBuf[1024]; + memset(msgBuf, 0, sizeof(msgBuf)); + EXPECT_EQ(android_log_buffer_to_string(buffer.data(), buffer.length(), msgBuf, + sizeof(msgBuf)), + 0); + EXPECT_STREQ(msgBuf, "[1005,tag_def,(tag|1),(name|3),(format|3)]"); +} +#endif // USING_LOGGER_DEFAULT + +#ifdef USING_LOGGER_DEFAULT // Do not retest pmsg functionality #ifdef __ANDROID__ static const char __pmsg_file[] = - "/data/william-shakespeare/MuchAdoAboutNothing.txt"; + "/data/william-shakespeare/MuchAdoAboutNothing.txt"; #endif TEST(liblog, __android_log_pmsg_file_write) { #ifdef __ANDROID__ - __android_log_close(); - if (getuid() == AID_ROOT) { - tested__android_log_close = true; - bool pmsgActiveAfter__android_log_close = isPmsgActive(); - bool logdwActiveAfter__android_log_close = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_close); - EXPECT_FALSE(logdwActiveAfter__android_log_close); - } else if (!tested__android_log_close) { - fprintf(stderr, "WARNING: can not test __android_log_close()\n"); - } - int return__android_log_pmsg_file_write = __android_log_pmsg_file_write( - LOG_ID_CRASH, ANDROID_LOG_VERBOSE, - __pmsg_file, max_payload_buf, sizeof(max_payload_buf)); - EXPECT_LT(0, return__android_log_pmsg_file_write); - if (return__android_log_pmsg_file_write == -ENOMEM) { - fprintf(stderr, - "Kernel does not have space allocated to pmsg pstore driver configured\n" - ); - } else if (!return__android_log_pmsg_file_write) { - fprintf(stderr, "Reboot, ensure file %s matches\n" - "with liblog.__android_log_msg_file_read test\n", - __pmsg_file); - } - bool pmsgActiveAfter__android_pmsg_file_write; - bool logdwActiveAfter__android_pmsg_file_write; - if (getuid() == AID_ROOT) { - pmsgActiveAfter__android_pmsg_file_write = isPmsgActive(); - logdwActiveAfter__android_pmsg_file_write = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_pmsg_file_write); - EXPECT_FALSE(logdwActiveAfter__android_pmsg_file_write); - } - EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, - "TEST__android_log_pmsg_file_write", - "main")); - if (getuid() == AID_ROOT) { - bool pmsgActiveAfter__android_log_buf_print = isPmsgActive(); - bool logdwActiveAfter__android_log_buf_print = isLogdwActive(); - EXPECT_TRUE(pmsgActiveAfter__android_log_buf_print); - EXPECT_TRUE(logdwActiveAfter__android_log_buf_print); - } - EXPECT_LT(0, __android_log_pmsg_file_write( - LOG_ID_CRASH, ANDROID_LOG_VERBOSE, - __pmsg_file, max_payload_buf, sizeof(max_payload_buf))); - if (getuid() == AID_ROOT) { - pmsgActiveAfter__android_pmsg_file_write = isPmsgActive(); - logdwActiveAfter__android_pmsg_file_write = isLogdwActive(); - EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write); - EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write); - } + __android_log_close(); + if (getuid() == AID_ROOT) { + tested__android_log_close = true; + bool pmsgActiveAfter__android_log_close = isPmsgActive(); + bool logdwActiveAfter__android_log_close = isLogdwActive(); + EXPECT_FALSE(pmsgActiveAfter__android_log_close); + EXPECT_FALSE(logdwActiveAfter__android_log_close); + } else if (!tested__android_log_close) { + fprintf(stderr, "WARNING: can not test __android_log_close()\n"); + } + int return__android_log_pmsg_file_write = __android_log_pmsg_file_write( + LOG_ID_CRASH, ANDROID_LOG_VERBOSE, __pmsg_file, max_payload_buf, + sizeof(max_payload_buf)); + EXPECT_LT(0, return__android_log_pmsg_file_write); + if (return__android_log_pmsg_file_write == -ENOMEM) { + fprintf(stderr, + "Kernel does not have space allocated to pmsg pstore driver " + "configured\n"); + } else if (!return__android_log_pmsg_file_write) { + fprintf(stderr, + "Reboot, ensure file %s matches\n" + "with liblog.__android_log_msg_file_read test\n", + __pmsg_file); + } + bool pmsgActiveAfter__android_pmsg_file_write; + bool logdwActiveAfter__android_pmsg_file_write; + if (getuid() == AID_ROOT) { + pmsgActiveAfter__android_pmsg_file_write = isPmsgActive(); + logdwActiveAfter__android_pmsg_file_write = isLogdwActive(); + EXPECT_FALSE(pmsgActiveAfter__android_pmsg_file_write); + EXPECT_FALSE(logdwActiveAfter__android_pmsg_file_write); + } + EXPECT_LT( + 0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, + "TEST__android_log_pmsg_file_write", "main")); + if (getuid() == AID_ROOT) { + bool pmsgActiveAfter__android_log_buf_print = isPmsgActive(); + bool logdwActiveAfter__android_log_buf_print = isLogdwActive(); + EXPECT_TRUE(pmsgActiveAfter__android_log_buf_print); + EXPECT_TRUE(logdwActiveAfter__android_log_buf_print); + } + EXPECT_LT(0, __android_log_pmsg_file_write(LOG_ID_CRASH, ANDROID_LOG_VERBOSE, + __pmsg_file, max_payload_buf, + sizeof(max_payload_buf))); + if (getuid() == AID_ROOT) { + pmsgActiveAfter__android_pmsg_file_write = isPmsgActive(); + logdwActiveAfter__android_pmsg_file_write = isLogdwActive(); + EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write); + EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write); + } #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } #ifdef __ANDROID__ -static ssize_t __pmsg_fn(log_id_t logId, char prio, const char *filename, - const char *buf, size_t len, void *arg) { - EXPECT_TRUE(NULL == arg); - EXPECT_EQ(LOG_ID_CRASH, logId); - EXPECT_EQ(ANDROID_LOG_VERBOSE, prio); - EXPECT_FALSE(NULL == strstr(__pmsg_file, filename)); - EXPECT_EQ(len, sizeof(max_payload_buf)); - EXPECT_EQ(0, strcmp(max_payload_buf, buf)); - - ++signaled; - if ((len != sizeof(max_payload_buf)) || - strcmp(max_payload_buf, buf)) { - fprintf(stderr, "comparison fails on content \"%s\"\n", buf); - } - return arg || - (LOG_ID_CRASH != logId) || - (ANDROID_LOG_VERBOSE != prio) || - !strstr(__pmsg_file, filename) || - (len != sizeof(max_payload_buf)) || - !!strcmp(max_payload_buf, buf) ? -ENOEXEC : 1; +static ssize_t __pmsg_fn(log_id_t logId, char prio, const char* filename, + const char* buf, size_t len, void* arg) { + EXPECT_TRUE(NULL == arg); + EXPECT_EQ(LOG_ID_CRASH, logId); + EXPECT_EQ(ANDROID_LOG_VERBOSE, prio); + EXPECT_FALSE(NULL == strstr(__pmsg_file, filename)); + EXPECT_EQ(len, sizeof(max_payload_buf)); + EXPECT_EQ(0, strcmp(max_payload_buf, buf)); + + ++signaled; + if ((len != sizeof(max_payload_buf)) || strcmp(max_payload_buf, buf)) { + fprintf(stderr, "comparison fails on content \"%s\"\n", buf); + } + return arg || (LOG_ID_CRASH != logId) || (ANDROID_LOG_VERBOSE != prio) || + !strstr(__pmsg_file, filename) || + (len != sizeof(max_payload_buf)) || + !!strcmp(max_payload_buf, buf) + ? -ENOEXEC + : 1; } #endif TEST(liblog, __android_log_pmsg_file_read) { #ifdef __ANDROID__ - signaled = 0; - - __android_log_close(); - if (getuid() == AID_ROOT) { - tested__android_log_close = true; - bool pmsgActiveAfter__android_log_close = isPmsgActive(); - bool logdwActiveAfter__android_log_close = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_close); - EXPECT_FALSE(logdwActiveAfter__android_log_close); - } else if (!tested__android_log_close) { - fprintf(stderr, "WARNING: can not test __android_log_close()\n"); - } - - ssize_t ret = __android_log_pmsg_file_read( - LOG_ID_CRASH, ANDROID_LOG_VERBOSE, - __pmsg_file, __pmsg_fn, NULL); - - if (getuid() == AID_ROOT) { - bool pmsgActiveAfter__android_log_pmsg_file_read = isPmsgActive(); - bool logdwActiveAfter__android_log_pmsg_file_read = isLogdwActive(); - EXPECT_FALSE(pmsgActiveAfter__android_log_pmsg_file_read); - EXPECT_FALSE(logdwActiveAfter__android_log_pmsg_file_read); - } - - if (ret == -ENOENT) { - fprintf(stderr, + signaled = 0; + + __android_log_close(); + if (getuid() == AID_ROOT) { + tested__android_log_close = true; + bool pmsgActiveAfter__android_log_close = isPmsgActive(); + bool logdwActiveAfter__android_log_close = isLogdwActive(); + EXPECT_FALSE(pmsgActiveAfter__android_log_close); + EXPECT_FALSE(logdwActiveAfter__android_log_close); + } else if (!tested__android_log_close) { + fprintf(stderr, "WARNING: can not test __android_log_close()\n"); + } + + ssize_t ret = __android_log_pmsg_file_read(LOG_ID_CRASH, ANDROID_LOG_VERBOSE, + __pmsg_file, __pmsg_fn, NULL); + + if (getuid() == AID_ROOT) { + bool pmsgActiveAfter__android_log_pmsg_file_read = isPmsgActive(); + bool logdwActiveAfter__android_log_pmsg_file_read = isLogdwActive(); + EXPECT_FALSE(pmsgActiveAfter__android_log_pmsg_file_read); + EXPECT_FALSE(logdwActiveAfter__android_log_pmsg_file_read); + } + + if (ret == -ENOENT) { + fprintf(stderr, "No pre-boot results of liblog.__android_log_mesg_file_write to " "compare with,\n" "false positive test result.\n"); - return; - } + return; + } - EXPECT_LT(0, ret); - EXPECT_EQ(1U, signaled); + EXPECT_LT(0, ret); + EXPECT_EQ(1U, signaled); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#endif // USING_LOGGER_DEFAULT +#endif // USING_LOGGER_DEFAULT -#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality +#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality #ifdef __ANDROID__ // must be: '<needle:> 0 kB' -static bool isZero(const std::string &content, std::string::size_type pos, +static bool isZero(const std::string& content, std::string::size_type pos, const char* needle) { - std::string::size_type offset = content.find(needle, pos); - return (offset != std::string::npos) && - ((offset = content.find_first_not_of(" \t", offset + - strlen(needle))) != std::string::npos) && - (content.find_first_not_of("0", offset) != offset); + std::string::size_type offset = content.find(needle, pos); + return (offset != std::string::npos) && + ((offset = content.find_first_not_of(" \t", offset + strlen(needle))) != + std::string::npos) && + (content.find_first_not_of("0", offset) != offset); } // must not be: '<needle:> 0 kB' -static bool isNotZero(const std::string &content, std::string::size_type pos, +static bool isNotZero(const std::string& content, std::string::size_type pos, const char* needle) { - std::string::size_type offset = content.find(needle, pos); - return (offset != std::string::npos) && - ((offset = content.find_first_not_of(" \t", offset + - strlen(needle))) != std::string::npos) && - (content.find_first_not_of("123456789", offset) != offset); + std::string::size_type offset = content.find(needle, pos); + return (offset != std::string::npos) && + ((offset = content.find_first_not_of(" \t", offset + strlen(needle))) != + std::string::npos) && + (content.find_first_not_of("123456789", offset) != offset); } static void event_log_tags_test_smap(pid_t pid) { - std::string filename = android::base::StringPrintf("/proc/%d/smaps", pid); - - std::string content; - if (!android::base::ReadFileToString(filename, &content)) return; - - bool shared_ok = false; - bool private_ok = false; - bool anonymous_ok = false; - bool pass_ok = false; - - static const char event_log_tags[] = "event-log-tags"; - std::string::size_type pos = 0; - while ((pos = content.find(event_log_tags, pos)) != std::string::npos) { - pos += strlen(event_log_tags); - - // must not be: 'Shared_Clean: 0 kB' - bool ok = isNotZero(content, pos, "Shared_Clean:") || - // If not /etc/event-log-tags, thus r/w, then half points - // back for not 'Shared_Dirty: 0 kB' - ((content.substr(pos - 5 - strlen(event_log_tags), 5) != "/etc/") && - isNotZero(content, pos, "Shared_Dirty:")); - if (ok && !pass_ok) { - shared_ok = true; - } else if (!ok) { - shared_ok = false; - } + std::string filename = android::base::StringPrintf("/proc/%d/smaps", pid); - // must be: 'Private_Dirty: 0 kB' and 'Private_Clean: 0 kB' - ok = isZero(content, pos, "Private_Dirty:") || - isZero(content, pos, "Private_Clean:"); - if (ok && !pass_ok) { - private_ok = true; - } else if (!ok) { - private_ok = false; - } + std::string content; + if (!android::base::ReadFileToString(filename, &content)) return; - // must be: 'Anonymous: 0 kB' - ok = isZero(content, pos, "Anonymous:"); - if (ok && !pass_ok) { - anonymous_ok = true; - } else if (!ok) { - anonymous_ok = false; - } + bool shared_ok = false; + bool private_ok = false; + bool anonymous_ok = false; + bool pass_ok = false; - pass_ok = true; + static const char event_log_tags[] = "event-log-tags"; + std::string::size_type pos = 0; + while ((pos = content.find(event_log_tags, pos)) != std::string::npos) { + pos += strlen(event_log_tags); + + // must not be: 'Shared_Clean: 0 kB' + bool ok = + isNotZero(content, pos, "Shared_Clean:") || + // If not /etc/event-log-tags, thus r/w, then half points + // back for not 'Shared_Dirty: 0 kB' + ((content.substr(pos - 5 - strlen(event_log_tags), 5) != "/etc/") && + isNotZero(content, pos, "Shared_Dirty:")); + if (ok && !pass_ok) { + shared_ok = true; + } else if (!ok) { + shared_ok = false; + } + + // must be: 'Private_Dirty: 0 kB' and 'Private_Clean: 0 kB' + ok = isZero(content, pos, "Private_Dirty:") || + isZero(content, pos, "Private_Clean:"); + if (ok && !pass_ok) { + private_ok = true; + } else if (!ok) { + private_ok = false; } - content = ""; - if (!pass_ok) return; - if (shared_ok && anonymous_ok && private_ok) return; + // must be: 'Anonymous: 0 kB' + ok = isZero(content, pos, "Anonymous:"); + if (ok && !pass_ok) { + anonymous_ok = true; + } else if (!ok) { + anonymous_ok = false; + } + + pass_ok = true; + } + content = ""; + + if (!pass_ok) return; + if (shared_ok && anonymous_ok && private_ok) return; - filename = android::base::StringPrintf("/proc/%d/comm", pid); - android::base::ReadFileToString(filename, &content); - content = android::base::StringPrintf("%d:%s", - pid, content.substr(0, content.find("\n")).c_str()); + filename = android::base::StringPrintf("/proc/%d/comm", pid); + android::base::ReadFileToString(filename, &content); + content = android::base::StringPrintf( + "%d:%s", pid, content.substr(0, content.find("\n")).c_str()); - EXPECT_TRUE(IsOk(shared_ok, content)); - EXPECT_TRUE(IsOk(private_ok, content)); - EXPECT_TRUE(IsOk(anonymous_ok, content)); + EXPECT_TRUE(IsOk(shared_ok, content)); + EXPECT_TRUE(IsOk(private_ok, content)); + EXPECT_TRUE(IsOk(anonymous_ok, content)); } -#endif // __ANDROID__ +#endif // __ANDROID__ TEST(liblog, event_log_tags) { #ifdef __ANDROID__ - std::unique_ptr<DIR, int(*)(DIR*)> proc_dir(opendir("/proc"), closedir); - ASSERT_FALSE(!proc_dir); - - dirent* e; - while ((e = readdir(proc_dir.get()))) { - if (e->d_type != DT_DIR) continue; - if (!isdigit(e->d_name[0])) continue; - long long id = atoll(e->d_name); - if (id <= 0) continue; - pid_t pid = id; - if (id != pid) continue; - event_log_tags_test_smap(pid); - } + std::unique_ptr<DIR, int (*)(DIR*)> proc_dir(opendir("/proc"), closedir); + ASSERT_FALSE(!proc_dir); + + dirent* e; + while ((e = readdir(proc_dir.get()))) { + if (e->d_type != DT_DIR) continue; + if (!isdigit(e->d_name[0])) continue; + long long id = atoll(e->d_name); + if (id <= 0) continue; + pid_t pid = id; + if (id != pid) continue; + event_log_tags_test_smap(pid); + } #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#endif // USING_LOGGER_DEFAULT +#endif // USING_LOGGER_DEFAULT -#ifdef USING_LOGGER_DEFAULT // Do not retest ratelimit +#ifdef USING_LOGGER_DEFAULT // Do not retest ratelimit TEST(liblog, __android_log_ratelimit) { - time_t state = 0; - - errno = 42; - // Prime - __android_log_ratelimit(3, &state); - EXPECT_EQ(errno, 42); - // Check - EXPECT_FALSE(__android_log_ratelimit(3, &state)); - sleep(1); - EXPECT_FALSE(__android_log_ratelimit(3, &state)); - sleep(4); - EXPECT_TRUE(__android_log_ratelimit(3, &state)); - sleep(5); - EXPECT_TRUE(__android_log_ratelimit(3, &state)); - - // API checks - IF_ALOG_RATELIMIT_LOCAL(3, &state) { - EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT_LOCAL(3, &state)"); - } - - IF_ALOG_RATELIMIT() { - ; - } else { - EXPECT_TRUE(0 == "IF_ALOG_RATELIMIT()"); - } - IF_ALOG_RATELIMIT() { - EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT()"); - } - // Do not test default seconds, to allow liblog to tune freely -} -#endif // USING_LOGGER_DEFAULT - -#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality + time_t state = 0; + + errno = 42; + // Prime + __android_log_ratelimit(3, &state); + EXPECT_EQ(errno, 42); + // Check + EXPECT_FALSE(__android_log_ratelimit(3, &state)); + sleep(1); + EXPECT_FALSE(__android_log_ratelimit(3, &state)); + sleep(4); + EXPECT_TRUE(__android_log_ratelimit(3, &state)); + sleep(5); + EXPECT_TRUE(__android_log_ratelimit(3, &state)); + + // API checks + IF_ALOG_RATELIMIT_LOCAL(3, &state) { + EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT_LOCAL(3, &state)"); + } + + IF_ALOG_RATELIMIT() { + ; + } + else { + EXPECT_TRUE(0 == "IF_ALOG_RATELIMIT()"); + } + IF_ALOG_RATELIMIT() { + EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT()"); + } + // Do not test default seconds, to allow liblog to tune freely +} +#endif // USING_LOGGER_DEFAULT + +#ifdef USING_LOGGER_DEFAULT // Do not retest event mapping functionality TEST(liblog, android_lookupEventTagNum) { #ifdef __ANDROID__ - EventTagMap* map = android_openEventTagMap(NULL); - EXPECT_TRUE(NULL != map); - std::string Name = android::base::StringPrintf("a%d", getpid()); - int tag = android_lookupEventTagNum(map, Name.c_str(), "(new|1)", ANDROID_LOG_UNKNOWN); - android_closeEventTagMap(map); - if (tag == -1) system("tail -3 /dev/event-log-tags >&2"); - EXPECT_NE(-1, tag); - EXPECT_NE(0, tag); - EXPECT_GT(UINT32_MAX, (unsigned)tag); + EventTagMap* map = android_openEventTagMap(NULL); + EXPECT_TRUE(NULL != map); + std::string Name = android::base::StringPrintf("a%d", getpid()); + int tag = android_lookupEventTagNum(map, Name.c_str(), "(new|1)", + ANDROID_LOG_UNKNOWN); + android_closeEventTagMap(map); + if (tag == -1) system("tail -3 /dev/event-log-tags >&2"); + EXPECT_NE(-1, tag); + EXPECT_NE(0, tag); + EXPECT_GT(UINT32_MAX, (unsigned)tag); #else - GTEST_LOG_(INFO) << "This test does nothing.\n"; + GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif } -#endif // USING_LOGGER_DEFAULT +#endif // USING_LOGGER_DEFAULT diff --git a/liblog/tests/log_id_test.cpp b/liblog/tests/log_id_test.cpp index b8223f15d..c56fa8b8a 100644 --- a/liblog/tests/log_id_test.cpp +++ b/liblog/tests/log_id_test.cpp @@ -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); } diff --git a/liblog/tests/log_radio_test.cpp b/liblog/tests/log_radio_test.cpp index ecba777d0..f202c677f 100644 --- a/liblog/tests/log_radio_test.cpp +++ b/liblog/tests/log_radio_test.cpp @@ -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 } diff --git a/liblog/tests/log_read_test.cpp b/liblog/tests/log_read_test.cpp index 2e02407b8..a63ab8e88 100644 --- a/liblog/tests/log_read_test.cpp +++ b/liblog/tests/log_read_test.cpp @@ -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); - - 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)); + // 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)); + } - 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 } - diff --git a/liblog/tests/log_system_test.cpp b/liblog/tests/log_system_test.cpp index 40e3a630e..0656c0b23 100644 --- a/liblog/tests/log_system_test.cpp +++ b/liblog/tests/log_system_test.cpp @@ -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 } diff --git a/liblog/tests/log_time_test.cpp b/liblog/tests/log_time_test.cpp index 59655ba43..0ae1d1848 100644 --- a/liblog/tests/log_time_test.cpp +++ b/liblog/tests/log_time_test.cpp @@ -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); } diff --git a/liblog/uio.c b/liblog/uio.c index ac0558f3f..e127202f2 100644 --- a/liblog/uio.c +++ b/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 |