From 733021a71b65fe74d258de659180dd5f787ae89d Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Wed, 7 Feb 2018 17:09:33 +0100 Subject: [PATCH] util: extract fd_info to subfiles Change-Id: I79569ea5bd91cc23a6b9a168f66de337a518a6f1 Signed-off-by: Michal Bloch --- Makefile.am | 4 + src/logutil/fd_info.c | 134 +++++++++++++++ src/logutil/fd_info.h | 33 ++++ src/logutil/fdi_binfile.c | 62 +++++++ src/logutil/fdi_binfile.h | 6 + src/logutil/fdi_logger.c | 84 ++++++++++ src/logutil/fdi_logger.h | 7 + src/logutil/fdi_pipe.c | 135 +++++++++++++++ src/logutil/fdi_pipe.h | 7 + src/logutil/logutil.c | 408 +--------------------------------------------- 10 files changed, 480 insertions(+), 400 deletions(-) create mode 100644 src/logutil/fd_info.c create mode 100644 src/logutil/fd_info.h create mode 100644 src/logutil/fdi_binfile.c create mode 100644 src/logutil/fdi_binfile.h create mode 100644 src/logutil/fdi_logger.c create mode 100644 src/logutil/fdi_logger.h create mode 100644 src/logutil/fdi_pipe.c create mode 100644 src/logutil/fdi_pipe.h diff --git a/Makefile.am b/Makefile.am index 2533a0b..fce9c73 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,6 +45,10 @@ dlogutil_LDFLAGS = \ dlogutil_SOURCES = \ src/logutil/logutil.c \ src/logutil/sort_vector.c \ + src/logutil/fd_info.c \ + src/logutil/fdi_pipe.c \ + src/logutil/fdi_logger.c \ + src/logutil/fdi_binfile.c \ src/shared/logcommon.c \ src/shared/logprint.c \ src/shared/queued_entry.c \ diff --git a/src/logutil/fd_info.c b/src/logutil/fd_info.c new file mode 100644 index 0000000..379a65e --- /dev/null +++ b/src/logutil/fd_info.c @@ -0,0 +1,134 @@ +#include +#include +#include + +#include + +#include +#include + +#include "fd_info.h" +#include "sort_vector.h" + +/** + * @brief Create struct fd_info + * @details Allocates memory for the struct and initializes it with given arguments + * @param[in] fd file descriptor + * @param[in] do_sorting specifies if the logs read from fd should be sorted + * @param[in] log_len up to how many bytes the logs should be read from fd + * UNLIMITED_LOG_LEN for unlimited logs reading + * @param[in] type source type we read from defined in enum fd_type + * @return FD created struct or NULL on memory allocation failure + */ +struct fd_info *fdi_create(int fd, int do_sorting, int log_len, fd_type type) +{ + struct fd_info *fdi = malloc(sizeof(struct fd_info)); + if (!fdi) + return NULL; + + fdi->fd = fd; + fdi->do_sorting = do_sorting; + fdi->log_len = log_len; + fdi->type = type; + fdi->index = 0; + + return fdi; +} + +void fdi_free(struct fd_info *fdi) +{ + if (!fdi) + return; + + if (fdi->fd >= 0) + close(fdi->fd); + free(fdi); +} + +void fdi_array_free(struct fd_info ***arr) +{ + assert(arr); + + if (!*arr) + return; + + for (int i = 0; (*arr)[i]; ++i) + fdi_free((*arr)[i]); + + free(*arr); +} + +bool fdi_has_log(struct fd_info *fdi) +{ + assert(fdi); + const struct logger_entry *const le = (const struct logger_entry *)fdi->buff; + return fdi->index >= sizeof le->len && fdi->index >= le->len; +} + +int fdi_push_log(struct fd_info *fdi, int *dump, struct sort_vector *logs, struct log_file *l_file) +{ + assert(fdi); + assert(dump); + assert(l_file); + + struct logger_entry *temp = fdi_extract_entry(fdi); + if (!temp) + return -ENOMEM; + + if (fdi->do_sorting) { + sort_vector_push(logs, temp, l_file); + } else { + int write_err = logfile_write_with_rotation(temp, l_file); + free(temp); + if (!write_err && *dump && !--*dump) + return 1; + } + + return 0; +} + +struct logger_entry *fdi_extract_entry(struct fd_info *fdi) +{ + assert(fdi); + + struct logger_entry *const buf_le = (struct logger_entry *)fdi->buff; + if (!buf_le->len) + return NULL; + + struct logger_entry *const new_le = malloc(buf_le->len); + if (!new_le) + return NULL; + + memcpy(new_le, buf_le, buf_le->len); + fdi->index -= buf_le->len; + memmove(fdi->buff, fdi->buff + buf_le->len, fdi->index); + + return new_le; +} + +int fdi_read(struct fd_info *fdi) +{ + assert(fdi); + + if (fdi->index == RECEIVE_BUFFER_SIZE) + return -EAGAIN; + + int r = read(fdi->fd, fdi->buff + fdi->index, RECEIVE_BUFFER_SIZE - fdi->index); + if (r < 0) + return -errno; + + if (fdi->type == ANDROID_LOGGER) { + struct logger_entry *const le = (struct logger_entry *)fdi->buff; + parse_androidlogger_message((struct android_logger_entry *)fdi->buff, le, r); + add_recv_timestamp(le); + fdi->index = le->len; + } else { + fdi->index += r; + } + + if (fdi->log_len > 0) + fdi->log_len -= r; + + return r; +} + diff --git a/src/logutil/fd_info.h b/src/logutil/fd_info.h new file mode 100644 index 0000000..3f450ec --- /dev/null +++ b/src/logutil/fd_info.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include +#include "sort_vector.h" + +#define RECEIVE_BUFFER_SIZE 16384 // How large (in bytes) the pipe receiving buffer is. +#define UNLIMITED_LOG_LEN (-RECEIVE_BUFFER_SIZE - 1) // value not reachable through a single read() + +typedef enum { + PIPE, + BINARY_FILE, + ANDROID_LOGGER +} fd_type; + +struct fd_info { + int fd; + int do_sorting; + int log_len; + fd_type type; + int index; + char buff[RECEIVE_BUFFER_SIZE]; +}; + +struct fd_info *fdi_create(int fd, int do_sorting, int log_len, fd_type type); +void fdi_free(struct fd_info *fdi); +void fdi_array_free(struct fd_info ***arr); +bool fdi_has_log(struct fd_info *fdi); +int fdi_push_log(struct fd_info *fdi, int *dump, struct sort_vector *logs, struct log_file *l_file); +struct logger_entry *fdi_extract_entry(struct fd_info *fdi); +int fdi_read(struct fd_info *fdi); + diff --git a/src/logutil/fdi_binfile.c b/src/logutil/fdi_binfile.c new file mode 100644 index 0000000..473972f --- /dev/null +++ b/src/logutil/fdi_binfile.c @@ -0,0 +1,62 @@ +#include +#include + +#include +#include + +#include + +#include "fd_info.h" +#include "fdi_binfile.h" + +/** + * @brief Handle a file + * @details Checks validity of a binary file + * @param[in] filename The file name + * @return A fd wrapper struct on valid file, else NULL + */ +struct fd_info *handle_file(char const *filename) +{ + assert(filename); + + int r; + int fd; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "File \"%s\" could not be opened: %m\n", filename); + return NULL; + } + + struct dlog_pipe_header header; + r = read(fd, &header, sizeof header); + if (r < 0) { + fprintf(stderr, "File \"%s\" read failed! %m\n", filename); + goto closefile; + } else if (r < sizeof header) { + fprintf(stderr, "File \"%s\" does not contain a full header!\n", filename); + goto closefile; + } + + if (header.endian != PIPE_FILE_ENDIAN_MAGIC) { + fprintf(stderr, "File \"%s\": unsupported endianness!\n", filename); + goto closefile; + } + + if (header.version != PIPE_FILE_FORMAT_VERSION) { + fprintf(stderr, "File \"%s\": file format version is %d but only %d is supported!\n", filename, header.version, PIPE_FILE_FORMAT_VERSION); + goto closefile; + } + + struct fd_info *fdi = fdi_create(fd, 1, UNLIMITED_LOG_LEN, BINARY_FILE); + if (!fdi) { + fprintf(stderr, "Error: not enough memory\n"); + goto closefile; + } + return fdi; + +closefile: + close(fd); + return NULL; +} + diff --git a/src/logutil/fdi_binfile.h b/src/logutil/fdi_binfile.h new file mode 100644 index 0000000..2b9179e --- /dev/null +++ b/src/logutil/fdi_binfile.h @@ -0,0 +1,6 @@ +#pragma once + +#include "fd_info.h" + +struct fd_info *handle_file(char const *filename); + diff --git a/src/logutil/fdi_logger.c b/src/logutil/fdi_logger.c new file mode 100644 index 0000000..2232328 --- /dev/null +++ b/src/logutil/fdi_logger.c @@ -0,0 +1,84 @@ +#include + +#include +#include + +#include +#include +#include + +#include "fd_info.h" +#include "fdi_logger.h" + +/** + * @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 + */ +static 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 + * @details Sends a clear ioctl to given fd + * @param[in] fd File descriptor of the buffer + * @remarks ANDROID LOGGER version + */ +static void clear_log_logger(int fd) +{ + int ret = ioctl(fd, LOGGER_FLUSH_LOG); + if (ret < 0) + _E("ioctl LOGGER_FLUSH_LOG failed (%d)", errno); +} + +/** + * @brief Process buffer (non-pipe version) + * @details Finalizes a buffer: sends the appropriate socket request + * @param[in] buffer_name The name of the buffer + * @param[in] clear Whether to clear the buffer + * @param[in] conf The configuration + * @param[in] argc Argument count + * @param[in] argv Argument values + * @return FD wrapper structure to read from + */ +struct fd_info *process_buffer_nonpipe(const char *buffer_name, int clear, struct log_config *conf) +{ + char const *dev_path; + dev_path = log_config_get(conf, buffer_name); + if (!dev_path) + return NULL; + + int fd = open(dev_path, clear ? O_WRONLY : O_RDONLY); + if (fd < 0) + return NULL; + + if (clear) { + clear_log_logger(fd); + goto cleanup; + } + + const int log_len = logger_get_log_len(fd); + if (log_len < 0) + goto cleanup; + + struct fd_info *fdi = fdi_create(fd, 1, log_len, ANDROID_LOGGER); + if (!fdi) + goto cleanup; + + return fdi; + +cleanup: + close(fd); + return NULL; +} + diff --git a/src/logutil/fdi_logger.h b/src/logutil/fdi_logger.h new file mode 100644 index 0000000..320a7b5 --- /dev/null +++ b/src/logutil/fdi_logger.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include "fd_info.h" + +struct fd_info *process_buffer_nonpipe(const char *buffer_name, int clear, struct log_config *conf); + diff --git a/src/logutil/fdi_pipe.c b/src/logutil/fdi_pipe.c new file mode 100644 index 0000000..92f4c1d --- /dev/null +++ b/src/logutil/fdi_pipe.c @@ -0,0 +1,135 @@ +#include +#include +#include + +#include +#include +#include + +#include "fd_info.h" +#include "fdi_pipe.h" + +/** + * @brief Clear request + * @details Send a CLEAR request to the logger daemon + * @param[in] sock_fd The socket to send the request over + * @return 1 on success, 0 on failure + */ +static int do_clear_pipe(int sock_fd) +{ + assert(sock_fd >= 0); + + int r = send_dlog_request(sock_fd, DLOG_REQ_CLEAR, NULL, 0); + if (r < 0) + printf("Error: could not send a CLEAR request to logger %s\n", strerror(-r)); + + return r; +} + +/** + * @brief Send a logger request + * @details Send a logging request to the daemon + * @param[in] argc Argument count + * @param[in] argv Argument values + * @param[in] sock_fd Socket file descriptor + * @return 0 on success, -errno on failure + */ +static int send_logger_request(int argc, char **argv, int sock_fd) +{ + char request_string[MAX_LOGGER_REQUEST_LEN] = "dlogutil"; + int len = strlen(request_string); + + for (int i = 1; i < argc; i++) { + int arglen = strnlen(argv[i], MAX_LOGGER_REQUEST_LEN); + int needed = arglen + 1 /* space */ + 1 /* null byte */; + if (len + needed > sizeof(request_string)) + return 0; + + strncat(request_string, " ", 1); + strncat(request_string, argv[i], arglen + 1); + len += needed; + } + + int r = send_dlog_request(sock_fd, DLOG_REQ_HANDLE_LOGUTIL, request_string, len); + if (r < 0) + printf("Error: could not send a logger request; socket write failed\n"); + + return r; +} +/** + * @brief Process buffer (pipe version) + * @details Finalizes a buffer: sends the appropriate socket request + * @param[in] buffer_name The name of the buffer + * @param[in] clear Whether to clear the buffer + * @param[in] conf The configuration + * @param[in] argc Argument count + * @param[in] argv Argument values + * @return FD wrapper structure of a pipe if we are to read from one, else NULL + */ + +struct fd_info *process_buffer_pipe(const char *buffer_name, int clear, struct log_config *conf, int argc, char **argv) +{ + char conf_key[MAX_CONF_KEY_LEN]; + int argc_processed = 0; + char * argv_processed[argc]; + char const * sock_path; + int sock_fd = -1; + int pipe_fd; + int i; + struct fd_info *ret = NULL; + + snprintf(conf_key, sizeof(conf_key), "%s_ctl_sock", buffer_name); + sock_path = log_config_get(conf, conf_key); + if (!sock_path) { + printf("Error: Socket %s is unavailable!\n", conf_key); + goto cleanup; + } + + sock_fd = connect_sock(sock_path); + if (sock_fd < 0) { + printf("Error: Could not connect to socket %s!\n", sock_path); + goto cleanup; + } + + if (clear) { + do_clear_pipe(sock_fd); + goto cleanup; + } + + for (i = 0; i < argc; ++i) { + if ((!strcmp("-b", argv[i])) + || !strcmp("--dumpfile", argv[i]) + || !strcmp("-f", argv[i]) + || !strcmp("-r", argv[i]) + || !strcmp("-n", argv[i])) + ++i; + else + argv_processed[argc_processed++] = argv[i]; + } + + if (send_logger_request(argc_processed, argv_processed, sock_fd) < 0) { + printf("Error: could not send request to logger daemon\n"); + goto cleanup; + } + + pipe_fd = recv_pipe(sock_fd); + if (pipe_fd < 0) { + printf("Error: couldn't retrieve pipe fd\n"); + goto cleanup; + } + + int do_sorting = strcmp(buffer_name, "kmsg") && strcmp(buffer_name, "syslog"); + ret = fdi_create(pipe_fd, do_sorting, UNLIMITED_LOG_LEN, PIPE); + + if (!ret) { + close(pipe_fd); + goto cleanup; + } + +cleanup: + if (sock_fd >= 0) + close(sock_fd); + + return ret; +} + diff --git a/src/logutil/fdi_pipe.h b/src/logutil/fdi_pipe.h new file mode 100644 index 0000000..1e96ee8 --- /dev/null +++ b/src/logutil/fdi_pipe.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include "fd_info.h" + +struct fd_info *process_buffer_pipe(const char *buffer_name, int clear, struct log_config *conf, int argc, char **argv); + diff --git a/src/logutil/logutil.c b/src/logutil/logutil.c index 2a34f0e..3377966 100755 --- a/src/logutil/logutil.c +++ b/src/logutil/logutil.c @@ -15,27 +15,23 @@ */ #include -#include -#include -#include #include #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include + #include #include #include #include + +#include "fd_info.h" +#include "fdi_pipe.h" +#include "fdi_logger.h" +#include "fdi_binfile.h" #include "logutil_doc.h" -#include #include "sort_vector.h" /** @@ -47,11 +43,6 @@ * @{ */ -/* How large (in bytes) the pipe receiving buffer is. */ -#define RECEIVE_BUFFER_SIZE 16384 - -#define UNLIMITED_LOG_LEN (-RECEIVE_BUFFER_SIZE - 1) // value not reachable through a single read() - // buffers to use by default, when nothing specified static const int default_buffers = (1 << LOG_ID_MAIN) | (1 << LOG_ID_SYSTEM) | (1 << LOG_ID_APPS); @@ -61,116 +52,6 @@ typedef enum action_e { ACTION_CLEAR, } action_e; -typedef enum { - PIPE, - BINARY_FILE, - ANDROID_LOGGER -} fd_type; - -struct fd_info { - int fd; - int do_sorting; - int log_len; - fd_type type; - int index; - char buff[RECEIVE_BUFFER_SIZE]; -}; - -static void fdi_free(struct fd_info *fdi) -{ - if (!fdi) - return; - - if (fdi->fd >= 0) - close(fdi->fd); - free(fdi); -} - -static void fdi_array_free(struct fd_info ***arr) -{ - assert(arr); - - if (!*arr) - return; - - for (int i = 0; (*arr)[i]; ++i) - fdi_free((*arr)[i]); - - free(*arr); -} - -/** - * @brief Create struct fd_info - * @details Allocates memory for the struct and initializes it with given arguments - * @param[in] fd file descriptor - * @param[in] do_sorting specifies if the logs read from fd should be sorted - * @param[in] log_len up to how many bytes the logs should be read from fd - * UNLIMITED_LOG_LEN for unlimited logs reading - * @param[in] type source type we read from defined in enum fd_type - * @return FD created struct or NULL on memory allocation failure - */ -static struct fd_info *create_fd_info(int fd, int do_sorting, int log_len, fd_type type) -{ - struct fd_info *fdi = malloc(sizeof(struct fd_info)); - if (!fdi) - return NULL; - - fdi->fd = fd; - fdi->do_sorting = do_sorting; - fdi->log_len = log_len; - fdi->type = type; - fdi->index = 0; - - return fdi; -} - -/** - * @brief Clear request - * @details Send a CLEAR request to the logger daemon - * @param[in] sock_fd The socket to send the request over - * @return 1 on success, 0 on failure - */ -static int do_clear_pipe(int sock_fd) -{ - assert(sock_fd >= 0); - - int r = send_dlog_request(sock_fd, DLOG_REQ_CLEAR, NULL, 0); - if (r < 0) - printf("Error: could not send a CLEAR request to logger %s\n", strerror(-r)); - - return r; -} -/** - * @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 - * @details Sends a clear ioctl to given fd - * @param[in] fd File descriptor of the buffer - * @remarks ANDROID LOGGER version - */ -void clear_log_logger(int fd) -{ - int ret = ioctl(fd, LOGGER_FLUSH_LOG); - if (ret < 0) - _E("ioctl LOGGER_FLUSH_LOG failed (%d)", errno); -} - /** * @brief Get buffer size * @details Print the size of the working buffer @@ -200,37 +81,6 @@ static int do_getsize(struct log_config *conf, int enabled_buffers) } /** - * @brief Send a logger request - * @details Send a logging request to the daemon - * @param[in] argc Argument count - * @param[in] argv Argument values - * @param[in] sock_fd Socket file descriptor - * @return 0 on success, -errno on failure - */ -static int send_logger_request(int argc, char **argv, int sock_fd) -{ - char request_string[MAX_LOGGER_REQUEST_LEN] = "dlogutil"; - int len = strlen(request_string); - - for (int i = 1; i < argc; i++) { - int arglen = strnlen(argv[i], MAX_LOGGER_REQUEST_LEN); - int needed = arglen + 1 /* space */ + 1 /* null byte */; - if (len + needed > sizeof(request_string)) - return 0; - - strncat(request_string, " ", 1); - strncat(request_string, argv[i], arglen + 1); - len += needed; - } - - int r = send_dlog_request(sock_fd, DLOG_REQ_HANDLE_LOGUTIL, request_string, len); - if (r < 0) - printf("Error: could not send a logger request; socket write failed\n"); - - return r; -} - -/** * @brief Process log * @details Processes a raw log and, if it's old enough, prints it * @param[in] e The entry to process @@ -260,80 +110,6 @@ static int process_log(struct logger_entry *e, struct logger_entry *last, struct return 0; } -static int fdi_read(struct fd_info *fdi) -{ - assert(fdi); - - if (fdi->index == RECEIVE_BUFFER_SIZE) - return -EAGAIN; - - int r = read(fdi->fd, fdi->buff + fdi->index, RECEIVE_BUFFER_SIZE - fdi->index); - if (r < 0) - return -errno; - - if (fdi->type == ANDROID_LOGGER) { - struct logger_entry *const le = (struct logger_entry *)fdi->buff; - parse_androidlogger_message((struct android_logger_entry *)fdi->buff, le, r); - add_recv_timestamp(le); - fdi->index = le->len; - } else { - fdi->index += r; - } - - if (fdi->log_len > 0) - fdi->log_len -= r; - - return r; -} - -static int fdi_has_log(struct fd_info *fdi) -{ - assert(fdi); - const struct logger_entry *const le = (const struct logger_entry *)fdi->buff; - return fdi->index >= sizeof le->len && fdi->index >= le->len; -} - -static struct logger_entry *fdi_extract_entry(struct fd_info *fdi) -{ - assert(fdi); - - struct logger_entry *const buf_le = (struct logger_entry *)fdi->buff; - if (!buf_le->len) - return NULL; - - struct logger_entry *const new_le = malloc(buf_le->len); - if (!new_le) - return NULL; - - memcpy(new_le, buf_le, buf_le->len); - fdi->index -= buf_le->len; - memmove(fdi->buff, fdi->buff + buf_le->len, fdi->index); - - return new_le; -} - -static int fdi_push_log(struct fd_info *fdi, int *dump, struct sort_vector *logs, struct log_file *l_file) -{ - assert(fdi); - assert(dump); - assert(l_file); - - struct logger_entry *temp = fdi_extract_entry(fdi); - if (!temp) - return -ENOMEM; - - if (fdi->do_sorting) { - sort_vector_push(logs, temp, l_file); - } else { - int write_err = logfile_write_with_rotation(temp, l_file); - free(temp); - if (!write_err && *dump && !--*dump) - return 1; - } - - return 0; -} - /** * @brief Handle input * @details The main loop reading log data @@ -459,174 +235,6 @@ static void handle_pipe(struct fd_info **data_fds, int fd_count, int dump, struc } } -/** - * @brief Handle a file - * @details Checks validity of a binary file - * @param[in] filename The file name - * @return A fd wrapper struct on valid file, else NULL - */ -struct fd_info *handle_file(char const *filename) -{ - assert(filename); - - int r; - int fd; - - fd = open(filename, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "File \"%s\" could not be opened: %m\n", filename); - return NULL; - } - - struct dlog_pipe_header header; - r = read(fd, &header, sizeof header); - if (r < 0) { - fprintf(stderr, "File \"%s\" read failed! %m\n", filename); - goto closefile; - } else if (r < sizeof header) { - fprintf(stderr, "File \"%s\" does not contain a full header!\n", filename); - goto closefile; - } - - if (header.endian != PIPE_FILE_ENDIAN_MAGIC) { - fprintf(stderr, "File \"%s\": unsupported endianness!\n", filename); - goto closefile; - } - - if (header.version != PIPE_FILE_FORMAT_VERSION) { - fprintf(stderr, "File \"%s\": file format version is %d but only %d is supported!\n", filename, header.version, PIPE_FILE_FORMAT_VERSION); - goto closefile; - } - - struct fd_info *fdi = create_fd_info(fd, 1, UNLIMITED_LOG_LEN, BINARY_FILE); - if (!fdi) { - fprintf(stderr, "Error: not enough memory\n"); - goto closefile; - } - return fdi; - -closefile: - close(fd); - return NULL; -} - -/** - * @brief Process buffer (non-pipe version) - * @details Finalizes a buffer: sends the appropriate socket request - * @param[in] buffer_name The name of the buffer - * @param[in] clear Whether to clear the buffer - * @param[in] conf The configuration - * @param[in] argc Argument count - * @param[in] argv Argument values - * @return FD wrapper structure to read from - */ -struct fd_info *process_buffer_nonpipe(const char *buffer_name, int clear, struct log_config *conf) -{ - char const * dev_path; - dev_path = log_config_get(conf, buffer_name); - if (!dev_path) - return NULL; - - int fd = open(dev_path, clear ? O_WRONLY : O_RDONLY); - if (fd < 0) - return NULL; - - if (clear) { - clear_log_logger(fd); - goto cleanup; - } - - const int log_len = logger_get_log_len(fd); - if (log_len < 0) - goto cleanup; - - struct fd_info *fdi = create_fd_info(fd, 1, log_len, ANDROID_LOGGER); - if (!fdi) - goto cleanup; - - return fdi; - -cleanup: - close(fd); - return NULL; -} - -/** - * @brief Process buffer (pipe version) - * @details Finalizes a buffer: sends the appropriate socket request - * @param[in] buffer_name The name of the buffer - * @param[in] clear Whether to clear the buffer - * @param[in] conf The configuration - * @param[in] argc Argument count - * @param[in] argv Argument values - * @return FD wrapper structure of a pipe if we are to read from one, else NULL - */ -struct fd_info *process_buffer_pipe(const char *buffer_name, int clear, struct log_config *conf, int argc, char **argv) -{ - char conf_key[MAX_CONF_KEY_LEN]; - int argc_processed = 0; - char * argv_processed[argc]; - char const * sock_path; - int sock_fd = -1; - int pipe_fd; - int i; - struct fd_info *ret = NULL; - - snprintf(conf_key, sizeof(conf_key), "%s_ctl_sock", buffer_name); - sock_path = log_config_get(conf, conf_key); - if (!sock_path) { - printf("Error: Socket %s is unavailable!\n", conf_key); - goto cleanup; - } - - sock_fd = connect_sock(sock_path); - if (sock_fd < 0) { - printf("Error: Could not connect to socket %s!\n", sock_path); - goto cleanup; - } - - if (clear) { - do_clear_pipe(sock_fd); - goto cleanup; - } - - for (i = 0; i < argc; ++i) { - if ((!strcmp("-b", argv[i])) - || !strcmp("--dumpfile", argv[i]) - || !strcmp("-f", argv[i]) - || !strcmp("-r", argv[i]) - || !strcmp("-n", argv[i])) - ++i; - else - argv_processed[argc_processed++] = argv[i]; - } - - if (send_logger_request(argc_processed, argv_processed, sock_fd) < 0) { - printf("Error: could not send request to logger daemon\n"); - goto cleanup; - } - - pipe_fd = recv_pipe(sock_fd); - if (pipe_fd < 0) { - printf("Error: couldn't retrieve pipe fd\n"); - goto cleanup; - } - - int do_sorting = strcmp(buffer_name, "kmsg") && strcmp(buffer_name, "syslog"); - ret = create_fd_info(pipe_fd, do_sorting, UNLIMITED_LOG_LEN, PIPE); - - if (!ret) { - close(pipe_fd); - goto cleanup; - } - -cleanup: - if (sock_fd >= 0) - close(sock_fd); - - return ret; -} - int parse_options(int argc, char **argv, struct log_file *l_file, struct sort_vector *logs, int *enabled_buffers, list_head *file_input_names, action_e *action, int *dump, int *tag_cnt) { assert(argv); -- 2.7.4