* @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,
++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) {
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;
}
}
- 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
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)
flush_logs(logs, callback, userdata, true);
-cleanup:
- free(evs);
- close(epollfd);
+ return 0;
}
static void show_version(const char *name)
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)
}
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;