android log丢失(三)动态切换logd机制和kernel机制

之前我们分析了如何修改版本使log机制变成kernel的log机制。这篇博客我们继续修改可以动态切换,这样方便平时log丢失时调试。


我们先来看liblog库的编译mk文件,这个文件中主要修改了对使用使用logd 使用不同文件进行编译这块做了修改,增加了log_write_common.c 和log_read_common.c两个通用文件。

[html]  view plain  copy
  1. #  
  2. # Copyright (C) 2008-2014 The Android Open Source Project  
  3. #  
  4. # Licensed under the Apache License, Version 2.0 (the "License");  
  5. # you may not use this file except in compliance with the License.  
  6. # You may obtain a copy of the License at  
  7. #  
  8. #      http://www.apache.org/licenses/LICENSE-2.0  
  9. #  
  10. # Unless required by applicable law or agreed to in writing, software  
  11. # distributed under the License is distributed on an "AS IS" BASIS,  
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  13. # See the License for the specific language governing permissions and  
  14. # limitations under the License.  
  15. #  
  16. LOCAL_PATH := $(my-dir)  
  17. include $(CLEAR_VARS)  
  18.   
  19. # This is what we want to do:  
  20. #  liblog_cflags := $(shell \  
  21. #   sed -n \  
  22. #       's/^ [09] [ \t]*liblog[ \t].*/-DLIBLOG_LOG_TAG=\1/p' \  
  23. #       $(LOCAL_PATH)/event.logtags)  
  24. # so make sure we do not regret hard-coding it as follows:  
  25. liblog_cflags :-DLIBLOG_LOG_TAG=1005  
  26.   
  27. #ifneq ($(TARGET_USES_LOGD),false)//注释了 不需要区分使用使用logd  
  28. #liblog_sources :logd_write.c log_event_write.c  
  29. #else  
  30. #liblog_sources :logd_write_kern.c log_event_write.c  
  31. #endif  
  32.   
  33.   
  34. liblog_sources :log_write_common.c log_event_write.c//增加log_write_common.c   
  35.   
  36. # some files must not be compiled when building against Mingw  
  37. # they correspond to features not used by our host development tools  
  38. # which are also hard or even impossible to port to native Win32  
  39.   
  40. ifeq ($(strip $(USE_MINGW)),)  
  41.     liblog_sources += \  
  42.         event_tag_map.c  
  43. else  
  44.     liblog_sources += \  
  45.         uio.c  
  46. endif  
  47.   
  48. liblog_host_sources := $(liblog_sources) fake_log_device.c event.logtags  
  49. liblog_target_sources := $(liblog_sources) log_time.cpp log_is_loggable.c  
  50. ifeq ($(strip $(USE_MINGW)),)  
  51. liblog_target_sources += logprint.c  
  52. endif  
  53.   
  54. #ifneq ($(TARGET_USES_LOGD),false)//注释了,不用区分是否使用logd  
  55. #liblog_target_sources += log_read.c  
  56. #else  
  57. #liblog_target_sources += log_read_kern.c  
  58. #endif  
  59.   
  60. liblog_target_sources += log_read_common.c//增加log_read_common.c  
  61. # Shared and static library for host  
  62. # ========================================================  
  63. LOCAL_MODULE :liblog  
  64. LOCAL_SRC_FILES := $(liblog_host_sources)  
  65. LOCAL_CFLAGS :-DFAKE_LOG_DEVICE=1 -Werror $(liblog_cflags)  
  66. LOCAL_MULTILIB :both  
  67. include $(BUILD_HOST_STATIC_LIBRARY)  
  68.   
  69. include $(CLEAR_VARS)  
  70. LOCAL_MODULE :liblog  
  71. LOCAL_WHOLE_STATIC_LIBRARIES :liblog  
  72. ifeq ($(strip $(HOST_OS)),linux)  
  73. LOCAL_LDLIBS := -lrt  
  74. endif  
  75. LOCAL_MULTILIB :both  
  76. include $(BUILD_HOST_SHARED_LIBRARY)  
  77.   
  78.   
  79. # Shared and static library for target  
  80. # ========================================================  
  81. include $(CLEAR_VARS)  
  82. LOCAL_MODULE :liblog  
  83. LOCAL_SRC_FILES := $(liblog_target_sources)  
  84. LOCAL_CFLAGS := -Werror $(liblog_cflags)  
  85. include $(BUILD_STATIC_LIBRARY)  
  86.   
  87. include $(CLEAR_VARS)  
  88. LOCAL_MODULE :liblog  
  89. LOCAL_WHOLE_STATIC_LIBRARIES :liblog  
  90. LOCAL_CFLAGS := -Werror $(liblog_cflags)  
  91.   
  92. # TODO: This is to work around b/19059885. Remove after root cause is fixed  
  93. LOCAL_LDFLAGS_arm := -Wl,--hash-style=both  
  94.   
  95. include $(BUILD_SHARED_LIBRARY)  
  96.   
  97. include $(call first-makefiles-under,$(LOCAL_PATH))  

我们先来看log_read_common.c文件,这样主要就是将原来的logd_write.c 和logd_write_kern.c 文件进行合并。一些对外的接口,统一使用use_logd这个全局变量来控制,选择logd的函数,还是kernel的函数(logd的函数和kernel的函数就是static函数了,不用对外)。另外在__write_to_log_init函数中,第一次初始化的使用,先看system/etc/disable_logd是否有这样一个文件,有就将use_logd为0,代表使用kernel机制。

