]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
tools: move lxc-top to API symbols only
authorChristian Brauner <christian.brauner@ubuntu.com>
Fri, 12 Jan 2018 15:29:46 +0000 (16:29 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 6 Feb 2018 20:10:48 +0000 (21:10 +0100)
Closes #2073.

Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/tools/lxc_top.c

index 5d5c08a252623858e90a2b8667df4938e96fb0ce..868693866c610ecc03989e587603877d5d8a1ce9 100644 (file)
  * 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"
@@ -181,24 +182,6 @@ static int stdin_tios_rows(void)
        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);
@@ -310,7 +293,7 @@ static void stat_get_blk_stats(struct lxc_container *c, const char *item,
        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;
        }
@@ -409,7 +392,7 @@ static void stats_print(const char *name, const struct stats *stats,
                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",
@@ -429,7 +412,7 @@ static void stats_print(const char *name, const struct stats *stats,
                        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,
@@ -554,6 +537,143 @@ static void ct_realloc(int active_cnt)
        }
 }
 
+#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;