From 30b3ac1492e385523d029f2f6ce2063da9926d8d Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Fri, 28 Apr 2017 15:12:35 +0200 Subject: [PATCH] Fix dlogutil -d under Android Logger backend Util would keep reading as long as any data was in the buffer, so if data came faster than it was processed then it would be working indefinitely. Now, it learns how many logs are present right at the start by sending a get length request and only reads that many. Change-Id: Idcfc7b10776ff93c85f16b335dad36d12bf5cd8e Signed-off-by: Michal Bloch --- src/logutil/logutil.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/src/logutil/logutil.c b/src/logutil/logutil.c index 4cd0d5a..516f764 100644 --- a/src/logutil/logutil.c +++ b/src/logutil/logutil.c @@ -62,6 +62,8 @@ #define DEFAULT_SORT_TIMEOUT 1000 // ms +#define UNLIMITED_LOG_LEN 0 + static int sort_buffer_size = 0; static long sort_timeout = DEFAULT_SORT_TIMEOUT; static struct log_file l_file; @@ -87,6 +89,7 @@ typedef enum { struct fd_info { int fd; int do_sorting; + int log_len; fd_type type; int index; char buff[RECEIVE_BUFFER_SIZE]; @@ -188,6 +191,23 @@ static int do_clear_pipe(int sock_fd) free(msg); return ret; } +/** + * @brief Get buffer filled size + * @details Sends a get log len ioctl to given fd + * @param[in] fd File descriptor of the buffer + * @return -errno on failure, else >= 0 length in bytes + * @remarks ANDROID LOGGER version + */ +int logger_get_log_len(int fd) +{ + int ret = ioctl(fd, LOGGER_GET_LOG_LEN); + if (ret < 0) { + const int saved_errno = errno; + _E("ioctl LOGGER_GET_LOG_LEN failed (%d)", saved_errno); + return -saved_errno; + } + return ret; +} /** * @brief Clear the buffer @@ -400,18 +420,30 @@ static void handle_pipe(struct fd_info **data_fds, int fd_count, int dump) } } - if (r == 0) { + int stop = (r == 0); + if (dump && !stop && fdi->log_len > 0) { + fdi->log_len -= r; + if (fdi->log_len <= 0) + stop = 1; + } + + filled = 1; + fdi->index += r; + + if (stop) { + if (fdi->type != BINARY_FILE) + epoll_ctl(epollfd, EPOLL_CTL_DEL, fdi->fd, NULL); + if (fdi->type == PIPE && dump) { --pipes; - epoll_ctl(epollfd, EPOLL_CTL_DEL, fdi->fd, NULL); } else if (--fd_count <= 0) accepting_logs = 0; - continue; + if (r == 0) + continue; + else + filled = 0; } - filled = 1; - fdi->index += r; - e = (struct logger_entry *)fdi->buff; switch (fdi->type) { case ANDROID_LOGGER: { @@ -503,6 +535,7 @@ struct fd_info * handle_file(char const * filename) goto closefile; fdi->fd = fd; fdi->do_sorting = 1; + fdi->log_len = UNLIMITED_LOG_LEN; fdi->type = BINARY_FILE; fdi->index = 0; return fdi; @@ -556,12 +589,17 @@ struct fd_info * process_buffer_nonpipe(char * buffer_name, int clear, struct lo goto cleanup; } + const int log_len = logger_get_log_len(fd); + if (log_len < 0) + goto cleanup; + struct fd_info * fdi = malloc(sizeof(struct fd_info)); if (!fdi) goto cleanup; fdi->fd = fd; fdi->do_sorting = 1; fdi->type = ANDROID_LOGGER; + fdi->log_len = log_len; fdi->index = 0; return fdi; @@ -636,6 +674,7 @@ struct fd_info * process_buffer_pipe(char * buffer_name, int clear, struct log_c goto cleanup; } ret->fd = pipe_fd; + ret->log_len = UNLIMITED_LOG_LEN; ret->do_sorting = strncmp(buffer_name, "kmsg", 5) && strncmp(buffer_name, "syslog", 7); ret->type = PIPE; -- 2.7.4