[cpp]  view plain  copy
  1. /* 
  2.  * Copyright (C) 2007-2014 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16. #if (FAKE_LOG_DEVICE == 0)  
  17. #include <endian.h>  
  18. #endif  
  19. #include <errno.h>  
  20. #include <fcntl.h>  
  21. #if !defined(_WIN32)  
  22. #include <pthread.h>  
  23. #endif  
  24. #include <stdarg.h>  
  25. #include <stdatomic.h>  
  26. #include <stdio.h>  
  27. #include <stdlib.h>  
  28. #include <string.h>  
  29. #include <sys/stat.h>  
  30. #include <sys/types.h>  
  31. #if (FAKE_LOG_DEVICE == 0)  
  32. #include <sys/socket.h>  
  33. #include <sys/un.h>  
  34. #endif  
  35. #include <time.h>  
  36. #include <unistd.h>  
  37.   
  38. #ifdef __BIONIC__  
  39. #include <android/set_abort_message.h>  
  40. #endif  
  41.   
  42. #include <log/log.h>  
  43. #include <log/logd.h>  
  44. #include <log/logger.h>  
  45.   
  46. #include <log/log_read.h>  
  47. #include <private/android_filesystem_config.h>  
  48. #include <private/android_logger.h>  
  49.   
  50. #define LOGGER_LOG_MAIN     "log/main"  
  51. #define LOGGER_LOG_RADIO    "log/radio"  
  52. #define LOGGER_LOG_EVENTS   "log/events"  
  53. #define LOGGER_LOG_SYSTEM   "log/system"  
  54.   
  55. #define LOG_BUF_SIZE 1024  
  56.   
  57. #if FAKE_LOG_DEVICE  
  58. /* This will be defined when building for the host. */  
  59. #include "fake_log_device.h"  
  60. #endif  
  61.   
  62. #define log_open(pathname, flags) open(pathname, (flags) | O_CLOEXEC)  
  63. #define log_writev(filedes, vector, count) writev(filedes, vector, count)  
  64. #define log_close(filedes) close(filedes)  
  65.   
  66. static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);  
  67. static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;  
  68. #if !defined(_WIN32)  
  69. static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;  
  70. #endif  
  71.   
  72. #ifndef __unused  
  73. #define __unused  __attribute__((__unused__))  
  74. #endif  
  75.   
  76. static int8_t use_logd = 1;//做区分  
  77.   
  78. #if FAKE_LOG_DEVICE  
  79. static int log_fds_fake[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };  
  80. #else  
  81. static int logd_fd = -1;  
  82. static int pstore_fd = -1;  
  83. #endif  
  84.   
  85. static int log_fds_kernel[(int)LOG_ID_MAX] = { -1, -1, -1, -1 };  
  86.   
  87.   
  88. /* 
  89.  * This is used by the C++ code to decide if it should write logs through 
  90.  * the C code.  Basically, if /dev/socket/logd is available, we're running in 
  91.  * the simulator rather than a desktop tool and want to use the device. 
  92.  */  
  93. static enum {  
  94.     kLogUninitialized, kLogNotAvailable, kLogAvailable  
  95. } g_log_status = kLogUninitialized;  
  96.   
  97. static int __android_log_dev_available_logd(void)  
  98. {  
  99.     if (g_log_status == kLogUninitialized) {  
  100.         if (access("/dev/socket/logdw", W_OK) == 0)  
  101.             g_log_status = kLogAvailable;  
  102.         else  
  103.             g_log_status = kLogNotAvailable;  
  104.     }  
  105.   
  106.     return (g_log_status == kLogAvailable);  
  107. }  
  108.   
  109. static int __android_log_dev_available_kernel(void)  
  110. {  
  111.     if (g_log_status == kLogUninitialized) {  
  112.         if (access("/dev/"LOGGER_LOG_MAIN, W_OK) == 0)  
  113.             g_log_status = kLogAvailable;  
  114.         else  
  115.             g_log_status = kLogNotAvailable;  
  116.     }  
  117.   
  118.     return (g_log_status == kLogAvailable);  
  119. }  
  120.   
  121. int __android_log_dev_available(void)  
  122. {  
  123.     if (use_logd) {  
  124.         return __android_log_dev_available_logd();  
  125.     } else {  
  126.         return __android_log_dev_available_kernel();  
  127.     }  
  128. }  
  129.   
  130. /* log_init_lock assumed */  
  131. static int __write_to_log_initialize()  
  132. {  
  133.     int i, ret = 0;  
  134.   
  135. #if FAKE_LOG_DEVICE  
  136.     for (i = 0; i < LOG_ID_MAX; i++) {  
  137.         char buf[sizeof("/dev/log_system")];  
  138.         snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i));  
  139.         log_fds_fake[i] = fakeLogOpen(buf, O_WRONLY);  
  140.     }  
  141. #else  
  142.     if (pstore_fd < 0) {  
  143.         pstore_fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY));  
  144.     }  
  145.   
  146.     if (logd_fd < 0) {  
  147.         i = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0));  
  148.         if (i < 0) {  
  149.             ret = -errno;  
  150.         } else if (TEMP_FAILURE_RETRY(fcntl(i, F_SETFL, O_NONBLOCK)) < 0) {  
  151.             ret = -errno;  
  152.             close(i);  
  153.         } else {  
  154.             struct sockaddr_un un;  
  155.             memset(&un, 0, sizeof(struct sockaddr_un));  
  156.             un.sun_family = AF_UNIX;  
  157.             strcpy(un.sun_path, "/dev/socket/logdw");  
  158.   
  159.             if (TEMP_FAILURE_RETRY(connect(i, (struct sockaddr *)&un,  
  160.                                            sizeof(struct sockaddr_un))) < 0) {  
  161.                 ret = -errno;  
  162.                 close(i);  
  163.             } else {  
  164.                 logd_fd = i;  
  165.             }  
  166.         }  
  167.     }  
  168. #endif  
  169.   
  170.     return ret;  
  171. }  
  172.   
  173.   
  174. static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr)  
  175. {  
  176.     ssize_t ret;  
  177. #if FAKE_LOG_DEVICE  
  178.     int log_fd;  
  179.   
  180.     if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {  
  181.         log_fd = log_fds_fake[(int)log_id];  
  182.     } else {  
  183.         return -EBADF;  
  184.     }  
  185.     do {  
  186.         ret = fakeLogWritev(log_fd, vec, nr);  
  187.         if (ret < 0) {  
  188.             ret = -errno;  
  189.         }  
  190.     } while (ret == -EINTR);  
  191. #else  
  192.     static const unsigned header_length = 2;  
  193.     struct iovec newVec[nr + header_length];  
  194.     android_log_header_t header;  
  195.     android_pmsg_log_header_t pmsg_header;  
  196.     struct timespec ts;  
  197.     size_t i, payload_size;  
  198.     static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */  
  199.     static pid_t last_pid = (pid_t) -1;  
  200.     static atomic_int_fast32_t dropped;  
  201.   
  202.     if (!nr) {  
  203.         return -EINVAL;  
  204.     }  
  205.   
  206.     if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */  
  207.         last_uid = getuid();  
  208.     }  
  209.     if (last_pid == (pid_t) -1) {  
  210.         last_pid = getpid();  
  211.     }  
  212.     /* 
  213.      *  struct { 
  214.      *      // what we provide to pstore 
  215.      *      android_pmsg_log_header_t pmsg_header; 
  216.      *      // what we provide to socket 
  217.      *      android_log_header_t header; 
  218.      *      // caller provides 
  219.      *      union { 
  220.      *          struct { 
  221.      *              char     prio; 
  222.      *              char     payload[]; 
  223.      *          } string; 
  224.      *          struct { 
  225.      *              uint32_t tag 
  226.      *              char     payload[]; 
  227.      *          } binary; 
  228.      *      }; 
  229.      *  }; 
  230.      */  
  231.   
  232.     clock_gettime(CLOCK_REALTIME, &ts);  
  233.   
  234.     pmsg_header.magic = LOGGER_MAGIC;  
  235.     pmsg_header.len = sizeof(pmsg_header) + sizeof(header);  
  236.     pmsg_header.uid = last_uid;  
  237.     pmsg_header.pid = last_pid;  
  238.   
  239.     header.tid = gettid();  
  240.     header.realtime.tv_sec = ts.tv_sec;  
  241.     header.realtime.tv_nsec = ts.tv_nsec;  
  242.   
  243.     newVec[0].iov_base   = (unsigned char *) &pmsg_header;  
  244.     newVec[0].iov_len    = sizeof(pmsg_header);  
  245.     newVec[1].iov_base   = (unsigned char *) &header;  
  246.     newVec[1].iov_len    = sizeof(header);  
  247.   
  248.     if (logd_fd > 0) {  
  249.         int32_t snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed);  
  250.         if (snapshot) {  
  251.             android_log_event_int_t buffer;  
  252.   
  253.             header.id = LOG_ID_EVENTS;  
  254.             buffer.header.tag = htole32(LIBLOG_LOG_TAG);  
  255.             buffer.payload.type = EVENT_TYPE_INT;  
  256.             buffer.payload.data = htole32(snapshot);  
  257.   
  258.             newVec[2].iov_base = &buffer;  
  259.             newVec[2].iov_len  = sizeof(buffer);  
  260.   
  261.             ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, 2));  
  262.             if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) {  
  263.                 atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed);  
  264.             }  
  265.         }  
  266.     }  
  267.   
  268.     header.id = log_id;  
  269.   
  270.     for (payload_size = 0, i = header_length; i < nr + header_length; i++) {  
  271.         newVec[i].iov_base = vec[i - header_length].iov_base;  
  272.         payload_size += newVec[i].iov_len = vec[i - header_length].iov_len;  
  273.   
  274.         if (payload_size > LOGGER_ENTRY_MAX_PAYLOAD) {  
  275.             newVec[i].iov_len -= payload_size - LOGGER_ENTRY_MAX_PAYLOAD;  
  276.             if (newVec[i].iov_len) {  
  277.                 ++i;  
  278.             }  
  279.             payload_size = LOGGER_ENTRY_MAX_PAYLOAD;  
  280.             break;  
  281.         }  
  282.     }  
  283.     pmsg_header.len += payload_size;  
  284.   
  285.     if (pstore_fd >= 0) {  
  286.         TEMP_FAILURE_RETRY(writev(pstore_fd, newVec, i));  
  287.     }  
  288.   
  289.     if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */  
  290.         /* 
  291.          * ignore log messages we send to ourself (logd). 
  292.          * Such log messages are often generated by libraries we depend on 
  293.          * which use standard Android logging. 
  294.          */  
  295.         return 0;  
  296.     }  
  297.   
  298.     if (logd_fd < 0) {  
  299.         return -EBADF;  
  300.     }  
  301.   
  302.     /* 
  303.      * The write below could be lost, but will never block. 
  304.      * 
  305.      * To logd, we drop the pmsg_header 
  306.      * 
  307.      * ENOTCONN occurs if logd dies. 
  308.      * EAGAIN occurs if logd is overloaded. 
  309.      */  
  310.     ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));  
  311.     if (ret < 0) {  
  312.         ret = -errno;  
  313.         if (ret == -ENOTCONN) {  
  314. #if !defined(_WIN32)  
  315.             pthread_mutex_lock(&log_init_lock);  
  316. #endif  
  317.             close(logd_fd);  
  318.             logd_fd = -1;  
  319.             ret = __write_to_log_initialize();  
  320. #if !defined(_WIN32)  
  321.             pthread_mutex_unlock(&log_init_lock);  
  322. #endif  
  323.   
  324.             if (ret < 0) {  
  325.                 return ret;  
  326.             }  
  327.   
  328.             ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));  
  329.             if (ret < 0) {  
  330.                 ret = -errno;  
  331.             }  
  332.         }  
  333.     }  
  334.   
  335.     if (ret > (ssize_t)sizeof(header)) {  
  336.         ret -= sizeof(header);  
  337.     } else if (ret == -EAGAIN) {  
  338.         atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed);  
  339.     }  
  340. #endif  
  341.   
  342.     return ret;  
  343. }  
  344.   
  345. #if FAKE_LOG_DEVICE  
  346. static const char *LOG_NAME[LOG_ID_MAX] = {  
  347.     [LOG_ID_MAIN] = "main",  
  348.     [LOG_ID_RADIO] = "radio",  
  349.     [LOG_ID_EVENTS] = "events",  
  350.     [LOG_ID_SYSTEM] = "system",  
  351.     [LOG_ID_CRASH] = "crash",  
  352.     [LOG_ID_KERNEL] = "kernel",  
  353. };  
  354.   
  355. const char *android_log_id_to_name(log_id_t log_id)  
  356. {  
  357.     if (log_id >= LOG_ID_MAX) {  
  358.         log_id = LOG_ID_MAIN;  
  359.     }  
  360.     return LOG_NAME[log_id];  
  361. }  
  362. #endif  
  363.   
  364. static int __write_to_log_init_logd(log_id_t log_id, struct iovec *vec, size_t nr)  
  365. {  
  366. #if !defined(_WIN32)  
  367.     pthread_mutex_lock(&log_init_lock);  
  368. #endif  
  369.   
  370.     if (write_to_log == __write_to_log_init) {  
  371.         int ret;  
  372.   
  373.         ret = __write_to_log_initialize();  
  374.         if (ret < 0) {  
  375. #if !defined(_WIN32)  
  376.             pthread_mutex_unlock(&log_init_lock);  
  377. #endif  
  378. #if (FAKE_LOG_DEVICE == 0)  
  379.             if (pstore_fd >= 0) {  
  380.                 __write_to_log_daemon(log_id, vec, nr);  
  381.             }  
  382. #endif  
  383.             return ret;  
  384.         }  
  385.   
  386.         write_to_log = __write_to_log_daemon;  
  387.     }  
  388.   
  389. #if !defined(_WIN32)  
  390.     pthread_mutex_unlock(&log_init_lock);  
  391. #endif  
  392.   
  393.     return write_to_log(log_id, vec, nr);  
  394. }  
  395.   
  396. static int __write_to_log_null(log_id_t log_fd __unused, struct iovec *vec __unused,  
  397.                                size_t nr __unused)  
  398. {  
  399.     return -1;  
  400. }  
  401.   
  402. static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)  
  403. {  
  404.     ssize_t ret;  
  405.     int log_fd;  
  406.   
  407.     if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {  
  408.         if (log_id == LOG_ID_CRASH) {  
  409.             log_id = LOG_ID_MAIN;  
  410.         }  
  411.         log_fd = log_fds_kernel[(int)log_id];  
  412.     } else {  
  413.         return -EBADF;  
  414.     }  
  415.   
  416.     do {  
  417.         ret = log_writev(log_fd, vec, nr);  
  418.         if (ret < 0) {  
  419.             ret = -errno;  
  420.         }  
  421.     } while (ret == -EINTR);  
  422.   
  423.     return ret;  
  424. }  
  425.   
  426. static int __write_to_log_init_kernel(log_id_t log_id, struct iovec *vec, size_t nr)  
  427. {  
  428.     pthread_mutex_lock(&log_init_lock);  
  429.   
  430.     if (write_to_log == __write_to_log_init) {  
  431.         log_fds_kernel[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);  
  432.         log_fds_kernel[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);  
  433.         log_fds_kernel[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);  
  434.         log_fds_kernel[LOG_ID_SYSTEM] = log_open("/dev/"LOGGER_LOG_SYSTEM, O_WRONLY);  
  435.   
  436.         write_to_log = __write_to_log_kernel;  
  437.   
  438.         if (log_fds_kernel[LOG_ID_MAIN] < 0 || log_fds_kernel[LOG_ID_RADIO] < 0 ||  
  439.                 log_fds_kernel[LOG_ID_EVENTS] < 0) {  
  440.             log_close(log_fds_kernel[LOG_ID_MAIN]);  
  441.             log_close(log_fds_kernel[LOG_ID_RADIO]);  
  442.             log_close(log_fds_kernel[LOG_ID_EVENTS]);  
  443.             log_fds_kernel[LOG_ID_MAIN] = -1;  
  444.             log_fds_kernel[LOG_ID_RADIO] = -1;  
  445.             log_fds_kernel[LOG_ID_EVENTS] = -1;  
  446.             write_to_log = __write_to_log_null;  
  447.         }  
  448.   
  449.         if (log_fds_kernel[LOG_ID_SYSTEM] < 0) {  
  450.             log_fds_kernel[LOG_ID_SYSTEM] = log_fds_kernel[LOG_ID_MAIN];  
  451.         }  
  452.     }  
  453.   
  454.     pthread_mutex_unlock(&log_init_lock);  
  455.   
  456.     return write_to_log(log_id, vec, nr);  
  457. }  
  458.   
  459. static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) {  
  460. #if (FAKE_LOG_DEVICE == 0)  
  461.     int fd;  
  462.     fd = open("system/etc/disable_logd", O_RDONLY);//是否有disable_logd文件  
  463.     if (fd > 0) {  
  464.         use_logd = 0;  
  465.         close(fd);  
  466.     }  
  467. #endif  
  468.   
  469.     if(use_logd) {  
  470.         return __write_to_log_init_logd(log_id, vec, nr);  
  471.     } else {  
  472.         return __write_to_log_init_kernel(log_id, vec, nr);  
  473.     }  
  474. }  
  475.   
  476. int __android_log_write(int prio, const char *tag, const char *msg)  
  477. {  
  478.     return __android_log_buf_write(LOG_ID_MAIN, prio, tag, msg);  
  479. }  
  480.   
  481. int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)  
  482. {  
  483.     struct iovec vec[3];  
  484.     char tmp_tag[32];  
  485.   
  486.     if (!tag)  
  487.         tag = "";  
  488.   
  489.     /* XXX: This needs to go! */  
  490.     if ((bufID != LOG_ID_RADIO) &&  
  491.          (!strcmp(tag, "HTC_RIL") ||  
  492.         !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */  
  493.         !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */  
  494.         !strcmp(tag, "AT") ||  
  495.         !strcmp(tag, "GSM") ||  
  496.         !strcmp(tag, "STK") ||  
  497.         !strcmp(tag, "CDMA") ||  
  498.         !strcmp(tag, "PHONE") ||  
  499.         !strcmp(tag, "SMS"))) {  
  500.             bufID = LOG_ID_RADIO;  
  501.             /* Inform third party apps/ril/radio.. to use Rlog or RLOG */  
  502.             snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);  
  503.             tag = tmp_tag;  
  504.     }  
  505.   
  506. #if __BIONIC__  
  507.     if (prio == ANDROID_LOG_FATAL) {  
  508.         android_set_abort_message(msg);  
  509.     }  
  510. #endif  
  511.   
  512.     vec[0].iov_base   = (unsigned char *) &prio;  
  513.     vec[0].iov_len    = 1;  
  514.     vec[1].iov_base   = (void *) tag;  
  515.     vec[1].iov_len    = strlen(tag) + 1;  
  516.     vec[2].iov_base   = (void *) msg;  
  517.     vec[2].iov_len    = strlen(msg) + 1;  
  518.   
  519.     return write_to_log(bufID, vec, 3);  
  520. }  
  521.   
  522. int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap)  
  523. {  
  524.     char buf[LOG_BUF_SIZE];  
  525.   
  526.     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  527.   
  528.     return __android_log_write(prio, tag, buf);  
  529. }  
  530.   
  531. int __android_log_print(int prio, const char *tag, const char *fmt, ...)  
  532. {  
  533.     va_list ap;  
  534.     char buf[LOG_BUF_SIZE];  
  535.   
  536.     va_start(ap, fmt);  
  537.     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  538.     va_end(ap);  
  539.   
  540.     return __android_log_write(prio, tag, buf);  
  541. }  
  542.   
  543. int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)  
  544. {  
  545.     va_list ap;  
  546.     char buf[LOG_BUF_SIZE];  
  547.   
  548.     va_start(ap, fmt);  
  549.     vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  550.     va_end(ap);  
  551.   
  552.     return __android_log_buf_write(bufID, prio, tag, buf);  
  553. }  
  554.   
  555. void __android_log_assert(const char *cond, const char *tag,  
  556.                           const char *fmt, ...)  
  557. {  
  558.     char buf[LOG_BUF_SIZE];  
  559.   
  560.     if (fmt) {  
  561.         va_list ap;  
  562.         va_start(ap, fmt);  
  563.         vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
  564.         va_end(ap);  
  565.     } else {  
  566.         /* Msg not provided, log condition.  N.B. Do not use cond directly as 
  567.          * format string as it could contain spurious '%' syntax (e.g. 
  568.          * "%d" in "blocks%devs == 0"). 
  569.          */  
  570.         if (cond)  
  571.             snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);  
  572.         else  
  573.             strcpy(buf, "Unspecified assertion failed");  
  574.     }  
  575.   
  576.     __android_log_write(ANDROID_LOG_FATAL, tag, buf);  
  577.     abort(); /* abort so we have a chance to debug the situation */  
  578.     /* NOTREACHED */  
  579. }  
  580.   
  581. int __android_log_bwrite(int32_t tag, const void *payload, size_t len)  
  582. {  
  583.     struct iovec vec[2];  
  584.   
  585.     vec[0].iov_base = &tag;  
  586.     vec[0].iov_len = sizeof(tag);  
  587.     vec[1].iov_base = (void*)payload;  
  588.     vec[1].iov_len = len;  
  589.   
  590.     return write_to_log(LOG_ID_EVENTS, vec, 2);  
  591. }  
  592.   
  593. /* 
  594.  * Like __android_log_bwrite, but takes the type as well.  Doesn't work 
  595.  * for the general case where we're generating lists of stuff, but very 
  596.  * handy if we just want to dump an integer into the log. 
  597.  */  
  598. int __android_log_btwrite(int32_t tag, char type, const void *payload,  
  599.                           size_t len)  
  600. {  
  601.     struct iovec vec[3];  
  602.   
  603.     vec[0].iov_base = &tag;  
  604.     vec[0].iov_len = sizeof(tag);  
  605.     vec[1].iov_base = &type;  
  606.     vec[1].iov_len = sizeof(type);  
  607.     vec[2].iov_base = (void*)payload;  
  608.     vec[2].iov_len = len;  
  609.   
  610.     return write_to_log(LOG_ID_EVENTS, vec, 3);  
  611. }  
  612.   
  613. /* 
  614.  * Like __android_log_bwrite, but used for writing strings to the 
  615.  * event log. 
  616.  */  
  617. int __android_log_bswrite(int32_t tag, const char *payload)  
  618. {  
  619.     struct iovec vec[4];  
  620.     char type = EVENT_TYPE_STRING;  
  621.     uint32_t len = strlen(payload);  
  622.   
  623.     vec[0].iov_base = &tag;  
  624.     vec[0].iov_len = sizeof(tag);  
  625.     vec[1].iov_base = &type;  
  626.     vec[1].iov_len = sizeof(type);  
  627.     vec[2].iov_base = &len;  
  628.     vec[2].iov_len = sizeof(len);  
  629.     vec[3].iov_base = (void*)payload;  
  630.     vec[3].iov_len = len;  
  631.   
  632.     return write_to_log(LOG_ID_EVENTS, vec, 4);  
  633. }  

