From 3f19a53996147cb191bfe02c2179ba4ec6514af6 Mon Sep 17 00:00:00 2001 From: Mateusz Majewski Date: Tue, 27 Aug 2019 15:25:43 +0200 Subject: [PATCH] Move print preparation into do_print Motivation for this is two-fold. First, it will allow us to reuse it in the libdlogutil in the future. Second, it allows us to merge the two loops that appear there (especially since do_print already did some additional preparation on the FDIs). Change-Id: Icd026476f3f453ccaca69ed992b32611f07c3a0a --- include/logcommon.h | 8 ++++++++ src/logutil/logutil.c | 53 ++++++++++++++++++++++++++------------------------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/include/logcommon.h b/include/logcommon.h index ff0a224..42d16e1 100644 --- a/include/logcommon.h +++ b/include/logcommon.h @@ -76,6 +76,14 @@ static inline void close_FILE(FILE *const *file) fclose(*file); } +static inline void close_fd(int *fd) +{ + assert(fd); + + if (*fd >= 0) + close(*fd); +} + char * log_name_by_id(log_id_t id); log_id_t log_id_by_name(const char *name); diff --git a/src/logutil/logutil.c b/src/logutil/logutil.c index 921c52d..861c11b 100644 --- a/src/logutil/logutil.c +++ b/src/logutil/logutil.c @@ -169,27 +169,35 @@ long sort_vector_time_span(struct sort_vector *logs) * @param[in] fd_count Size of the above array * @param[in] logs The log sorting vector * @param[in] l_file File output metadata + * @return int 0 if successful, 1 otherwise */ -static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector *logs, write_callback callback, void *userdata, log_filter *filter) +static int do_print(struct fd_info **data_fds, int fd_count, struct sort_vector *logs, write_callback callback, void *userdata, list_head filter_list, log_filter *filter_object) { assert(data_fds); assert(logs); assert(userdata); int epoll_cnt = 0; - int epollfd = epoll_create1(0); - struct epoll_event *evs = NULL; + __attribute__((cleanup(close_fd))) int epollfd = epoll_create1(0); if (epollfd < 0) { DBG("epoll_create failed: %m"); - return; + return 1; } for (int nfds = 0; nfds < fd_count; ++nfds) { - if (!data_fds[nfds]) + int r = data_fds[nfds]->ops->prepare_print(data_fds[nfds], logs->dump, filter_list, filter_object); + if (r > 0) { + // everything went fine, but we're not printing this one + fdi_free(data_fds[nfds]); + data_fds[nfds] = NULL; continue; + } else if (r < 0) { + ERR("Error while preparing for printing: %s", strerror(-r)); + return 1; + } int fd = data_fds[nfds]->fd; if (fd_set_flags(fd, O_NONBLOCK) < 0) - goto cleanup; + return 1; struct epoll_event ev = { .data.ptr = data_fds[nfds], .events = EPOLLIN, @@ -198,10 +206,10 @@ static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector ++epoll_cnt; } - evs = calloc(epoll_cnt, sizeof *evs); + __attribute__((cleanup(free_ptr))) struct epoll_event *evs = calloc(epoll_cnt, sizeof *evs); if (!evs) { ERR("Error: no memory for epoll array"); - goto cleanup; + return 1; } while (epoll_cnt > 0) { @@ -210,7 +218,7 @@ static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector nfds = epoll_wait(epollfd, evs, epoll_cnt, 100); while (nfds < 0 && errno == EINTR); if (nfds < 0) - goto cleanup; + return 1; for (int i = 0; i < nfds; ++i) { struct fd_info *fdi = evs[i].data.ptr; @@ -228,8 +236,8 @@ static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector } } - if (put_logs_into_vector(data_fds, fd_count, nfds, logs, callback, userdata, filter) < 0) - goto cleanup; + if (put_logs_into_vector(data_fds, fd_count, nfds, logs, callback, userdata, filter_object) < 0) + return 1; /* The oldest log can be so fresh as to be from the future * (i.e. has a negative age). This can happen when somebody @@ -244,8 +252,8 @@ static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector flush_logs(logs, callback, userdata, is_from_future); } - if (put_logs_into_vector(data_fds, fd_count, 0, logs, callback, userdata, filter) < 0) - goto cleanup; + if (put_logs_into_vector(data_fds, fd_count, 0, logs, callback, userdata, filter_object) < 0) + return 1; if (logs->dump != DUMP_CONTINUOUS && logs->dump != DUMP_INFINITE) while (sort_vector_used_size(logs) > logs->dump) @@ -253,9 +261,7 @@ static void do_print(struct fd_info **data_fds, int fd_count, struct sort_vector flush_logs(logs, callback, userdata, true); -cleanup: - free(evs); - close(epollfd); + return 0; } static void show_version(const char *name) @@ -583,15 +589,10 @@ int main(int argc, char **argv) case ACTION_CLEAR: r = fdi->ops->clear(fdi); break; - case ACTION_PRINT: { - r = fdi->ops->prepare_print(fdi, logs.dump, filter_list, filter_object); - if (r > 0) { - // everything went fine, but we're not printing this one - fdi_free(fdi); - fdi_ptrs[i] = NULL; - } + case ACTION_PRINT: + // No action here. We have to keep the case because otherwise we get a warning. break; - } case ACTION_GETSIZE: { + case ACTION_GETSIZE: { uint32_t size; r = fdi->ops->getsize(fdi, &size); if (!r) @@ -611,10 +612,10 @@ int main(int argc, char **argv) } if (action == ACTION_PRINT) - do_print(fdi_ptrs, fdi_cnt, &logs, logfile_callback, &(struct logfile_callback_data) { + return do_print(fdi_ptrs, fdi_cnt, &logs, logfile_callback, &(struct logfile_callback_data) { .file = &l_file, .sort_by = logs.sort_by, - }, filter_object); + }, filter_list, filter_object); return 0; -- 2.7.4