Loading liblog/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ liblog_sources = [ ] liblog_host_sources = [ "fake_log_device.cpp", "fake_writer.cpp", ] liblog_target_sources = [ "event_tag_map.cpp", Loading liblog/fake_log_device.cpp +55 −169 Original line number Diff line number Diff line Loading @@ -23,18 +23,20 @@ #include <ctype.h> #include <errno.h> #include <fcntl.h> #if !defined(_WIN32) #include <pthread.h> #endif #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <mutex> #include <android/log.h> #include <log/log_id.h> #include <log/logprint.h> #include "log_portability.h" #include "logger.h" #define kMaxTagLen 16 /* from the long-dead utils/Log.cpp */ Loading @@ -46,37 +48,26 @@ #define TRACE(...) ((void)0) #endif /* 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 } LogFormat; /* * Log driver state. */ typedef struct LogState { /* the fake fd that's seen by the user */ int fakeFd; /* a printable name for this fake device */ char debugName[sizeof("/dev/log/security")]; static int FakeAvailable(log_id_t); static int FakeOpen(); static void FakeClose(); static int FakeWrite(log_id_t log_id, struct timespec* ts, struct iovec* vec, size_t nr); /* nonzero if this is a binary log */ int isBinary; struct android_log_transport_write fakeLoggerWrite = { .name = "fake", .logMask = 0, .available = FakeAvailable, .open = FakeOpen, .close = FakeClose, .write = FakeWrite, }; typedef struct LogState { /* global minimum priority */ int globalMinPriority; int global_min_priority; /* output format */ LogFormat outputFormat; AndroidLogPrintFormat output_format; /* tags and priorities */ struct { Loading @@ -85,81 +76,18 @@ typedef struct LogState { } tagSet[kTagSetSize]; } LogState; #if !defined(_WIN32) /* * Locking. Since we're emulating a device, we need to be prepared * to have multiple callers at the same time. This lock is used * to both protect the fd list and to prevent LogStates from being * freed out from under a user. */ 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 unlock() { pthread_mutex_unlock(&fakeLogDeviceLock); } #else // !defined(_WIN32) #define lock() ((void)0) #define unlock() ((void)0) #endif // !defined(_WIN32) /* * File descriptor management. */ #define FAKE_FD_BASE 10000 #define MAX_OPEN_LOGS 8 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]; } } 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; } /* * Unregister the fake fd and free the memory it pointed to. */ static void deleteFakeFd(int fd) { LogState* ls; std::mutex mutex; lock(); static LogState log_state; ls = fdToLogState(fd); if (ls != NULL) { memset(&openLogTable[fd - FAKE_FD_BASE], 0, sizeof(openLogTable[0])); } unlock(); static int FakeAvailable(log_id_t) { return 0; } /* Loading @@ -175,20 +103,11 @@ 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") || !strcmp(pathName + kDevLogLen, "stats")) { logState->isBinary = 1; } int FakeOpen() { std::lock_guard guard{mutex}; /* global min priority defaults to "info" level */ logState->globalMinPriority = ANDROID_LOG_INFO; log_state.global_min_priority = ANDROID_LOG_INFO; /* * This is based on the the long-dead utils/Log.cpp code. Loading @@ -210,7 +129,7 @@ static void configureInitialState(const char* pathName, LogState* logState) { } if (i == kMaxTagLen) { TRACE("ERROR: env tag too long (%d chars max)\n", kMaxTagLen - 1); return; return 0; } tagName[i] = '\0'; Loading Loading @@ -261,16 +180,16 @@ static void configureInitialState(const char* pathName, LogState* logState) { if (*tags != '\0' && !isspace(*tags)) { TRACE("ERROR: garbage in tag env; expected whitespace\n"); TRACE(" env='%s'\n", tags); return; return 0; } } if (tagName[0] == 0) { logState->globalMinPriority = minPrio; log_state.global_min_priority = minPrio; TRACE("+++ global min prio %d\n", logState->globalMinPriority); } else { logState->tagSet[entry].minPriority = minPrio; strcpy(logState->tagSet[entry].tag, tagName); log_state.tagSet[entry].minPriority = minPrio; strcpy(log_state.tagSet[entry].tag, tagName); TRACE("+++ entry %d: %s:%d\n", entry, logState->tagSet[entry].tag, logState->tagSet[entry].minPriority); entry++; Loading @@ -282,7 +201,7 @@ static void configureInitialState(const char* pathName, LogState* logState) { * Taken from the long-dead utils/Log.cpp */ const char* fstr = getenv("ANDROID_PRINTF_LOG"); LogFormat format; AndroidLogPrintFormat format; if (fstr == NULL) { format = FORMAT_BRIEF; } else { Loading @@ -301,10 +220,11 @@ static void configureInitialState(const char* pathName, LogState* logState) { else if (strcmp(fstr, "long") == 0) format = FORMAT_PROCESS; else format = (LogFormat)atoi(fstr); // really?! format = (AndroidLogPrintFormat)atoi(fstr); // really?! } logState->outputFormat = format; log_state.output_format = format; return 0; } /* Loading Loading @@ -349,7 +269,7 @@ static ssize_t fake_writev(int fd, const struct iovec* iov, int iovcnt) { * * 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(int logPrio, const char* tag, const char* msg) { #if !defined(_WIN32) struct tm tmBuf; #endif Loading Loading @@ -392,7 +312,7 @@ static void showLog(LogState* state, int logPrio, const char* tag, const char* m */ size_t prefixLen, suffixLen; switch (state->outputFormat) { switch (log_state.output_format) { case FORMAT_TAG: prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "%c/%-8s: ", priChar, tag); strcpy(suffixBuf, "\n"); Loading Loading @@ -549,35 +469,24 @@ static void showLog(LogState* state, int logPrio, const char* tag, const char* m * tag (N bytes -- null-terminated ASCII string) * message (N bytes -- null-terminated ASCII string) */ ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count) { LogState* state; static int FakeWrite(log_id_t log_id, struct timespec*, struct iovec* vector, size_t count) { /* 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; unlock(); return -1; } std::lock_guard guard{mutex}; if (state->isBinary) { TRACE("%s: ignoring binary log\n", state->debugName); unlock(); if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS || log_id == LOG_ID_SECURITY) { TRACE("%s: ignoring binary log\n", android_log_id_to_name(log_id)); int len = 0; for (int i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) { len += vector[i].iov_len; } return len; } if (count != 3) { TRACE("%s: writevLog with count=%d not expected\n", state->debugName, count); unlock(); TRACE("%s: writevLog with count=%d not expected\n", android_log_id_to_name(log_id), count); return -1; } Loading @@ -587,32 +496,30 @@ ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count) { 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) int minPrio = log_state.global_min_priority; for (size_t i = 0; i < kTagSetSize; i++) { if (log_state.tagSet[i].minPriority == ANDROID_LOG_UNKNOWN) break; /* reached end of configured values */ if (strcmp(state->tagSet[i].tag, tag) == 0) { minPrio = state->tagSet[i].minPriority; if (strcmp(log_state.tagSet[i].tag, tag) == 0) { minPrio = log_state.tagSet[i].minPriority; break; } } if (logPrio >= minPrio) { showLog(state, logPrio, tag, msg); ShowLog(logPrio, tag, msg); } unlock(); int len = 0; for (i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) { len += vector[i].iov_len; } return len; } /* * Free up our state and close the fake descriptor. * Reset out state. * * The logger API has no means or need to 'stop' or 'close' using the logs, * and as such, there is no way for that 'stop' or 'close' to translate into Loading @@ -624,31 +531,10 @@ ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count) { * call is in the exit handler. Logging can continue in the exit handler to * help debug HOST tools ... */ int fakeLogClose(int fd) { deleteFakeFd(fd); return 0; } /* * Open a log output device and return a fake fd. */ int fakeLogOpen(const char* pathName) { LogState* logState; int fd = -1; lock(); logState = createLogState(); if (logState != NULL) { configureInitialState(pathName, logState); fd = logState->fakeFd; } else { errno = ENFILE; } unlock(); static void FakeClose() { std::lock_guard guard{mutex}; return fd; memset(&log_state, 0, sizeof(log_state)); } int __android_log_is_loggable(int prio, const char*, int def) { Loading liblog/fake_writer.cppdeleted 100644 → 0 +0 −105 Original line number Diff line number Diff line /* * Copyright (C) 2007-2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <log/log.h> #include "fake_log_device.h" #include "log_portability.h" #include "logger.h" static int fakeAvailable(log_id_t); 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 logFds[(int)LOG_ID_MAX] = {-1, -1, -1, -1, -1, -1}; struct android_log_transport_write fakeLoggerWrite = { .name = "fake", .logMask = 0, .context.priv = &logFds, .available = fakeAvailable, .open = fakeOpen, .close = fakeClose, .write = fakeWrite, }; static int fakeAvailable(log_id_t) { return 0; } 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(static_cast<log_id_t>(i))); logFds[i] = fakeLogOpen(buf); if (logFds[i] < 0) { fprintf(stderr, "fakeLogOpen(%s) failed\n", buf); } } return 0; } static void fakeClose() { int i; for (i = 0; i < LOG_ID_MAX; i++) { fakeLogClose(logFds[i]); logFds[i] = -1; } } static int fakeWrite(log_id_t log_id, struct timespec*, 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; } Loading
liblog/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ liblog_sources = [ ] liblog_host_sources = [ "fake_log_device.cpp", "fake_writer.cpp", ] liblog_target_sources = [ "event_tag_map.cpp", Loading
liblog/fake_log_device.cpp +55 −169 Original line number Diff line number Diff line Loading @@ -23,18 +23,20 @@ #include <ctype.h> #include <errno.h> #include <fcntl.h> #if !defined(_WIN32) #include <pthread.h> #endif #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <mutex> #include <android/log.h> #include <log/log_id.h> #include <log/logprint.h> #include "log_portability.h" #include "logger.h" #define kMaxTagLen 16 /* from the long-dead utils/Log.cpp */ Loading @@ -46,37 +48,26 @@ #define TRACE(...) ((void)0) #endif /* 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 } LogFormat; /* * Log driver state. */ typedef struct LogState { /* the fake fd that's seen by the user */ int fakeFd; /* a printable name for this fake device */ char debugName[sizeof("/dev/log/security")]; static int FakeAvailable(log_id_t); static int FakeOpen(); static void FakeClose(); static int FakeWrite(log_id_t log_id, struct timespec* ts, struct iovec* vec, size_t nr); /* nonzero if this is a binary log */ int isBinary; struct android_log_transport_write fakeLoggerWrite = { .name = "fake", .logMask = 0, .available = FakeAvailable, .open = FakeOpen, .close = FakeClose, .write = FakeWrite, }; typedef struct LogState { /* global minimum priority */ int globalMinPriority; int global_min_priority; /* output format */ LogFormat outputFormat; AndroidLogPrintFormat output_format; /* tags and priorities */ struct { Loading @@ -85,81 +76,18 @@ typedef struct LogState { } tagSet[kTagSetSize]; } LogState; #if !defined(_WIN32) /* * Locking. Since we're emulating a device, we need to be prepared * to have multiple callers at the same time. This lock is used * to both protect the fd list and to prevent LogStates from being * freed out from under a user. */ 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 unlock() { pthread_mutex_unlock(&fakeLogDeviceLock); } #else // !defined(_WIN32) #define lock() ((void)0) #define unlock() ((void)0) #endif // !defined(_WIN32) /* * File descriptor management. */ #define FAKE_FD_BASE 10000 #define MAX_OPEN_LOGS 8 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]; } } 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; } /* * Unregister the fake fd and free the memory it pointed to. */ static void deleteFakeFd(int fd) { LogState* ls; std::mutex mutex; lock(); static LogState log_state; ls = fdToLogState(fd); if (ls != NULL) { memset(&openLogTable[fd - FAKE_FD_BASE], 0, sizeof(openLogTable[0])); } unlock(); static int FakeAvailable(log_id_t) { return 0; } /* Loading @@ -175,20 +103,11 @@ 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") || !strcmp(pathName + kDevLogLen, "stats")) { logState->isBinary = 1; } int FakeOpen() { std::lock_guard guard{mutex}; /* global min priority defaults to "info" level */ logState->globalMinPriority = ANDROID_LOG_INFO; log_state.global_min_priority = ANDROID_LOG_INFO; /* * This is based on the the long-dead utils/Log.cpp code. Loading @@ -210,7 +129,7 @@ static void configureInitialState(const char* pathName, LogState* logState) { } if (i == kMaxTagLen) { TRACE("ERROR: env tag too long (%d chars max)\n", kMaxTagLen - 1); return; return 0; } tagName[i] = '\0'; Loading Loading @@ -261,16 +180,16 @@ static void configureInitialState(const char* pathName, LogState* logState) { if (*tags != '\0' && !isspace(*tags)) { TRACE("ERROR: garbage in tag env; expected whitespace\n"); TRACE(" env='%s'\n", tags); return; return 0; } } if (tagName[0] == 0) { logState->globalMinPriority = minPrio; log_state.global_min_priority = minPrio; TRACE("+++ global min prio %d\n", logState->globalMinPriority); } else { logState->tagSet[entry].minPriority = minPrio; strcpy(logState->tagSet[entry].tag, tagName); log_state.tagSet[entry].minPriority = minPrio; strcpy(log_state.tagSet[entry].tag, tagName); TRACE("+++ entry %d: %s:%d\n", entry, logState->tagSet[entry].tag, logState->tagSet[entry].minPriority); entry++; Loading @@ -282,7 +201,7 @@ static void configureInitialState(const char* pathName, LogState* logState) { * Taken from the long-dead utils/Log.cpp */ const char* fstr = getenv("ANDROID_PRINTF_LOG"); LogFormat format; AndroidLogPrintFormat format; if (fstr == NULL) { format = FORMAT_BRIEF; } else { Loading @@ -301,10 +220,11 @@ static void configureInitialState(const char* pathName, LogState* logState) { else if (strcmp(fstr, "long") == 0) format = FORMAT_PROCESS; else format = (LogFormat)atoi(fstr); // really?! format = (AndroidLogPrintFormat)atoi(fstr); // really?! } logState->outputFormat = format; log_state.output_format = format; return 0; } /* Loading Loading @@ -349,7 +269,7 @@ static ssize_t fake_writev(int fd, const struct iovec* iov, int iovcnt) { * * 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(int logPrio, const char* tag, const char* msg) { #if !defined(_WIN32) struct tm tmBuf; #endif Loading Loading @@ -392,7 +312,7 @@ static void showLog(LogState* state, int logPrio, const char* tag, const char* m */ size_t prefixLen, suffixLen; switch (state->outputFormat) { switch (log_state.output_format) { case FORMAT_TAG: prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), "%c/%-8s: ", priChar, tag); strcpy(suffixBuf, "\n"); Loading Loading @@ -549,35 +469,24 @@ static void showLog(LogState* state, int logPrio, const char* tag, const char* m * tag (N bytes -- null-terminated ASCII string) * message (N bytes -- null-terminated ASCII string) */ ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count) { LogState* state; static int FakeWrite(log_id_t log_id, struct timespec*, struct iovec* vector, size_t count) { /* 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; unlock(); return -1; } std::lock_guard guard{mutex}; if (state->isBinary) { TRACE("%s: ignoring binary log\n", state->debugName); unlock(); if (log_id == LOG_ID_EVENTS || log_id == LOG_ID_STATS || log_id == LOG_ID_SECURITY) { TRACE("%s: ignoring binary log\n", android_log_id_to_name(log_id)); int len = 0; for (int i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) { len += vector[i].iov_len; } return len; } if (count != 3) { TRACE("%s: writevLog with count=%d not expected\n", state->debugName, count); unlock(); TRACE("%s: writevLog with count=%d not expected\n", android_log_id_to_name(log_id), count); return -1; } Loading @@ -587,32 +496,30 @@ ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count) { 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) int minPrio = log_state.global_min_priority; for (size_t i = 0; i < kTagSetSize; i++) { if (log_state.tagSet[i].minPriority == ANDROID_LOG_UNKNOWN) break; /* reached end of configured values */ if (strcmp(state->tagSet[i].tag, tag) == 0) { minPrio = state->tagSet[i].minPriority; if (strcmp(log_state.tagSet[i].tag, tag) == 0) { minPrio = log_state.tagSet[i].minPriority; break; } } if (logPrio >= minPrio) { showLog(state, logPrio, tag, msg); ShowLog(logPrio, tag, msg); } unlock(); int len = 0; for (i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) { len += vector[i].iov_len; } return len; } /* * Free up our state and close the fake descriptor. * Reset out state. * * The logger API has no means or need to 'stop' or 'close' using the logs, * and as such, there is no way for that 'stop' or 'close' to translate into Loading @@ -624,31 +531,10 @@ ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count) { * call is in the exit handler. Logging can continue in the exit handler to * help debug HOST tools ... */ int fakeLogClose(int fd) { deleteFakeFd(fd); return 0; } /* * Open a log output device and return a fake fd. */ int fakeLogOpen(const char* pathName) { LogState* logState; int fd = -1; lock(); logState = createLogState(); if (logState != NULL) { configureInitialState(pathName, logState); fd = logState->fakeFd; } else { errno = ENFILE; } unlock(); static void FakeClose() { std::lock_guard guard{mutex}; return fd; memset(&log_state, 0, sizeof(log_state)); } int __android_log_is_loggable(int prio, const char*, int def) { Loading
liblog/fake_writer.cppdeleted 100644 → 0 +0 −105 Original line number Diff line number Diff line /* * Copyright (C) 2007-2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <log/log.h> #include "fake_log_device.h" #include "log_portability.h" #include "logger.h" static int fakeAvailable(log_id_t); 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 logFds[(int)LOG_ID_MAX] = {-1, -1, -1, -1, -1, -1}; struct android_log_transport_write fakeLoggerWrite = { .name = "fake", .logMask = 0, .context.priv = &logFds, .available = fakeAvailable, .open = fakeOpen, .close = fakeClose, .write = fakeWrite, }; static int fakeAvailable(log_id_t) { return 0; } 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(static_cast<log_id_t>(i))); logFds[i] = fakeLogOpen(buf); if (logFds[i] < 0) { fprintf(stderr, "fakeLogOpen(%s) failed\n", buf); } } return 0; } static void fakeClose() { int i; for (i = 0; i < LOG_ID_MAX; i++) { fakeLogClose(logFds[i]); logFds[i] = -1; } } static int fakeWrite(log_id_t log_id, struct timespec*, 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; }