diff options
Diffstat (limited to 'liblog/logd_write.c')
| -rw-r--r-- | liblog/logd_write.c | 147 |
1 files changed, 101 insertions, 46 deletions
diff --git a/liblog/logd_write.c b/liblog/logd_write.c index 5766f8c..d3ee167 100644 --- a/liblog/logd_write.c +++ b/liblog/logd_write.c @@ -13,41 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <time.h> -#include <stdio.h> +#include <errno.h> +#include <fcntl.h> #ifdef HAVE_PTHREADS #include <pthread.h> #endif -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> #include <stdarg.h> -#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <sys/stat.h> +#include <sys/types.h> +#if (FAKE_LOG_DEVICE == 0) +#include <sys/socket.h> +#include <sys/un.h> +#endif +#include <time.h> +#include <unistd.h> -#include <log/logger.h> #include <log/logd.h> -#include <log/log.h> - -#define LOGGER_LOG_MAIN "log/main" -#define LOGGER_LOG_RADIO "log/radio" -#define LOGGER_LOG_EVENTS "log/events" -#define LOGGER_LOG_SYSTEM "log/system" +#include <log/logger.h> +#include <log/log_read.h> +#include <private/android_filesystem_config.h> #define LOG_BUF_SIZE 1024 #if FAKE_LOG_DEVICE -// This will be defined when building for the host. +/* This will be defined when building for the host. */ #include "fake_log_device.h" -#define log_open(pathname, flags) fakeLogOpen(pathname, flags) -#define log_writev(filedes, vector, count) fakeLogWritev(filedes, vector, count) -#define log_close(filedes) fakeLogClose(filedes) -#else -#define log_open(pathname, flags) open(pathname, (flags) | O_CLOEXEC) -#define log_writev(filedes, vector, count) writev(filedes, vector, count) -#define log_close(filedes) close(filedes) #endif static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr); @@ -58,11 +51,15 @@ static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER; #define UNUSED __attribute__((__unused__)) +static int logd_fd = -1; +#if FAKE_LOG_DEVICE +#define WEAK __attribute__((weak)) static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1 }; +#endif /* * This is used by the C++ code to decide if it should write logs through - * the C code. Basically, if /dev/log/... is available, we're running in + * the C code. Basically, if /dev/socket/logd is available, we're running in * the simulator rather than a desktop tool and want to use the device. */ static enum { @@ -71,7 +68,7 @@ static enum { int __android_log_dev_available(void) { if (g_log_status == kLogUninitialized) { - if (access("/dev/"LOGGER_LOG_MAIN, W_OK) == 0) + if (access("/dev/socket/logdw", W_OK) == 0) g_log_status = kLogAvailable; else g_log_status = kLogNotAvailable; @@ -81,13 +78,14 @@ int __android_log_dev_available(void) } static int __write_to_log_null(log_id_t log_fd UNUSED, struct iovec *vec UNUSED, - size_t nr UNUSED) + size_t nr UNUSED) { return -1; } static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) { +#if FAKE_LOG_DEVICE ssize_t ret; int log_fd; @@ -96,13 +94,62 @@ static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) } else { return EBADF; } - do { - ret = log_writev(log_fd, vec, nr); + ret = fakeLogWritev(log_fd, vec, nr); } while (ret < 0 && errno == EINTR); return ret; +#else + if (logd_fd == -1) { + return -1; + } + if (getuid() == AID_LOGD) { + /* + * ignore log messages we send to ourself. + * Such log messages are often generated by libraries we depend on + * which use standard Android logging. + */ + return 0; + } + struct iovec newVec[nr + 2]; + typeof_log_id_t log_id_buf = log_id; + + newVec[0].iov_base = (unsigned char *) &log_id_buf; + newVec[0].iov_len = sizeof_log_id_t; + + log_time realtime_ts; + clock_gettime(CLOCK_REALTIME, &realtime_ts); + + newVec[1].iov_base = (unsigned char *) &realtime_ts; + newVec[1].iov_len = sizeof(log_time); + + size_t i; + for (i = 2; i < nr + 2; i++) { + newVec[i].iov_base = vec[i-2].iov_base; + newVec[i].iov_len = vec[i-2].iov_len; + } + + /* The write below could be lost, but will never block. */ + return writev(logd_fd, newVec, nr + 2); +#endif +} + +#if FAKE_LOG_DEVICE +static const char *LOG_NAME[LOG_ID_MAX] = { + [LOG_ID_MAIN] = "main", + [LOG_ID_RADIO] = "radio", + [LOG_ID_EVENTS] = "events", + [LOG_ID_SYSTEM] = "system" +}; + +const WEAK 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]; } +#endif static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) { @@ -111,27 +158,35 @@ static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) #endif if (write_to_log == __write_to_log_init) { - log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY); - log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY); - log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY); - log_fds[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY); - write_to_log = __write_to_log_kernel; - if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0 || - log_fds[LOG_ID_EVENTS] < 0) { - log_close(log_fds[LOG_ID_MAIN]); - log_close(log_fds[LOG_ID_RADIO]); - log_close(log_fds[LOG_ID_EVENTS]); - log_fds[LOG_ID_MAIN] = -1; - log_fds[LOG_ID_RADIO] = -1; - log_fds[LOG_ID_EVENTS] = -1; - write_to_log = __write_to_log_null; +#if FAKE_LOG_DEVICE + int i; + for (i = 0; i < LOG_ID_MAX; i++) { + char buf[sizeof("/dev/log_system")]; + snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i)); + log_fds[i] = fakeLogOpen(buf, O_WRONLY); } - - if (log_fds[LOG_ID_SYSTEM] < 0) { - log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN]; +#else + int sock = socket(PF_UNIX, SOCK_DGRAM, 0); + if (sock != -1) { + if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) { + /* NB: Loss of content */ + close(sock); + sock = -1; + } else { + struct sockaddr_un un; + memset(&un, 0, sizeof(struct sockaddr_un)); + un.sun_family = AF_UNIX; + strcpy(un.sun_path, "/dev/socket/logdw"); + + connect(sock, (struct sockaddr *)&un, sizeof(struct sockaddr_un)); + } + } else { + write_to_log = __write_to_log_null; } + logd_fd = sock; +#endif } #ifdef HAVE_PTHREADS @@ -288,7 +343,7 @@ int __android_log_bwrite(int32_t tag, const void *payload, size_t len) * handy if we just want to dump an integer into the log. */ int __android_log_btwrite(int32_t tag, char type, const void *payload, - size_t len) + size_t len) { struct iovec vec[3]; |