另外一个就是log_read_common.c文件,将log_read.c和log_read_kern.c合并。这样文件稍微复杂一点,因为在log_read.c和log_read_kern.c中都使用了struct logger_list 和struct logger结构体而且不一样,这样我们将共同部分做了一个基类的struct logger_list 和struct logger结构体。而在合并文件中定义了struct logger_list_logd struct logger_list_kernel结构体,将其基类放在第一个变量base中。而使用指针时,对外返回的指针强制转成基类,进入的指针强制转到相关的子类。因为基类的数据结构在子类结构体中是第一个,因此子类指针强转成父类,也是能正确调用到父类的变量的。

还有我们也是用use_logd这个全局变量来控制log机制的,并且定义了一个对外的函数set_uselogd. 因为使用read这块是在logcat进程中使用的,我们需要在logcat中调用。

[cpp]  view plain  copy
  1. /* 
  2. ** Copyright 2013-2014, The Android Open Source Project 
  3. ** 
  4. ** Licensed under the Apache License, Version 2.0 (the "License"); 
  5. ** you may not use this file except in compliance with the License. 
  6. ** You may obtain a copy of the License at 
  7. ** 
  8. **     http://www.apache.org/licenses/LICENSE-2.0 
  9. ** 
  10. ** Unless required by applicable law or agreed to in writing, software 
  11. ** distributed under the License is distributed on an "AS IS" BASIS, 
  12. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13. ** See the License for the specific language governing permissions and 
  14. ** limitations under the License. 
  15. */  
  16. #define _GNU_SOURCE /* asprintf for x86 host */  
  17. #include <errno.h>  
  18. #include <fcntl.h>  
  19. #include <inttypes.h>  
  20. #include <poll.h>  
  21. #include <signal.h>  
  22. #include <stdbool.h>  
  23. #include <stddef.h>  
  24. #define NOMINMAX /* for windows to suppress definition of min in stdlib.h */  
  25. #include <stdlib.h>  
  26. #include <string.h>  
  27. #include <sys/cdefs.h>  
  28. #include <sys/ioctl.h>  
  29. #include <unistd.h>  
  30. #include <string.h>  
  31. #include <stdio.h>  
  32.   
  33. #include <cutils/list.h>  
  34. #include <cutils/sockets.h>  
  35. #include <log/log.h>  
  36. #include <log/logger.h>  
  37. #include <private/android_filesystem_config.h>  
  38. #include <private/android_logger.h>  
  39.   
  40. #include <cutils/sockets.h>  
  41.   
  42. #define __LOGGERIO     0xAE  
  43.   
  44. #define LOGGER_GET_LOG_BUF_SIZE    _IO(__LOGGERIO, 1) /* size of log */  
  45. #define LOGGER_GET_LOG_LEN         _IO(__LOGGERIO, 2) /* used log len */  
  46. #define LOGGER_GET_NEXT_ENTRY_LEN  _IO(__LOGGERIO, 3) /* next entry len */  
  47. #define LOGGER_FLUSH_LOG           _IO(__LOGGERIO, 4) /* flush log */  
  48. #define LOGGER_GET_VERSION         _IO(__LOGGERIO, 5) /* abi version */  
  49. #define LOGGER_SET_VERSION         _IO(__LOGGERIO, 6) /* abi version */  
  50.   
  51. #define LOG_FILE_DIR "/dev/log/"  
  52.   
  53. /* timeout in milliseconds */  
  54. #define LOG_TIMEOUT_FLUSH 5  
  55. #define LOG_TIMEOUT_NEVER -1  
  56.   
  57. /* branchless on many architectures. */  
  58. #define min(x,y) ((y) ^ (((x) ^ (y)) & -((x) < (y))))  
  59.   
  60. #if (defined(USE_MINGW) || defined(HAVE_WINSOCK))  
  61. #define WEAK static  
  62. #else  
  63. #define WEAK __attribute__((weak))  
  64. #endif  
  65. #ifndef __unused  
  66. #define __unused __attribute__((unused))  
  67. #endif  
  68.   
  69. static int8_t use_logd = 1;//版本控制  
  70.   
  71. void set_uselogd(int8_t uselogd) {//对外函数  
  72.     use_logd = uselogd;  
  73. }  
  74.   
  75. /* Private copy of ../libcutils/socket_local_client.c prevent library loops */  
  76.   
  77. #ifdef HAVE_WINSOCK  
  78.   
  79. int WEAK socket_local_client(const char *name, int namespaceId, int type)  
  80. {  
  81.     errno = ENOSYS;  
  82.     return -ENOSYS;  
  83. }  
  84.   
  85. #else /* !HAVE_WINSOCK */  
  86.   
  87. #include <sys/socket.h>  
  88. #include <sys/un.h>  
  89. #include <sys/select.h>  
  90. #include <sys/types.h>  
  91.   
  92. /* Private copy of ../libcutils/socket_local.h prevent library loops */  
  93. #define FILESYSTEM_SOCKET_PREFIX "/tmp/"  
  94. #define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/"  
  95. /* End of ../libcutils/socket_local.h */  
  96.   
  97. #define LISTEN_BACKLOG 4  
  98.   
  99. /* Documented in header file. */  
  100. int WEAK socket_make_sockaddr_un(const char *name, int namespaceId,  
  101.                                  struct sockaddr_un *p_addr, socklen_t *alen)  
  102. {  
  103.     memset (p_addr, 0, sizeof (*p_addr));  
  104.     size_t namelen;  
  105.   
  106.     switch (namespaceId) {  
  107.     case ANDROID_SOCKET_NAMESPACE_ABSTRACT:  
  108. #if defined(__linux__)  
  109.         namelen  = strlen(name);  
  110.   
  111.         /* Test with length +1 for the *initial* '\0'. */  
  112.         if ((namelen + 1) > sizeof(p_addr->sun_path)) {  
  113.             goto error;  
  114.         }  
  115.   
  116.         /* 
  117.          * Note: The path in this case is *not* supposed to be 
  118.          * '\0'-terminated. ("man 7 unix" for the gory details.) 
  119.          */  
  120.   
  121.         p_addr->sun_path[0] = 0;  
  122.         memcpy(p_addr->sun_path + 1, name, namelen);  
  123. #else  
  124.         /* this OS doesn't have the Linux abstract namespace */  
  125.   
  126.         namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX);  
  127.         /* unix_path_max appears to be missing on linux */  
  128.         if (namelen > sizeof(*p_addr)  
  129.                 - offsetof(struct sockaddr_un, sun_path) - 1) {  
  130.             goto error;  
  131.         }  
  132.   
  133.         strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX);  
  134.         strcat(p_addr->sun_path, name);  
  135. #endif  
  136.         break;  
  137.   
  138.     case ANDROID_SOCKET_NAMESPACE_RESERVED:  
  139.         namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX);  
  140.         /* unix_path_max appears to be missing on linux */  
  141.         if (namelen > sizeof(*p_addr)  
  142.                 - offsetof(struct sockaddr_un, sun_path) - 1) {  
  143.             goto error;  
  144.         }  
  145.   
  146.         strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX);  
  147.         strcat(p_addr->sun_path, name);  
  148.         break;  
  149.   
  150.     case ANDROID_SOCKET_NAMESPACE_FILESYSTEM:  
  151.         namelen = strlen(name);  
  152.         /* unix_path_max appears to be missing on linux */  
  153.         if (namelen > sizeof(*p_addr)  
  154.                 - offsetof(struct sockaddr_un, sun_path) - 1) {  
  155.             goto error;  
  156.         }  
  157.   
  158.         strcpy(p_addr->sun_path, name);  
  159.         break;  
  160.   
  161.     default:  
  162.         /* invalid namespace id */  
  163.         return -1;  
  164.     }  
  165.   
  166.     p_addr->sun_family = AF_LOCAL;  
  167.     *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;  
  168.     return 0;  
  169. error:  
  170.     return -1;  
  171. }  
  172.   
  173. /** 
  174.  * connect to peer named "name" on fd 
  175.  * returns same fd or -1 on error. 
  176.  * fd is not closed on error. that's your job. 
  177.  * 
  178.  * Used by AndroidSocketImpl 
  179.  */  
  180. int WEAK socket_local_client_connect(int fd, const char *name, int namespaceId,  
  181.                                      int type __unused)  
  182. {  
  183.     struct sockaddr_un addr;  
  184.     socklen_t alen;  
  185.     int err;  
  186.   
  187.     err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen);  
  188.   
  189.     if (err < 0) {  
  190.         goto error;  
  191.     }  
  192.   
  193.     if(connect(fd, (struct sockaddr *) &addr, alen) < 0) {  
  194.         goto error;  
  195.     }  
  196.   
  197.     return fd;  
  198.   
  199. error:  
  200.     return -1;  
  201. }  
  202.   
  203. /** 
  204.  * connect to peer named "name" 
  205.  * returns fd or -1 on error 
  206.  */  
  207. int WEAK socket_local_client(const char *name, int namespaceId, int type)  
  208. {  
  209.     int s;  
  210.   
  211.     s = socket(AF_LOCAL, type, 0);  
  212.     if(s < 0) return -1;  
  213.   
  214.     if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) {  
  215.         close(s);  
  216.         return -1;  
  217.     }  
  218.   
  219.     return s;  
  220. }  
  221.   
  222. #endif /* !HAVE_WINSOCK */  
  223. /* End of ../libcutils/socket_local_client.c */  
  224.   
  225. #define logger_for_each(logger, logger_list) \  
  226.     for (logger = node_to_item((logger_list)->node.next, struct logger, node); \  
  227.          logger != node_to_item(&(logger_list)->node, struct logger, node); \  
  228.          logger = node_to_item((logger)->node.next, struct logger, node))  
  229.   
  230. #ifndef __unused  
  231. #define __unused __attribute__((unused))  
  232. #endif  
  233.   
  234. /* In the future, we would like to make this list extensible */  
  235. static const char *LOG_NAME[LOG_ID_MAX] = {  
  236.     [LOG_ID_MAIN] = "main",  
  237.     [LOG_ID_RADIO] = "radio",  
  238.     [LOG_ID_EVENTS] = "events",  
  239.     [LOG_ID_SYSTEM] = "system",  
  240.     [LOG_ID_CRASH] = "crash",  
  241.     [LOG_ID_KERNEL] = "kernel",  
  242. };  
  243.   
  244. const char *android_log_id_to_name(log_id_t log_id)  
  245. {  
  246.     if (log_id >= LOG_ID_MAX) {  
  247.         log_id = LOG_ID_MAIN;  
  248.     }  
  249.     return LOG_NAME[log_id];  
  250. }  
  251.   
  252. static int accessmode(int mode)  
  253. {  
  254.     if ((mode & ANDROID_LOG_ACCMODE) == ANDROID_LOG_WRONLY) {  
  255.         return W_OK;  
  256.     }  
  257.     if ((mode & ANDROID_LOG_ACCMODE) == ANDROID_LOG_RDWR) {  
  258.         return R_OK | W_OK;  
  259.     }  
  260.     return R_OK;  
  261. }  
  262.   
  263. /* repeated fragment */  
  264. static int check_allocate_accessible(char **n, const char *b, int mode)  
  265. {  
  266.     *n = NULL;  
  267.   
  268.     if (!b) {  
  269.         return -EINVAL;  
  270.     }  
  271.   
  272.     asprintf(n, LOG_FILE_DIR "%s", b);  
  273.     if (!*n) {  
  274.         return -1;  
  275.     }  
  276.   
  277.     return access(*n, accessmode(mode));  
  278. }  
  279.   
  280. log_id_t android_name_to_log_id_logd(const char *logName)  
  281. {  
  282.     const char *b;  
  283.     int ret;  
  284.   
  285.     if (!logName) {  
  286.         return -1; /* NB: log_id_t is unsigned */  
  287.     }  
  288.     b = strrchr(logName, '/');  
  289.     if (!b) {  
  290.         b = logName;  
  291.     } else {  
  292.         ++b;  
  293.     }  
  294.   
  295.     for(ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) {  
  296.         const char *l = LOG_NAME[ret];  
  297.         if (l && !strcmp(b, l)) {  
  298.             return ret;  
  299.         }  
  300.     }  
  301.     return -1;   /* should never happen */  
  302. }  
  303.   
  304. log_id_t android_name_to_log_id_kernel(const char *logName)  
  305. {  
  306.     const char *b;  
  307.     char *n;  
  308.     int ret;  
  309.   
  310.     if (!logName) {  
  311.         return -1; /* NB: log_id_t is unsigned */  
  312.     }  
  313.     b = strrchr(logName, '/');  
  314.     if (!b) {  
  315.         b = logName;  
  316.     } else {  
  317.         ++b;  
  318.     }  
  319.   
  320.     ret = check_allocate_accessible(&n, b, ANDROID_LOG_RDONLY);  
  321.     free(n);  
  322.     if (ret) {  
  323.         return ret;  
  324.     }  
  325.   
  326.     for(ret = LOG_ID_MIN; ret < LOG_ID_MAX; ++ret) {  
  327.         const char *l = LOG_NAME[ret];  
  328.         if (l && !strcmp(b, l)) {  
  329.             return ret;  
  330.         }  
  331.     }  
  332.     return -1;   /* should never happen */  
  333. }  
  334.   
  335. log_id_t android_name_to_log_id(const char *logName) {  
  336.     if (use_logd) {  
  337.         return android_name_to_log_id_logd(logName);  
  338.     } else {  
  339.         return android_name_to_log_id_kernel(logName);  
  340.     }  
  341. }  
  342.   
  343. struct logger_list {//基类结构体  
  344.     struct listnode node;  
  345.     int mode;  
  346.     unsigned int tail;  
  347.     pid_t pid;  
  348. };  
  349.   
  350. struct logger_list_logd {//logd机制结构体  
  351.     struct logger_list base;  
  352.     log_time start;  
  353.     int sock;  
  354. };  
  355.   
  356. struct logger_list_kernel {//kernel机制结构体  
  357.     struct logger_list base;  
  358.     unsigned int queued_lines;  
  359.     int timeout_ms;  
  360.     int error;  
  361.     bool flush;  
  362.     bool valid_entry; /* valiant(?) effort to deal with memory starvation */  
  363.     struct log_msg entry;  
  364. };  
  365.   
  366. struct logger {  
  367.     struct listnode node;  
  368.     struct logger_list *top;  
  369.     log_id_t id;  
  370. };  
  371.   
  372. struct log_list {  
  373.     struct listnode node;  
  374.     struct log_msg entry; /* Truncated to event->len() + 1 to save space */  
  375. };  
  376.   
  377. struct logger_kernel {  
  378.     struct logger base;  
  379.     int fd;  
  380.     short *revents;  
  381.     struct listnode log_list;  
  382. };  
  383.   
  384. /* android_logger_alloc unimplemented, no use case */  
  385. /* android_logger_free not exported */  
  386. static void android_logger_free_logd(struct logger *logger)  
  387. {  
  388.     if (!logger) {  
  389.         return;  
  390.     }  
  391.   
  392.     list_remove(&logger->node);  
  393.   
  394.     free(logger);  
  395. }  
  396.   
  397. /* android_logger_alloc unimplemented, no use case */  
  398. /* android_logger_free not exported */  
  399. static void android_logger_free_kernel(struct logger *logger)  
  400. {  
  401.     if (!logger) {  
  402.         return;  
  403.     }  
  404.     struct logger_kernel *logger_kernel = (struct logger_kernel*)logger;  
  405.     struct logger_list_kernel *logger_list_kernel;  
  406.     while (!list_empty(&logger_kernel->log_list)) {  
  407.         struct log_list *entry = node_to_item(  
  408.             list_head(&logger_kernel->log_list), struct log_list, node);  
  409.         list_remove(&entry->node);  
  410.         free(entry);  
  411.         logger_list_kernel = (struct logger_list_kernel *)(logger_kernel->base.top);  
  412.         if (logger_list_kernel->queued_lines) {  
  413.             logger_list_kernel->queued_lines--;  
  414.         }  
  415.     }  
  416.   
  417.     if (logger_kernel->fd >= 0) {  
  418.         close(logger_kernel->fd);  
  419.     }  
  420.   
  421.     list_remove(&logger_kernel->base.node);  
  422.   
  423.     free(logger_kernel);  
  424. }  
  425.   
  426. /* android_logger_alloc unimplemented, no use case */  
  427. /* android_logger_free not exported */  
  428. void android_logger_free(struct logger *logger)  
  429. {  
  430.     if (use_logd) {  
  431.         android_logger_free_logd(logger);  
  432.     } else {  
  433.         android_logger_free_kernel(logger);  
  434.     }  
  435. }  
  436.   
  437. /* android_logger_alloc unimplemented, no use case */  
  438.   
  439. /* method for getting the associated sublog id */  
  440. log_id_t android_logger_get_id(struct logger *logger)  
  441. {  
  442.     return logger->id;  
  443. }  
  444.   
  445. /* worker for sending the command to the logger */  
  446. static ssize_t send_log_msg(struct logger *logger,  
  447.                             const char *msg, char *buf, size_t buf_size)  
  448. {  
  449.     ssize_t ret;  
  450.     size_t len;  
  451.     char *cp;  
  452.     int errno_save = 0;  
  453.     int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,  
  454.                                    SOCK_STREAM);  
  455.     if (sock < 0) {  
  456.         return sock;  
  457.     }  
  458.   
  459.     if (msg) {  
  460.         snprintf(buf, buf_size, msg, logger ? logger->id : (unsigned) -1);  
  461.     }  
  462.   
  463.     len = strlen(buf) + 1;  
  464.     ret = TEMP_FAILURE_RETRY(write(sock, buf, len));  
  465.     if (ret <= 0) {  
  466.         goto done;  
  467.     }  
  468.   
  469.     len = buf_size;  
  470.     cp = buf;  
  471.     while ((ret = TEMP_FAILURE_RETRY(read(sock, cp, len))) > 0) {  
  472.         struct pollfd p;  
  473.   
  474.         if (((size_t)ret == len) || (buf_size < PAGE_SIZE)) {  
  475.             break;  
  476.         }  
  477.   
  478.         len -= ret;  
  479.         cp += ret;  
  480.   
  481.         memset(&p, 0, sizeof(p));  
  482.         p.fd = sock;  
  483.         p.events = POLLIN;  
  484.   
  485.         /* Give other side 20ms to refill pipe */  
  486.         ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20));  
  487.   
  488.         if (ret <= 0) {  
  489.             break;  
  490.         }  
  491.   
  492.         if (!(p.revents & POLLIN)) {  
  493.             ret = 0;  
  494.             break;  
  495.         }  
  496.     }  
  497.   
  498.     if (ret >= 0) {  
  499.         ret += buf_size - len;  
  500.     }  
  501.   
  502. done:  
  503.     if ((ret == -1) && errno) {  
  504.         errno_save = errno;  
  505.     }  
  506.     close(sock);  
  507.     if (errno_save) {  
  508.         errno = errno_save;  
  509.     }  
  510.     return ret;  
  511. }  
  512.   
  513.   
  514. /* worker for sending the command to the logger */  
  515. static int logger_ioctl(struct logger *logger, int cmd, int mode)  
  516. {  
  517.     char *n;  
  518.     int  f, ret;  
  519.     struct logger_kernel* logger_kernel = (struct logger_kernel*)logger;  
  520.     if (!logger_kernel || !logger_kernel->base.top) {  
  521.         return -EFAULT;  
  522.     }  
  523.   
  524.     if (((mode & ANDROID_LOG_ACCMODE) == ANDROID_LOG_RDWR)  
  525.             || (((mode ^ logger_kernel->base.top->mode) & ANDROID_LOG_ACCMODE) == 0)) {  
  526.         return ioctl(logger_kernel->fd, cmd);  
  527.     }  
  528.   
  529.     /* We go here if android_logger_list_open got mode wrong for this ioctl */  
  530.     ret = check_allocate_accessible(&n, android_log_id_to_name(logger_kernel->base.id), mode);  
  531.     if (ret) {  
  532.         free(n);  
  533.         return ret;  
  534.     }  
  535.   
  536.     f = open(n, mode);  
  537.     free(n);  
  538.     if (f < 0) {  
  539.         return f;  
  540.     }  
  541.   
  542.     ret = ioctl(f, cmd);  
  543.     close (f);  
  544.   
  545.     return ret;  
  546. }  
  547.   
  548. static int check_log_success(char *buf, ssize_t ret)  
  549. {  
  550.     if (ret < 0) {  
  551.         return ret;  
  552.     }  
  553.   
  554.     if (strncmp(buf, "success", 7)) {  
  555.         errno = EINVAL;  
  556.         return -1;  
  557.     }  
  558.   
  559.     return 0;  
  560. }  
  561.   
  562. /* Determine the credentials of the caller */  
  563. static bool uid_has_log_permission(uid_t uid)  
  564. {  
  565.     return (uid == AID_SYSTEM) || (uid == AID_LOG) || (uid == AID_ROOT);  
  566. }  
  567.   
  568. static uid_t get_best_effective_uid()  
  569. {  
  570.     uid_t euid;  
  571.     uid_t uid;  
  572.     gid_t gid;  
  573.     ssize_t i;  
  574.     static uid_t last_uid = (uid_t) -1;  
  575.   
  576.     if (last_uid != (uid_t) -1) {  
  577.         return last_uid;  
  578.     }  
  579.     uid = getuid();  
  580.     if (uid_has_log_permission(uid)) {  
  581.         return last_uid = uid;  
  582.     }  
  583.     euid = geteuid();  
  584.     if (uid_has_log_permission(euid)) {  
  585.         return last_uid = euid;  
  586.     }  
  587.     gid = getgid();  
  588.     if (uid_has_log_permission(gid)) {  
  589.         return last_uid = gid;  
  590.     }  
  591.     gid = getegid();  
  592.     if (uid_has_log_permission(gid)) {  
  593.         return last_uid = gid;  
  594.     }  
  595.     i = getgroups((size_t) 0, NULL);  
  596.     if (i > 0) {  
  597.         gid_t list[i];  
  598.   
  599.         getgroups(i, list);  
  600.         while (--i >= 0) {  
  601.             if (uid_has_log_permission(list[i])) {  
  602.                 return last_uid = list[i];  
  603.             }  
  604.         }  
  605.     }  
  606.     return last_uid = uid;  
  607. }  
  608.   
  609. static int android_logger_clear_logd(struct logger *logger)  
  610. {  
  611.     char buf[512];  
  612.   
  613.     if (logger->top->mode & ANDROID_LOG_PSTORE) {  
  614.         if (uid_has_log_permission(get_best_effective_uid())) {  
  615.             return unlink("/sys/fs/pstore/pmsg-ramoops-0");  
  616.         }  
  617.         errno = EPERM;  
  618.         return -1;  
  619.     }  
  620.     return check_log_success(buf,  
  621.         send_log_msg(logger, "clear %d", buf, sizeof(buf)));  
  622. }  
  623.   
  624. static int android_logger_clear_kernel(struct logger *logger)  
  625. {  
  626.     return logger_ioctl(logger, LOGGER_FLUSH_LOG, ANDROID_LOG_WRONLY);  
  627. }  
  628.   
  629. int android_logger_clear(struct logger *logger)  
  630. {  
  631.     if (use_logd) {  
  632.         return android_logger_clear_logd(logger);  
  633.     } else {  
  634.         return android_logger_clear_kernel(logger);  
  635.     }  
  636. }  
  637.   
  638. /* returns the total size of the log's ring buffer */  
  639. static long android_logger_get_log_size_logd(struct logger *logger)  
  640. {  
  641.     char buf[512];  
  642.   
  643.     ssize_t ret = send_log_msg(logger, "getLogSize %d", buf, sizeof(buf));  
  644.     if (ret < 0) {  
  645.         return ret;  
  646.     }  
  647.   
  648.     if ((buf[0] < '0') || ('9' < buf[0])) {  
  649.         return -1;  
  650.     }  
  651.   
  652.     return atol(buf);  
  653. }  
  654.   
  655. /* returns the total size of the log's ring buffer */  
  656. static long android_logger_get_log_size_kernel(struct logger *logger)  
  657. {  
  658.     return logger_ioctl(logger, LOGGER_GET_LOG_BUF_SIZE, ANDROID_LOG_RDWR);  
  659. }  
  660.   
  661. /* returns the total size of the log's ring buffer */  
  662. long android_logger_get_log_size(struct logger *logger)  
  663. {  
  664.     if (use_logd) {  
  665.         return android_logger_get_log_size_logd(logger);  
  666.     } else {  
  667.         return android_logger_get_log_size_kernel(logger);  
  668.     }  
  669. }  
  670.   
  671. int android_logger_set_log_size(struct logger *logger, unsigned long size)  
  672. {  
  673.     if (use_logd) {  
  674.         char buf[512];  
  675.   
  676.         snprintf(buf, sizeof(buf), "setLogSize %d %lu",  
  677.             logger ? logger->id : (unsigned) -1, size);  
  678.   
  679.         return check_log_success(buf, send_log_msg(NULL, NULL, buf, sizeof(buf)));  
  680.     } else {  
  681.         return -ENOTSUP;  
  682.     }  
  683.   
  684. }  
  685.   
  686. /* 
  687.  * returns the readable size of the log's ring buffer (that is, amount of the 
  688.  * log consumed) 
  689.  */  
  690. static long android_logger_get_log_readable_size_logd(struct logger *logger)  
  691. {  
  692.     char buf[512];  
  693.   
  694.     ssize_t ret = send_log_msg(logger, "getLogSizeUsed %d", buf, sizeof(buf));  
  695.     if (ret < 0) {  
  696.         return ret;  
  697.     }  
  698.   
  699.     if ((buf[0] < '0') || ('9' < buf[0])) {  
  700.         return -1;  
  701.     }  
  702.   
  703.     return atol(buf);  
  704. }  
  705.   
  706. /* 
  707.  * returns the readable size of the log's ring buffer (that is, amount of the 
  708.  * log consumed) 
  709.  */  
  710. static long android_logger_get_log_readable_size_kernel(struct logger *logger)  
  711. {  
  712.     return logger_ioctl(logger, LOGGER_GET_LOG_LEN, ANDROID_LOG_RDONLY);  
  713. }  
  714.   
  715. /* 
  716.  * returns the readable size of the log's ring buffer (that is, amount of the 
  717.  * log consumed) 
  718.  */  
  719. long android_logger_get_log_readable_size(struct logger *logger)  
  720. {  
  721.     if (use_logd) {  
  722.         return android_logger_get_log_readable_size_logd(logger);  
  723.     } else {  
  724.         return android_logger_get_log_readable_size_kernel(logger);  
  725.     }  
  726. }  
  727.   
  728. /* 
  729.  * returns the logger version 
  730.  */  
  731. int android_logger_get_log_version(struct logger *logger __unused)  
  732. {  
  733.     if (use_logd) {  
  734.         return 3;  
  735.     } else {  
  736.         int ret = logger_ioctl(logger, LOGGER_GET_VERSION, ANDROID_LOG_RDWR);  
  737.         return (ret < 0) ? 1 : ret;  
  738.     }  
  739.   
  740. }  
  741.   
  742. /* 
  743.  * returns statistics 
  744.  */  
  745. static const char unsupported[] = "18\nNot Supported\n\f";  
  746.   
  747. ssize_t android_logger_get_statistics(struct logger_list *logger_list,  
  748.                                       char *buf, size_t len)  
  749. {  
  750.     if (use_logd) {  
  751.         struct logger *logger;  
  752.         char *cp = buf;  
  753.         size_t remaining = len;  
  754.         size_t n;  
  755.   
  756.         n = snprintf(cp, remaining, "getStatistics");  
  757.         n = min(n, remaining);  
  758.         remaining -= n;  
  759.         cp += n;  
  760.   
  761.         logger_for_each(logger, logger_list) {  
  762.             n = snprintf(cp, remaining, " %d", logger->id);  
  763.             n = min(n, remaining);  
  764.             remaining -= n;  
  765.             cp += n;  
  766.         }  
  767.         return send_log_msg(NULL, NULL, buf, len);  
  768.     } else {  
  769.         strncpy(buf, unsupported, len);  
  770.         return -ENOTSUP;  
  771.     }  
  772. }  
  773.   
  774. ssize_t android_logger_get_prune_list(struct logger_list *logger_list __unused,  
  775.                                       char *buf, size_t len)  
  776. {  
  777.     if (use_logd) {  
  778.         return send_log_msg(NULL, "getPruneList", buf, len);  
  779.     } else {  
  780.         strncpy(buf, unsupported, len);  
  781.         return -ENOTSUP;  
  782.     }  
  783. }  
  784.   
  785. int android_logger_set_prune_list(struct logger_list *logger_list __unused,  
  786.                                   char *buf, size_t len)  
  787. {  
  788.     if (use_logd) {  
  789.         const char cmd[] = "setPruneList ";  
  790.         const size_t cmdlen = sizeof(cmd) - 1;  
  791.   
  792.         if (strlen(buf) > (len - cmdlen)) {  
  793.             return -ENOMEM; /* KISS */  
  794.         }  
  795.         memmove(buf + cmdlen, buf, len - cmdlen);  
  796.         buf[len - 1] = '\0';  
  797.         memcpy(buf, cmd, cmdlen);  
  798.   
  799.         return check_log_success(buf, send_log_msg(NULL, NULL, buf, len));  
  800.     } else {  
  801.         static const char unsupported_error[] = "Unsupported";  
  802.         strncpy(buf, unsupported, len);  
  803.         return -ENOTSUP;  
  804.     }  
  805. }  
  806.   
  807. static struct logger_list *android_logger_list_alloc_logd(int mode,  
  808.                                               unsigned int tail,  
  809.                                               pid_t pid)  
  810. {  
  811.     struct logger_list_logd *logger_list_logd;  
  812.   
  813.     logger_list_logd = calloc(1, sizeof(*logger_list_logd));  
  814.     if (!logger_list_logd) {  
  815.         return NULL;  
  816.     }  
  817.   
  818.     list_init(&logger_list_logd->base.node);  
  819.     logger_list_logd->base.mode = mode;  
  820.     logger_list_logd->start.tv_sec = 0;  
  821.     logger_list_logd->start.tv_nsec = 0;  
  822.     logger_list_logd->base.tail = tail;  
  823.     logger_list_logd->base.pid = pid;  
  824.     logger_list_logd->sock = -1;  
  825.   
  826.     return (struct logger_list *)logger_list_logd;  
  827. }  
  828.   
  829. static struct logger_list *android_logger_list_alloc_kernel(int mode,  
  830.                                               unsigned int tail,  
  831.                                               pid_t pid)  
  832. {  
  833.     struct logger_list_kernel *logger_list_kernel;  
  834.   
  835.     logger_list_kernel = calloc(1, sizeof(*logger_list_kernel));  
  836.     if (!logger_list_kernel) {  
  837.         return NULL;  
  838.     }  
  839.     list_init(&logger_list_kernel->base.node);  
  840.     logger_list_kernel->base.mode = mode;  
  841.     logger_list_kernel->base.tail = tail;  
  842.     logger_list_kernel->base.pid = pid;  
  843.     return (struct logger_list *)logger_list_kernel;  
  844. }  
  845.   
  846. struct logger_list *android_logger_list_alloc(int mode,  
  847.                                               unsigned int tail,  
  848.                                               pid_t pid)  
  849. {  
  850.     if (use_logd) {  
  851.         return android_logger_list_alloc_logd(mode, tail, pid);  
  852.     } else {  
  853.         return android_logger_list_alloc_kernel(mode, tail, pid);  
  854.     }  
  855. }  
  856.   
  857. static struct logger_list *android_logger_list_alloc_time_logd(int mode,  
  858.                                                    log_time start,  
  859.                                                    pid_t pid)  
  860. {  
  861.     struct logger_list_logd *logger_list_logd;  
  862.   
  863.     logger_list_logd = calloc(1, sizeof(*logger_list_logd));  
  864.     if (!logger_list_logd) {  
  865.         return NULL;  
  866.     }  
  867.   
  868.     list_init(&logger_list_logd->base.node);  
  869.     logger_list_logd->base.mode = mode;  
  870.     logger_list_logd->start = start;  
  871.     logger_list_logd->base.tail = 0;  
  872.     logger_list_logd->base.pid = pid;  
  873.     logger_list_logd->sock = -1;  
  874.   
  875.     return (struct logger_list *)logger_list_logd;  
  876. }  
  877.   
  878. static struct logger_list *android_logger_list_alloc_time_kernel(int mode,  
  879.                                                    log_time start __unused,  
  880.                                                    pid_t pid)  
  881. {  
  882.     return android_logger_list_alloc(mode, 0, pid);  
  883. }  
  884.   
  885. struct logger_list *android_logger_list_alloc_time(int mode,  
  886.                                                    log_time start,  
  887.                                                    pid_t pid)  
  888. {  
  889.     if(use_logd){  
  890.         return android_logger_list_alloc_time_logd(mode, start, pid);  
  891.     } else {  
  892.         return android_logger_list_alloc_time_kernel(mode, start, pid);  
  893.     }  
  894. }  
  895.   
  896.   
  897. /* android_logger_list_register unimplemented, no use case */  
  898. /* android_logger_list_unregister unimplemented, no use case */  
  899.   
  900. /* Open the named log and add it to the logger list */  
  901. static struct logger *android_logger_open_logd(struct logger_list *logger_list,  
  902.                                    log_id_t id)  
  903. {  
  904.     struct logger *logger;  
  905.   
  906.     if (!logger_list || (id >= LOG_ID_MAX)) {  
  907.         goto err;  
  908.     }  
  909.   
  910.     logger_for_each(logger, logger_list) {  
  911.         if (logger->id == id) {  
  912.             goto ok;  
  913.         }  
  914.     }  
  915.   
  916.     logger = calloc(1, sizeof(*logger));  
  917.     if (!logger) {  
  918.         goto err;  
  919.     }  
  920.   
  921.     logger->id = id;  
  922.     list_add_tail(&logger_list->node, &logger->node);  
  923.     logger->top = logger_list;  
  924.     goto ok;  
  925.   
  926. err:  
  927.     logger = NULL;  
  928. ok:  
  929.     return logger;  
  930. }  
  931.   
  932. /* android_logger_list_register unimplemented, no use case */  
  933. /* android_logger_list_unregister unimplemented, no use case */  
  934.   
  935. /* Open the named log and add it to the logger list */  
  936. static struct logger *android_logger_open_kernel(struct logger_list *logger_list,  
  937.                                    log_id_t id)  
  938. {  
  939.     struct listnode *node;  
  940.     struct logger_kernel *logger_kernel = NULL;  
  941.     struct logger *logger;  
  942.     char *n;  
  943.     struct logger_list_kernel* logger_list_kernel = (struct logger_list_kernel*)logger_list;  
  944.   
  945.     if (!logger_list || (id >= LOG_ID_MAX)) {  
  946.         goto err;  
  947.     }  
  948.   
  949.     logger_for_each(logger, logger_list) {  
  950.         if (logger->id == id) {  
  951.             goto ok;  
  952.         }  
  953.     }  
  954.   
  955.     logger_kernel = calloc(1, sizeof(struct logger_kernel));  
  956.     if (!logger_kernel) {  
  957.         goto err;  
  958.     }  
  959.   
  960.     if (check_allocate_accessible(&n, android_log_id_to_name(id),  
  961.                                   logger_list_kernel->base.mode)) {  
  962.         goto err_name;  
  963.     }  
  964.   
  965.   
  966.     logger_kernel->fd = open(n, logger_list_kernel->base.mode & (ANDROID_LOG_ACCMODE | ANDROID_LOG_NONBLOCK));  
  967.     if (logger_kernel->fd < 0) {  
  968.         goto err_name;  
  969.     }  
  970.   
  971.     free(n);  
  972.     logger_kernel->base.id = id;  
  973.     list_init(&logger_kernel->log_list);  
  974.     list_add_tail(&logger_list_kernel->base.node, &logger_kernel->base.node);  
  975.     logger_kernel->base.top = (struct logger_list *)logger_list_kernel;  
  976.     logger_list_kernel->timeout_ms = LOG_TIMEOUT_FLUSH;  
  977.     goto ok;  
  978.   
  979. err_name:  
  980.     free(n);  
  981. err_logger:  
  982.     free(logger_kernel);  
  983. err:  
  984.     logger_kernel = NULL;  
  985. ok:  
  986.     return (struct logger *)logger_kernel;  
  987. }  
  988.   
  989. struct logger *android_logger_open(struct logger_list *logger_list,  
  990.                                    log_id_t id)  
  991. {  
  992.       if (use_logd) {  
  993.           return android_logger_open_logd(logger_list, id);  
  994.       } else {  
  995.           return android_logger_open_kernel(logger_list, id);  
  996.       }  
  997. }  
  998. /* Open the single named log and make it part of a new logger list */  
  999. struct logger_list *android_logger_list_open(log_id_t id,  
  1000.                                              int mode,  
  1001.                                              unsigned int tail,  
  1002.                                              pid_t pid)  
  1003. {  
  1004.     struct logger_list *logger_list = android_logger_list_alloc(mode, tail, pid);  
  1005.     if (!logger_list) {  
  1006.         return NULL;  
  1007.     }  
  1008.   
  1009.     if (!android_logger_open(logger_list, id)) {  
  1010.         android_logger_list_free(logger_list);  
  1011.         return NULL;  
  1012.     }  
  1013.   
  1014.     return logger_list;  
  1015. }  
  1016.   
  1017. /* prevent memory starvation when backfilling */  
  1018. static unsigned int queue_threshold(struct logger_list *logger_list)  
  1019. {  
  1020.     return (logger_list->tail < 64) ? 64 : logger_list->tail;  
  1021. }  
  1022.   
  1023. static bool low_queue(struct listnode *node)  
  1024. {  
  1025.     /* low is considered less than 2 */  
  1026.     return list_head(node) == list_tail(node);  
  1027. }  
  1028.   
  1029. static int android_logger_list_read_pstore(struct logger_list *logger_list,  
  1030.                                            struct log_msg *log_msg)  
  1031. {  
  1032.     ssize_t ret;  
  1033.     off_t current, next;  
  1034.     uid_t uid;  
  1035.     struct logger *logger;  
  1036.     struct __attribute__((__packed__)) {  
  1037.         android_pmsg_log_header_t p;  
  1038.         android_log_header_t l;  
  1039.     } buf;  
  1040.     static uint8_t preread_count;  
  1041.     struct logger_list_logd* logger_list_logd = (struct logger_list_logd*)logger_list;  
  1042.   
  1043.     memset(log_msg, 0, sizeof(*log_msg));  
  1044.   
  1045.     if (logger_list_logd->sock < 0) {  
  1046.         int fd = open("/sys/fs/pstore/pmsg-ramoops-0", O_RDONLY);  
  1047.   
  1048.         if (fd < 0) {  
  1049.             return -errno;  
  1050.         }  
  1051.         logger_list_logd->sock = fd;  
  1052.         preread_count = 0;  
  1053.     }  
  1054.   
  1055.     ret = 0;  
  1056.     while(1) {  
  1057.         if (preread_count < sizeof(buf)) {  
  1058.             ret = TEMP_FAILURE_RETRY(read(logger_list_logd->sock,  
  1059.                                           &buf.p.magic + preread_count,  
  1060.                                           sizeof(buf) - preread_count));  
  1061.             if (ret < 0) {  
  1062.                 return -errno;  
  1063.             }  
  1064.             preread_count += ret;  
  1065.         }  
  1066.         if (preread_count != sizeof(buf)) {  
  1067.             return preread_count ? -EIO : -EAGAIN;  
  1068.         }  
  1069.         if ((buf.p.magic != LOGGER_MAGIC)  
  1070.          || (buf.p.len <= sizeof(buf))  
  1071.          || (buf.p.len > (sizeof(buf) + LOGGER_ENTRY_MAX_PAYLOAD))  
  1072.          || (buf.l.id >= LOG_ID_MAX)  
  1073.          || (buf.l.realtime.tv_nsec >= NS_PER_SEC)) {  
  1074.             do {  
  1075.                 memmove(&buf.p.magic, &buf.p.magic + 1, --preread_count);  
  1076.             } while (preread_count && (buf.p.magic != LOGGER_MAGIC));  
  1077.             continue;  
  1078.         }  
  1079.         preread_count = 0;  
  1080.   
  1081.         logger_for_each(logger, logger_list) {  
  1082.             if (buf.l.id != logger->id) {  
  1083.                 continue;  
  1084.             }  
  1085.   
  1086.             if ((logger_list_logd->start.tv_sec || logger_list_logd->start.tv_nsec)  
  1087.              && ((logger_list_logd->start.tv_sec > buf.l.realtime.tv_sec)  
  1088.               || ((logger_list_logd->start.tv_sec == buf.l.realtime.tv_sec)  
  1089.                && (logger_list_logd->start.tv_nsec > buf.l.realtime.tv_nsec)))) {  
  1090.                 break;  
  1091.             }  
  1092.   
  1093.             if (logger_list_logd->base.pid && (logger_list_logd->base.pid != buf.p.pid)) {  
  1094.                 break;  
  1095.             }  
  1096.   
  1097.             uid = get_best_effective_uid();  
  1098.             if (!uid_has_log_permission(uid) && (uid != buf.p.uid)) {  
  1099.                 break;  
  1100.             }  
  1101.   
  1102.             ret = TEMP_FAILURE_RETRY(read(logger_list_logd->sock,  
  1103.                                           log_msg->entry_v3.msg,  
  1104.                                           buf.p.len - sizeof(buf)));  
  1105.             if (ret < 0) {  
  1106.                 return -errno;  
  1107.             }  
  1108.             if (ret != (ssize_t)(buf.p.len - sizeof(buf))) {  
  1109.                 return -EIO;  
  1110.             }  
  1111.   
  1112.             log_msg->entry_v3.len = buf.p.len - sizeof(buf);  
  1113.             log_msg->entry_v3.hdr_size = sizeof(log_msg->entry_v3);  
  1114.             log_msg->entry_v3.pid = buf.p.pid;  
  1115.             log_msg->entry_v3.tid = buf.l.tid;  
  1116.             log_msg->entry_v3.sec = buf.l.realtime.tv_sec;  
  1117.             log_msg->entry_v3.nsec = buf.l.realtime.tv_nsec;  
  1118.             log_msg->entry_v3.lid = buf.l.id;  
  1119.   
  1120.             return ret;  
  1121.         }  
  1122.   
  1123.         current = TEMP_FAILURE_RETRY(lseek(logger_list_logd->sock,  
  1124.                                            (off_t)0, SEEK_CUR));  
  1125.         if (current < 0) {  
  1126.             return -errno;  
  1127.         }  
  1128.         next = TEMP_FAILURE_RETRY(lseek(logger_list_logd->sock,  
  1129.                                         (off_t)(buf.p.len - sizeof(buf)),  
  1130.                                         SEEK_CUR));  
  1131.         if (next < 0) {  
  1132.             return -errno;  
  1133.         }  
  1134.         if ((next - current) != (ssize_t)(buf.p.len - sizeof(buf))) {  
  1135.             return -EIO;  
  1136.         }  
  1137.     }  
  1138. }  
  1139.   
  1140. /* Flush queues in sequential order, one at a time */  
  1141. static int android_logger_list_flush(struct logger_list *logger_list,  
  1142.                                      struct log_msg *log_msg)  
  1143. {  
  1144.     int ret = 0;  
  1145.     struct log_list *firstentry = NULL;  
  1146.     struct logger_list_kernel* logger_list_kernel = (struct logger_list_kernel*)logger_list;  
  1147.   
  1148.     while ((ret == 0)  
  1149.             && (logger_list_kernel->flush  
  1150.                 || (logger_list_kernel->queued_lines > logger_list_kernel->base.tail))) {  
  1151.         struct logger *logger;  
  1152.         struct logger_kernel *logger_kernel;  
  1153.   
  1154.         /* Merge sort */  
  1155.         bool at_least_one_is_low = false;  
  1156.         struct logger *firstlogger = NULL;  
  1157.         firstentry = NULL;  
  1158.   
  1159.         logger_for_each(logger, logger_list) {  
  1160.             struct listnode *node;  
  1161.             struct log_list *oldest = NULL;  
  1162.   
  1163.             /* kernel logger channels not necessarily time-sort order */  
  1164.             logger_kernel = (struct logger_kernel *)logger;  
  1165.             list_for_each(node, &logger_kernel->log_list) {  
  1166.                 struct log_list *entry = node_to_item(node,  
  1167.                                                       struct log_list, node);  
  1168.                 if (!oldest  
  1169.                         || (entry->entry.entry.sec < oldest->entry.entry.sec)  
  1170.                         || ((entry->entry.entry.sec == oldest->entry.entry.sec)  
  1171.                             && (entry->entry.entry.nsec < oldest->entry.entry.nsec))) {  
  1172.                     oldest = entry;  
  1173.                 }  
  1174.             }  
  1175.   
  1176.             if (!oldest) {  
  1177.                 at_least_one_is_low = true;  
  1178.                 continue;  
  1179.             } else if (low_queue(&logger_kernel->log_list)) {  
  1180.                 at_least_one_is_low = true;  
  1181.             }  
  1182.   
  1183.             if (!firstentry  
  1184.                     || (oldest->entry.entry.sec < firstentry->entry.entry.sec)  
  1185.                     || ((oldest->entry.entry.sec == firstentry->entry.entry.sec)  
  1186.                         && (oldest->entry.entry.nsec < firstentry->entry.entry.nsec))) {  
  1187.                 firstentry = oldest;  
  1188.                 firstlogger = logger;  
  1189.             }  
  1190.         }  
  1191.   
  1192.         if (!firstentry) {  
  1193.             break;  
  1194.         }  
  1195.   
  1196.         /* when trimming list, tries to keep one entry behind in each bucket */  
  1197.         if (!logger_list_kernel->flush  
  1198.                 && at_least_one_is_low  
  1199.                 && (logger_list_kernel->queued_lines < queue_threshold(logger_list))) {  
  1200.             break;  
  1201.         }  
  1202.   
  1203.         /* within tail?, send! */  
  1204.         if ((logger_list_kernel->base.tail == 0)  
  1205.                 || (logger_list_kernel->queued_lines <= logger_list_kernel->base.tail)) {  
  1206.             int diff;  
  1207.             ret = firstentry->entry.entry.hdr_size;  
  1208.             if (!ret) {  
  1209.                 ret = sizeof(firstentry->entry.entry_v1);  
  1210.             }  
  1211.   
  1212.             /* Promote entry to v3 format */  
  1213.             memcpy(log_msg->buf, firstentry->entry.buf, ret);  
  1214.             diff = sizeof(firstentry->entry.entry_v3) - ret;  
  1215.             if (diff < 0) {  
  1216.                 diff = 0;  
  1217.             } else if (diff > 0) {  
  1218.                 memset(log_msg->buf + ret, 0, diff);  
  1219.             }  
  1220.             memcpy(log_msg->buf + ret + diff, firstentry->entry.buf + ret,  
  1221.                    firstentry->entry.entry.len + 1);  
  1222.             ret += diff;  
  1223.             log_msg->entry.hdr_size = ret;  
  1224.             log_msg->entry.lid = firstlogger->id;  
  1225.   
  1226.             ret += firstentry->entry.entry.len;  
  1227.         }  
  1228.   
  1229.         /* next entry */  
  1230.         list_remove(&firstentry->node);  
  1231.         free(firstentry);  
  1232.         if (logger_list_kernel->queued_lines) {  
  1233.             logger_list_kernel->queued_lines--;  
  1234.         }  
  1235.     }  
  1236.   
  1237.     /* Flushed the list, no longer in tail mode for continuing content */  
  1238.     if (logger_list_kernel->flush && !firstentry) {  
  1239.         logger_list_kernel->base.tail = 0;  
  1240.     }  
  1241.     return ret;  
  1242. }  
  1243.   
  1244. static void caught_signal(int signum __unused)  
  1245. {  
  1246. }  
  1247.   
  1248. /* Read from the selected logs */  
  1249. static int android_logger_list_read_logd(struct logger_list *logger_list,  
  1250.                              struct log_msg *log_msg)  
  1251. {  
  1252.     int ret, e;  
  1253.     struct logger *logger;  
  1254.     struct sigaction ignore;  
  1255.     struct sigaction old_sigaction;  
  1256.     struct logger_list_logd *logger_list_logd = (struct logger_list_logd *)logger_list;  
  1257.     unsigned int old_alarm = 0;  
  1258.   
  1259.     if (!logger_list) {  
  1260.         return -EINVAL;  
  1261.     }  
  1262.   
  1263.     if (logger_list->mode & ANDROID_LOG_PSTORE) {  
  1264.         return android_logger_list_read_pstore(logger_list, log_msg);  
  1265.     }  
  1266.   
  1267.     if (logger_list->mode & ANDROID_LOG_NONBLOCK) {  
  1268.         memset(&ignore, 0, sizeof(ignore));  
  1269.         ignore.sa_handler = caught_signal;  
  1270.         sigemptyset(&ignore.sa_mask);  
  1271.     }  
  1272.   
  1273.     if (logger_list_logd->sock < 0) {  
  1274.         char buffer[256], *cp, c;  
  1275.   
  1276.         int sock = socket_local_client("logdr",  
  1277.                                        ANDROID_SOCKET_NAMESPACE_RESERVED,  
  1278.                                        SOCK_SEQPACKET);  
  1279.         if (sock < 0) {  
  1280.             if ((sock == -1) && errno) {  
  1281.                 return -errno;  
  1282.             }  
  1283.             return sock;  
  1284.         }  
  1285.   
  1286.         strcpy(buffer,  
  1287.                (logger_list->mode & ANDROID_LOG_NONBLOCK) ? "dumpAndClose" : "stream");  
  1288.         cp = buffer + strlen(buffer);  
  1289.   
  1290.         strcpy(cp, " lids");  
  1291.         cp += 5;  
  1292.         c = '=';  
  1293.         int remaining = sizeof(buffer) - (cp - buffer);  
  1294.         logger_for_each(logger, logger_list) {  
  1295.             ret = snprintf(cp, remaining, "%c%u", c, logger->id);  
  1296.             ret = min(ret, remaining);  
  1297.             remaining -= ret;  
  1298.             cp += ret;  
  1299.             c = ',';  
  1300.         }  
  1301.   
  1302.         if (logger_list->tail) {  
  1303.             ret = snprintf(cp, remaining, " tail=%u", logger_list->tail);  
  1304.             ret = min(ret, remaining);  
  1305.             remaining -= ret;  
  1306.             cp += ret;  
  1307.         }  
  1308.   
  1309.         if (logger_list_logd->start.tv_sec || logger_list_logd->start.tv_nsec) {  
  1310.             ret = snprintf(cp, remaining, " start=%" PRIu32 ".%09" PRIu32,  
  1311.                            logger_list_logd->start.tv_sec,  
  1312.                            logger_list_logd->start.tv_nsec);  
  1313.             ret = min(ret, remaining);  
  1314.             remaining -= ret;  
  1315.             cp += ret;  
  1316.         }  
  1317.   
  1318.         if (logger_list->pid) {  
  1319.             ret = snprintf(cp, remaining, " pid=%u", logger_list->pid);  
  1320.             ret = min(ret, remaining);  
  1321.             remaining -= ret;  
  1322.             cp += ret;  
  1323.         }  
  1324.   
  1325.         if (logger_list->mode & ANDROID_LOG_NONBLOCK) {  
  1326.             /* Deal with an unresponsive logd */  
  1327.             sigaction(SIGALRM, &ignore, &old_sigaction);  
  1328.             old_alarm = alarm(30);  
  1329.         }  
  1330.         ret = write(sock, buffer, cp - buffer);  
  1331.         e = errno;  
  1332.         if (logger_list->mode & ANDROID_LOG_NONBLOCK) {  
  1333.             if (e == EINTR) {  
  1334.                 e = ETIMEDOUT;  
  1335.             }  
  1336.             alarm(old_alarm);  
  1337.             sigaction(SIGALRM, &old_sigaction, NULL);  
  1338.         }  
  1339.   
  1340.         if (ret <= 0) {  
  1341.             close(sock);  
  1342.             if ((ret == -1) && e) {  
  1343.                 return -e;  
  1344.             }  
  1345.             if (ret == 0) {  
  1346.                 return -EIO;  
  1347.             }  
  1348.             return ret;  
  1349.         }  
  1350.   
  1351.         logger_list_logd->sock = sock;  
  1352.     }  
  1353.   
  1354.     ret = 0;  
  1355.     while(1) {  
  1356.         memset(log_msg, 0, sizeof(*log_msg));  
  1357.   
  1358.         if (logger_list->mode & ANDROID_LOG_NONBLOCK) {  
  1359.             /* particularily useful if tombstone is reporting for logd */  
  1360.             sigaction(SIGALRM, &ignore, &old_sigaction);  
  1361.             old_alarm = alarm(30);  
  1362.         }  
  1363.         /* NOTE: SOCK_SEQPACKET guarantees we read exactly one full entry */  
  1364.         ret = recv(logger_list_logd->sock, log_msg, LOGGER_ENTRY_MAX_LEN, 0);  
  1365.         e = errno;  
  1366.         if (logger_list->mode & ANDROID_LOG_NONBLOCK) {  
  1367.             if ((ret == 0) || (e == EINTR)) {  
  1368.                 e = EAGAIN;  
  1369.                 ret = -1;  
  1370.             }  
  1371.             alarm(old_alarm);  
  1372.             sigaction(SIGALRM, &old_sigaction, NULL);  
  1373.         }  
  1374.   
  1375.         if (ret <= 0) {  
  1376.             if ((ret == -1) && e) {  
  1377.                 return -e;  
  1378.             }  
  1379.             return ret;  
  1380.         }  
  1381.   
  1382.         logger_for_each(logger, logger_list) {  
  1383.             if (log_msg->entry.lid == logger->id) {  
  1384.                 return ret;  
  1385.             }  
  1386.         }  
  1387.     }  
  1388.     /* NOTREACH */  
  1389.     return ret;  
  1390. }  
  1391.   
  1392. /* Read from the selected logs */  
  1393. static int android_logger_list_read_kernel(struct logger_list *logger_list,  
  1394.                              struct log_msg *log_msg)  
  1395. {  
  1396.     struct logger *logger;  
  1397.     struct logger_list_kernel *logger_list_kernel = (struct logger_list_kernel *)logger_list;  
  1398.     nfds_t nfds;  
  1399.     struct pollfd *p, *pollfds = NULL;  
  1400.     int error = 0, ret = 0;  
  1401.   
  1402.     memset(log_msg, 0, sizeof(struct log_msg));  
  1403.   
  1404.     if (!logger_list) {  
  1405.         return -ENODEV;  
  1406.     }  
  1407.   
  1408.     if (!(accessmode(logger_list->mode) & R_OK)) {  
  1409.         logger_list_kernel->error = EPERM;  
  1410.         goto done;  
  1411.     }  
  1412.   
  1413.     nfds = 0;  
  1414.     logger_for_each(logger, logger_list) {  
  1415.         ++nfds;  
  1416.     }  
  1417.     if (nfds <= 0) {  
  1418.         error = ENODEV;  
  1419.         goto done;  
  1420.     }  
  1421.   
  1422.     /* Do we have anything to offer from the buffer or state? */  
  1423.     if (logger_list_kernel->valid_entry) { /* implies we are also in a flush state */  
  1424.         goto flush;  
  1425.     }  
  1426.   
  1427.     ret = android_logger_list_flush(logger_list, log_msg);  
  1428.     if (ret) {  
  1429.         goto done;  
  1430.     }  
  1431.   
  1432.     if (logger_list_kernel->error) { /* implies we are also in a flush state */  
  1433.         goto done;  
  1434.     }  
  1435.   
  1436.     /* Lets start grinding on metal */  
  1437.     pollfds = calloc(nfds, sizeof(struct pollfd));  
  1438.     if (!pollfds) {  
  1439.         error = ENOMEM;  
  1440.         goto flush;  
  1441.     }  
  1442.   
  1443.     p = pollfds;  
  1444.     struct logger_kernel *logger_kernel;  
  1445.     logger_for_each(logger, logger_list) {  
  1446.         logger_kernel = (struct logger_kernel *)logger;  
  1447.         p->fd = logger_kernel->fd;  
  1448.         p->events = POLLIN;  
  1449.         logger_kernel->revents = &p->revents;  
  1450.         ++p;  
  1451.     }  
  1452.   
  1453.     while (!ret && !error) {  
  1454.         int result;  
  1455.   
  1456.         /* If we oversleep it's ok, i.e. ignore EINTR. */  
  1457.         result = TEMP_FAILURE_RETRY(  
  1458.                     poll(pollfds, nfds, logger_list_kernel->timeout_ms));  
  1459.   
  1460.         if (result <= 0) {  
  1461.             if (result) {  
  1462.                 error = errno;  
  1463.             } else if (logger_list->mode & ANDROID_LOG_NONBLOCK) {  
  1464.                 error = EAGAIN;  
  1465.             } else {  
  1466.                 logger_list_kernel->timeout_ms = LOG_TIMEOUT_NEVER;  
  1467.             }  
  1468.   
  1469.             logger_list_kernel->flush = true;  
  1470.             goto try_flush;  
  1471.         }  
  1472.   
  1473.         logger_list_kernel->timeout_ms = LOG_TIMEOUT_FLUSH;  
  1474.   
  1475.         /* Anti starvation */  
  1476.         if (!logger_list_kernel->flush  
  1477.                 && (logger_list_kernel->queued_lines > (queue_threshold(logger_list) / 2))) {  
  1478.             /* Any queues with input pending that is low? */  
  1479.             bool starving = false;  
  1480.             logger_for_each(logger, logger_list) {  
  1481.                 logger_kernel = (struct logger_kernel *)logger;  
  1482.                 if ((*(logger_kernel->revents) & POLLIN)  
  1483.                         && low_queue(&logger_kernel->log_list)) {  
  1484.                     starving = true;  
  1485.                     break;  
  1486.                 }  
  1487.             }  
  1488.   
  1489.             /* pushback on any queues that are not low */  
  1490.             if (starving) {  
  1491.                 logger_for_each(logger, logger_list) {  
  1492.                     logger_kernel = (struct logger_kernel *)logger;  
  1493.                     if ((*(logger_kernel->revents) & POLLIN)  
  1494.                             && !low_queue(&logger_kernel->log_list)) {  
  1495.                         *(logger_kernel->revents) &= ~POLLIN;  
  1496.                     }  
  1497.                 }  
  1498.             }  
  1499.         }  
  1500.   
  1501.         logger_for_each(logger, logger_list) {  
  1502.             unsigned int hdr_size;  
  1503.             struct log_list *entry;  
  1504.             int diff;  
  1505.             logger_kernel = (struct logger_kernel *)logger;  
  1506.   
  1507.             if (!(*(logger_kernel->revents) & POLLIN)) {  
  1508.                 continue;  
  1509.             }  
  1510.   
  1511.             memset(logger_list_kernel->entry.buf, 0, sizeof(struct log_msg));  
  1512.             /* NOTE: driver guarantees we read exactly one full entry */  
  1513.             result = read(logger_kernel->fd, logger_list_kernel->entry.buf,  
  1514.                           LOGGER_ENTRY_MAX_LEN);  
  1515.             if (result <= 0) {  
  1516.                 if (!result) {  
  1517.                     error = EIO;  
  1518.                 } else if (errno != EINTR) {  
  1519.                     error = errno;  
  1520.                 }  
  1521.                 continue;  
  1522.             }  
  1523.   
  1524.             if (logger_list->pid  
  1525.                     && (logger_list->pid != logger_list_kernel->entry.entry.pid)) {  
  1526.                 continue;  
  1527.             }  
  1528.   
  1529.             hdr_size = logger_list_kernel->entry.entry.hdr_size;  
  1530.             if (!hdr_size) {  
  1531.                 hdr_size = sizeof(logger_list_kernel->entry.entry_v1);  
  1532.             }  
  1533.   
  1534.             if ((hdr_size > sizeof(struct log_msg))  
  1535.                     || (logger_list_kernel->entry.entry.len  
  1536.                         > sizeof(logger_list_kernel->entry.buf) - hdr_size)  
  1537.                     || (logger_list_kernel->entry.entry.len != result - hdr_size)) {  
  1538.                 error = EINVAL;  
  1539.                 continue;  
  1540.             }  
  1541.   
  1542.             /* Promote entry to v3 format */  
  1543.             diff = sizeof(logger_list_kernel->entry.entry_v3) - hdr_size;  
  1544.             if (diff > 0) {  
  1545.                 if (logger_list_kernel->entry.entry.len  
  1546.                         > sizeof(logger_list_kernel->entry.buf) - hdr_size - diff) {  
  1547.                     error = EINVAL;  
  1548.                     continue;  
  1549.                 }  
  1550.                 result += diff;  
  1551.                 memmove(logger_list_kernel->entry.buf + hdr_size + diff,  
  1552.                         logger_list_kernel->entry.buf + hdr_size,  
  1553.                         logger_list_kernel->entry.entry.len + 1);  
  1554.                 memset(logger_list_kernel->entry.buf + hdr_size, 0, diff);  
  1555.                 logger_list_kernel->entry.entry.hdr_size = hdr_size + diff;  
  1556.             }  
  1557.             logger_list_kernel->entry.entry.lid = logger->id;  
  1558.   
  1559.             /* speedup: If not tail, and only one list, send directly */  
  1560.             if (!logger_list->tail  
  1561.                     && (list_head(&logger_list->node)  
  1562.                         == list_tail(&logger_list->node))) {  
  1563.                 ret = result;  
  1564.                 memcpy(log_msg->buf, logger_list_kernel->entry.buf, result + 1);  
  1565.                 break;  
  1566.             }  
  1567.   
  1568.             entry = malloc(sizeof(*entry) - sizeof(entry->entry) + result + 1);  
  1569.   
  1570.             if (!entry) {  
  1571.                 logger_list_kernel->valid_entry = true;  
  1572.                 error = ENOMEM;  
  1573.                 break;  
  1574.             }  
  1575.   
  1576.             logger_list_kernel->queued_lines++;  
  1577.   
  1578.             memcpy(entry->entry.buf, logger_list_kernel->entry.buf, result);  
  1579.             entry->entry.buf[result] = '\0';  
  1580.             list_add_tail(&logger_kernel->log_list, &entry->node);  
  1581.         }  
  1582.   
  1583.         if (ret <= 0) {  
  1584. try_flush:  
  1585.             ret = android_logger_list_flush(logger_list, log_msg);  
  1586.         }  
  1587.     }  
  1588.   
  1589.     free(pollfds);  
  1590.   
  1591. flush:  
  1592.     if (error) {  
  1593.         logger_list_kernel->flush = true;  
  1594.     }  
  1595.   
  1596.     if (ret <= 0) {  
  1597.         ret = android_logger_list_flush(logger_list, log_msg);  
  1598.   
  1599.         if (!ret && logger_list_kernel->valid_entry) {  
  1600.             ret = logger_list_kernel->entry.entry.hdr_size;  
  1601.             if (!ret) {  
  1602.                 ret = sizeof(logger_list_kernel->entry.entry_v1);  
  1603.             }  
  1604.             ret += logger_list_kernel->entry.entry.len;  
  1605.   
  1606.             memcpy(log_msg->buf, logger_list_kernel->entry.buf,  
  1607.                    sizeof(struct log_msg));  
  1608.             logger_list_kernel->valid_entry = false;  
  1609.         }  
  1610.     }  
  1611.   
  1612. done:  
  1613.     if (logger_list_kernel->error) {  
  1614.         error = logger_list_kernel->error;  
  1615.     }  
  1616.     if (error) {  
  1617.         logger_list_kernel->error = error;  
  1618.         if (!ret) {  
  1619.             ret = -error;  
  1620.         }  
  1621.     }  
  1622.     return ret;  
  1623. }  
  1624.   
  1625. int android_logger_list_read(struct logger_list *logger_list,  
  1626.                              struct log_msg *log_msg)  
  1627. {  
  1628.     if (use_logd) {  
  1629.         return android_logger_list_read_logd(logger_list, log_msg);  
  1630.     } else {  
  1631.         return android_logger_list_read_kernel(logger_list, log_msg);  
  1632.     }  
  1633. }  
  1634.   
  1635. /* Close all the logs */  
  1636. static void android_logger_list_free_logd(struct logger_list *logger_list)  
  1637. {  
  1638.     if (logger_list == NULL) {  
  1639.         return;  
  1640.     }  
  1641.   
  1642.     while (!list_empty(&logger_list->node)) {  
  1643.         struct listnode *node = list_head(&logger_list->node);  
  1644.         struct logger *logger = node_to_item(node, struct logger, node);  
  1645.         android_logger_free(logger);  
  1646.     }  
  1647.   
  1648.     struct logger_list_logd *logger_list_logd = (struct logger_list_logd *)logger_list;  
  1649.     if (use_logd) {  
  1650.         if (logger_list_logd->sock >= 0) {  
  1651.             close (logger_list_logd->sock);  
  1652.         }  
  1653.     }  
  1654.   
  1655.     free(logger_list_logd);  
  1656. }  
  1657.   
  1658. /* Close all the logs */  
  1659. static void android_logger_list_free_kernel(struct logger_list *logger_list)  
  1660. {  
  1661.     if (logger_list == NULL) {  
  1662.         return;  
  1663.     }  
  1664.   
  1665.     while (!list_empty(&logger_list->node)) {  
  1666.         struct listnode *node = list_head(&logger_list->node);  
  1667.         struct logger *logger = node_to_item(node, struct logger, node);  
  1668.         android_logger_free(logger);  
  1669.     }  
  1670.     struct logger_list_kernel *logger_list_kernel = (struct logger_list_kernel *)logger_list;  
  1671.     free(logger_list_kernel);  
  1672. }  
  1673.   
  1674. void android_logger_list_free(struct logger_list *logger_list) {  
  1675.     if (use_logd) {  
  1676.         android_logger_list_free_logd(logger_list);  
  1677.     } else {  
  1678.         android_logger_list_free_kernel(logger_list);  
  1679.     }  
  1680. }  

