* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define _GNU_SOURCE
#define __STDC_FORMAT_MACROS /* Required for PRIu64 to work. */
#include <errno.h>
#include <inttypes.h>
#include <signal.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdint.h>
+#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
+
#include <lxc/lxccontainer.h>
#include "arguments.h"
-#include "log.h"
-#include "lxc.h"
-#include "mainloop.h"
-#include "utils.h"
+#include "tool_utils.h"
#define USER_HZ 100
#define ESC "\033"
return 25;
}
-static int stdin_handler(int fd, uint32_t events, void *data,
- struct lxc_epoll_descr *descr)
-{
- char *in_char = data;
-
- if (events & EPOLLIN) {
- int rc;
-
- rc = read(fd, in_char, sizeof(*in_char));
- if (rc <= 0)
- *in_char = '\0';
- }
-
- if (events & EPOLLHUP)
- *in_char = 'q';
- return 1;
-}
-
static void sig_handler(int sig)
{
exit(EXIT_SUCCESS);
char **lines, **cols;
len = c->get_cgroup_item(c, item, buf, sizeof(buf));
- if (len <= 0 || len >= sizeof(buf)) {
+ if (len <= 0 || (size_t)len >= sizeof(buf)) {
fprintf(stderr, "unable to read cgroup item %s\n", item);
return;
}
size_humanize(stats->mem_used, mem_used_str, sizeof(mem_used_str));
ret = snprintf(iosb_str, sizeof(iosb_str), "%s(%s/%s)", iosb_total_str, iosb_read_str, iosb_write_str);
- if (ret < 0 || ret >= sizeof(iosb_str))
+ if (ret < 0 || (size_t)ret >= sizeof(iosb_str))
printf("snprintf'd too many characters: %d\n", ret);
printf("%-18.18s %12.2f %12.2f %12.2f %36s %10s",
printf(" %10s", kmem_used_str);
}
} else {
- gettimeofday(&time_val, NULL);
+ (void)gettimeofday(&time_val, NULL);
time_ms = (unsigned long long) (time_val.tv_sec) * 1000 + (unsigned long long) (time_val.tv_usec) / 1000;
printf("%" PRIu64 ",%s,%" PRIu64 ",%" PRIu64 ",%" PRIu64
",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64 ",%" PRIu64,
}
}
+#define LXC_MAINLOOP_CONTINUE 0
+#define LXC_MAINLOOP_CLOSE 1
+
+struct lxc_epoll_descr {
+ int epfd;
+ struct lxc_list handlers;
+};
+
+typedef int (*lxc_mainloop_callback_t)(int fd, uint32_t event, void *data,
+ struct lxc_epoll_descr *descr);
+
+struct mainloop_handler {
+ lxc_mainloop_callback_t callback;
+ int fd;
+ void *data;
+};
+
+#define MAX_EVENTS 10
+
+int lxc_mainloop(struct lxc_epoll_descr *descr, int timeout_ms)
+{
+ int i, nfds, ret;
+ struct mainloop_handler *handler;
+ struct epoll_event events[MAX_EVENTS];
+
+ for (;;) {
+ nfds = epoll_wait(descr->epfd, events, MAX_EVENTS, timeout_ms);
+ if (nfds < 0) {
+ if (errno == EINTR)
+ continue;
+
+ return -1;
+ }
+
+ for (i = 0; i < nfds; i++) {
+ handler = events[i].data.ptr;
+
+ /* If the handler returns a positive value, exit the
+ * mainloop.
+ */
+ ret = handler->callback(handler->fd, events[i].events,
+ handler->data, descr);
+ if (ret == LXC_MAINLOOP_CLOSE)
+ return 0;
+ }
+
+ if (nfds == 0)
+ return 0;
+
+ if (lxc_list_empty(&descr->handlers))
+ return 0;
+ }
+}
+
+int lxc_mainloop_open(struct lxc_epoll_descr *descr)
+{
+ /* hint value passed to epoll create */
+ descr->epfd = epoll_create1(EPOLL_CLOEXEC);
+ if (descr->epfd < 0)
+ return -1;
+
+ lxc_list_init(&descr->handlers);
+ return 0;
+}
+
+int lxc_mainloop_add_handler(struct lxc_epoll_descr *descr, int fd,
+ lxc_mainloop_callback_t callback, void *data)
+{
+ struct epoll_event ev;
+ struct mainloop_handler *handler;
+ struct lxc_list *item;
+
+ handler = malloc(sizeof(*handler));
+ if (!handler)
+ return -1;
+
+ handler->callback = callback;
+ handler->fd = fd;
+ handler->data = data;
+
+ ev.events = EPOLLIN;
+ ev.data.ptr = handler;
+
+ if (epoll_ctl(descr->epfd, EPOLL_CTL_ADD, fd, &ev) < 0)
+ goto out_free_handler;
+
+ item = malloc(sizeof(*item));
+ if (!item)
+ goto out_free_handler;
+
+ item->elem = handler;
+ lxc_list_add(&descr->handlers, item);
+ return 0;
+
+out_free_handler:
+ free(handler);
+ return -1;
+}
+
+int lxc_mainloop_close(struct lxc_epoll_descr *descr)
+{
+ struct lxc_list *iterator, *next;
+
+ iterator = descr->handlers.next;
+ while (iterator != &descr->handlers) {
+ next = iterator->next;
+
+ lxc_list_del(iterator);
+ free(iterator->elem);
+ free(iterator);
+ iterator = next;
+ }
+
+ if (descr->epfd >= 0)
+ return close(descr->epfd);
+
+ return 0;
+}
+
+static int stdin_handler(int fd, uint32_t events, void *data,
+ struct lxc_epoll_descr *descr)
+{
+ char *in_char = data;
+
+ if (events & EPOLLIN) {
+ int rc;
+
+ rc = read(fd, in_char, sizeof(*in_char));
+ if (rc <= 0)
+ *in_char = '\0';
+ }
+
+ if (events & EPOLLHUP)
+ *in_char = 'q';
+ return 1;
+}
+
int main(int argc, char *argv[])
{
struct lxc_epoll_descr descr;