Backported to glibc 2.8
[lttng-tools.git] / src / common / compat / compat-epoll.c
index f014a0d783d434f57fc95a5c17e126f62946e74e..368fae19f6c3615b00760ce99b07d0b3250c7cf1 100644 (file)
@@ -27,6 +27,8 @@
 
 #include <common/error.h>
 #include <common/defaults.h>
+#include <common/macros.h>
+#include <common/utils.h>
 
 #include "poll.h"
 
@@ -49,6 +51,11 @@ static int resize_poll_event(struct lttng_poll_event *events,
                PERROR("realloc epoll add");
                goto error;
        }
+       if (new_size > events->alloc_size) {
+               /* Zero newly allocated memory */
+               memset(ptr + events->alloc_size, 0,
+                       (new_size - events->alloc_size) * sizeof(*ptr));
+       }
        events->events = ptr;
        events->alloc_size = new_size;
 
@@ -74,7 +81,7 @@ int compat_epoll_create(struct lttng_poll_event *events, int size, int flags)
                size = poll_max_size;
        }
 
-       ret = epoll_create1(flags);
+       ret = compat_glibc_epoll_create(size, flags);
        if (ret < 0) {
                /* At this point, every error is fatal */
                PERROR("epoll_create1");
@@ -117,6 +124,11 @@ int compat_epoll_add(struct lttng_poll_event *events, int fd, uint32_t req_event
                goto error;
        }
 
+       /*
+        * Zero struct epoll_event to ensure all representations of its
+        * union are zeroed.
+        */
+       memset(&ev, 0, sizeof(ev));
        ev.events = req_events;
        ev.data.fd = fd;
 
@@ -201,11 +213,15 @@ int compat_epoll_wait(struct lttng_poll_event *events, int timeout)
         */
        if (events->nb_fd > events->alloc_size) {
                /* Expand if the nb_fd is higher than the actual size. */
-               new_size = events->alloc_size << 1UL;
+               new_size = max_t(uint32_t,
+                               1U << utils_get_count_order_u32(events->nb_fd),
+                               events->alloc_size << 1UL);
        } else if ((events->nb_fd << 1UL) <= events->alloc_size &&
                        events->nb_fd >= events->init_size) {
                /* Shrink if nb_fd multiplied by two is <= than the actual size. */
-               new_size = events->alloc_size >> 1UL;
+               new_size = max_t(uint32_t,
+                               utils_get_count_order_u32(events->nb_fd) >> 1U,
+                               events->alloc_size >> 1U);
        } else {
                /* Indicate that we don't want to resize. */
                new_size = 0;
@@ -244,6 +260,7 @@ error:
 void compat_epoll_set_max_size(void)
 {
        int ret, fd;
+       ssize_t size_ret;
        char buf[64];
 
        poll_max_size = DEFAULT_POLL_SIZE;
@@ -253,11 +270,16 @@ void compat_epoll_set_max_size(void)
                return;
        }
 
-       ret = read(fd, buf, sizeof(buf));
-       if (ret < 0) {
+       size_ret = lttng_read(fd, buf, sizeof(buf));
+       /*
+        * Allow reading a file smaller than buf, but keep space for
+        * final \0.
+        */
+       if (size_ret < 0 || size_ret >= sizeof(buf)) {
                PERROR("read set max size");
                goto error;
        }
+       buf[size_ret] = '\0';
 
        poll_max_size = atoi(buf);
        if (poll_max_size == 0) {
This page took 0.024015 seconds and 4 git commands to generate.