在logger.h中定义对外函数,FAKE_LOG_DEVICE==0 代表是手机版本,不是host。必须加这个宏,因为在编译host的使用也会引用到这个头文件,而在编译HOST的静态库时,log_read_common.c是不会参与编译的这样会造成set_uselogd这样函数没有定义。所以必须加这个宏。

[cpp]  view plain  copy
  1. ......  
  2. #if (FAKE_LOG_DEVICE == 0)  
  3. void set_uselogd(int8_t uselogd);  
  4. #endif  
  5. ......  


最后我们来看logcat的main函数中,调用这个函数来控制logcat read log时使用logd机制还是kernel机制。下面这段代码是在logcat的main函数在定义完变量之后,和write相同也是看system/etc/disable_logd这个文件是否存在,存在就是kernel机制,不存在就是logd机制。

[cpp]  view plain  copy
  1. ......  
  2.     int fd;  
  3.     int8_t use_logd = 1;  
  4.     fd = open("system/etc/disable_logd", O_RDONLY);  
  5.     if (fd > 0) {  
  6.         LOGCAT_INFO("logcat disable logd.\n ");  
  7.         use_logd = 0;  
  8.         close(fd);  
  9.     }  
  10.   
  11.     set_uselogd(use_logd);  
  12. ......  

write是在liblog库中log函数初始化的时候来判断使用哪个机制,也就是每个进程调用这个函数时都会初始化下。而read只有在logcat进程中使用,每次logcat进程启动的时候判断使用哪个机制,并且调用set_uselogd来通知read那块。


原文地址: http://blog.csdn.net/kc58236582/article/details/72279744

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值