summarylogtreecommitdiffstats
path: root/0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch
diff options
context:
space:
mode:
authorDobroslaw Kijowski2024-03-24 20:53:40 +0100
committerDobroslaw Kijowski2024-03-24 20:53:40 +0100
commit8469cb985a9cf74b0ca9aca338f12e66ec642029 (patch)
tree010a36fde5222bbce8e80e6618d2bd2e825398c9 /0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch
parent7a22fb06e7c4fc217cda23837bc8a4e29feb3d42 (diff)
downloadaur-relayd.tar.gz
Update to 20230121
Diffstat (limited to '0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch')
-rw-r--r--0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch397
1 files changed, 335 insertions, 62 deletions
diff --git a/0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch b/0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch
index 2a5c21f1bd9a..3d6a54155fae 100644
--- a/0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch
+++ b/0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch
@@ -1,27 +1,28 @@
-From 93e640d3236f1937ddb0ab07b06397cd950b6fb0 Mon Sep 17 00:00:00 2001
+From 34a2fa8165063b9dd47ab870562b9667ba26af39 Mon Sep 17 00:00:00 2001
From: Dobroslaw Kijowski <dobo90@gmail.com>
Date: Thu, 25 Mar 2021 22:06:53 +0100
Subject: [PATCH 1/3] libubox: import {list,uloop,utils}.h uloop{,-epoll}.c
From HEAD:
-commit 551d75b5662cccd0466b990d58136bdf799a804d
-Author: Peter Seiderer <ps.report@gmx.net>
-Date: Sat Mar 6 11:54:50 2021 +0100
+12bda4bdb1971385fd787737e8eec5a2eeb0deed (HEAD -> master, origin/master, origin/HEAD)
+Author: Christian Marangi <ansuelsmth@gmail.com>
+Date: Sat Feb 24 00:44:12 2024 +0100
- libubox: tests: add more blobmsg/json test cases
+ CI: add CodeQL workflow tests
- * add mixed int/double tests
- * add blobmsg_cast_u64/blobmsg_cast_s64 tests
+ Add CodeQL workflow action for security testing.
- Signed-off-by: Peter Seiderer <ps.report@gmx.net>
+ Enable security-and-quality queries.
+
+ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
- list.h | 208 ++++++++++++++++++
- uloop-epoll.c | 107 ++++++++++
- uloop.c | 581 ++++++++++++++++++++++++++++++++++++++++++++++++++
- uloop.h | 115 ++++++++++
- utils.h | 258 ++++++++++++++++++++++
- 5 files changed, 1269 insertions(+)
+ list.h | 228 ++++++++++++++++
+ uloop-epoll.c | 186 +++++++++++++
+ uloop.c | 704 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ uloop.h | 153 +++++++++++
+ utils.h | 270 +++++++++++++++++++
+ 5 files changed, 1541 insertions(+)
create mode 100644 list.h
create mode 100644 uloop-epoll.c
create mode 100644 uloop.c
@@ -30,10 +31,10 @@ Date: Sat Mar 6 11:54:50 2021 +0100
diff --git a/list.h b/list.h
new file mode 100644
-index 0000000..8e61e47
+index 0000000..6aa7b2a
--- /dev/null
+++ b/list.h
-@@ -0,0 +1,208 @@
+@@ -0,0 +1,228 @@
+/*-
+ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (c) 2010 Isilon Systems, Inc.
@@ -78,6 +79,14 @@ index 0000000..8e61e47
+ })
+#endif
+
++#ifndef container_of_safe
++#define container_of_safe(ptr, type, member) \
++ ({ \
++ const __typeof__(((type *) NULL)->member) *__mptr = (ptr); \
++ __mptr ? (type *)((char *) __mptr - offsetof(type, member)) : NULL; \
++ })
++#endif
++
+struct list_head {
+ struct list_head *next;
+ struct list_head *prev;
@@ -148,6 +157,8 @@ index 0000000..8e61e47
+#define list_entry(ptr, type, field) container_of(ptr, type, field)
+#define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field)
+#define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field)
++#define list_next_entry(pos, member) list_entry((pos)->member.next, typeof(*(pos)), member)
++#define list_entry_is_h(p, h, field) (&p->field == (h))
+
+#define list_for_each(p, head) \
+ for (p = (head)->next; p != (head); p = p->next)
@@ -159,6 +170,16 @@ index 0000000..8e61e47
+ for (p = list_first_entry(h, __typeof__(*p), field); &p->field != (h); \
+ p = list_entry(p->field.next, __typeof__(*p), field))
+
++#define list_for_each_entry_continue(p, h, field) \
++ for (p = list_next_entry(p, field); \
++ !list_entry_is_h(p, h, field); \
++ p = list_next_entry(p, field))
++
++#define list_for_each_entry_continue_reverse(p, h, field) \
++ for (p = list_prev_entry(p, field); \
++ !list_entry_is_h(p, h, field); \
++ p = list_prev_entry(p, field))
++
+#define list_for_each_entry_safe(p, n, h, field) \
+ for (p = list_first_entry(h, __typeof__(*p), field), \
+ n = list_entry(p->field.next, __typeof__(*p), field); &p->field != (h);\
@@ -244,10 +265,10 @@ index 0000000..8e61e47
+#endif /* _LINUX_LIST_H_ */
diff --git a/uloop-epoll.c b/uloop-epoll.c
new file mode 100644
-index 0000000..609ca6e
+index 0000000..d7b3acf
--- /dev/null
+++ b/uloop-epoll.c
-@@ -0,0 +1,107 @@
+@@ -0,0 +1,186 @@
+/*
+ * uloop - event loop implementation
+ *
@@ -303,7 +324,6 @@ index 0000000..609ca6e
+ ev.events |= EPOLLET;
+
+ ev.data.ptr = fd;
-+ fd->flags = flags;
+
+ return epoll_ctl(poll_fd, op, fd->fd, &ev);
+}
@@ -355,12 +375,92 @@ index 0000000..609ca6e
+
+ return nfds;
+}
++
++static void dispatch_timer(struct uloop_fd *u, unsigned int events)
++{
++ if (!(events & ULOOP_READ))
++ return;
++
++ uint64_t fired;
++
++ if (read(u->fd, &fired, sizeof(fired)) != sizeof(fired))
++ return;
++
++ struct uloop_interval *tm = container_of(u, struct uloop_interval, priv.ufd);
++
++ tm->expirations += fired;
++ tm->cb(tm);
++}
++
++static int timer_register(struct uloop_interval *tm, unsigned int msecs)
++{
++ if (!tm->priv.ufd.registered) {
++ int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC|TFD_NONBLOCK);
++
++ if (fd == -1)
++ return -1;
++
++ tm->priv.ufd.fd = fd;
++ tm->priv.ufd.cb = dispatch_timer;
++ }
++
++ struct itimerspec spec = {
++ .it_value = {
++ .tv_sec = msecs / 1000,
++ .tv_nsec = (msecs % 1000) * 1000000
++ },
++ .it_interval = {
++ .tv_sec = msecs / 1000,
++ .tv_nsec = (msecs % 1000) * 1000000
++ }
++ };
++
++ if (timerfd_settime(tm->priv.ufd.fd, 0, &spec, NULL) == -1)
++ goto err;
++
++ if (uloop_fd_add(&tm->priv.ufd, ULOOP_READ) == -1)
++ goto err;
++
++ return 0;
++
++err:
++ uloop_fd_delete(&tm->priv.ufd);
++ close(tm->priv.ufd.fd);
++ memset(&tm->priv.ufd, 0, sizeof(tm->priv.ufd));
++
++ return -1;
++}
++
++static int timer_remove(struct uloop_interval *tm)
++{
++ int ret = __uloop_fd_delete(&tm->priv.ufd);
++
++ if (ret == 0) {
++ close(tm->priv.ufd.fd);
++ memset(&tm->priv.ufd, 0, sizeof(tm->priv.ufd));
++ }
++
++ return ret;
++}
++
++static int64_t timer_next(struct uloop_interval *tm)
++{
++ struct itimerspec spec;
++
++ if (!tm->priv.ufd.registered)
++ return -1;
++
++ if (timerfd_gettime(tm->priv.ufd.fd, &spec) == -1)
++ return -1;
++
++ return spec.it_value.tv_sec * 1000 + spec.it_value.tv_nsec / 1000000;
++}
diff --git a/uloop.c b/uloop.c
new file mode 100644
-index 0000000..8517366
+index 0000000..da6f690
--- /dev/null
+++ b/uloop.c
-@@ -0,0 +1,581 @@
+@@ -0,0 +1,704 @@
+/*
+ * uloop - event loop implementation
+ *
@@ -389,6 +489,7 @@ index 0000000..8517366
+#include <string.h>
+#include <fcntl.h>
+#include <stdbool.h>
++#include <limits.h>
+
+#include "uloop.h"
+#include "utils.h"
@@ -398,6 +499,7 @@ index 0000000..8517366
+#endif
+#ifdef USE_EPOLL
+#include <sys/epoll.h>
++#include <sys/timerfd.h>
+#endif
+#include <sys/wait.h>
+
@@ -418,6 +520,7 @@ index 0000000..8517366
+
+static struct list_head timeouts = LIST_HEAD_INIT(timeouts);
+static struct list_head processes = LIST_HEAD_INIT(processes);
++static struct list_head signals = LIST_HEAD_INIT(signals);
+
+static int poll_fd = -1;
+bool uloop_cancelled = false;
@@ -429,6 +532,8 @@ index 0000000..8517366
+static int cur_fd, cur_nfds;
+static int uloop_run_depth = 0;
+
++uloop_fd_handler uloop_fd_set_cb = NULL;
++
+int uloop_fd_add(struct uloop_fd *sock, unsigned int flags);
+
+#ifdef USE_KQUEUE
@@ -439,18 +544,41 @@ index 0000000..8517366
+#include "uloop-epoll.c"
+#endif
+
-+static void waker_consume(struct uloop_fd *fd, unsigned int events)
++static void set_signo(uint64_t *signums, int signo)
+{
-+ char buf[4];
++ if (signo >= 1 && signo <= 64)
++ *signums |= (1u << (signo - 1));
++}
+
-+ while (read(fd->fd, buf, 4) > 0)
-+ ;
++static bool get_signo(uint64_t signums, int signo)
++{
++ return (signo >= 1) && (signo <= 64) && (signums & (1u << (signo - 1)));
++}
++
++static void signal_consume(struct uloop_fd *fd, unsigned int events)
++{
++ struct uloop_signal *usig, *usig_next;
++ uint64_t signums = 0;
++ uint8_t buf[32];
++ ssize_t nsigs;
++
++ do {
++ nsigs = read(fd->fd, buf, sizeof(buf));
++
++ for (ssize_t i = 0; i < nsigs; i++)
++ set_signo(&signums, buf[i]);
++ }
++ while (nsigs > 0);
++
++ list_for_each_entry_safe(usig, usig_next, &signals, list)
++ if (get_signo(signums, usig->signo))
++ usig->cb(usig);
+}
+
+static int waker_pipe = -1;
+static struct uloop_fd waker_fd = {
+ .fd = -1,
-+ .cb = waker_consume,
++ .cb = signal_consume,
+};
+
+static void waker_init_fd(int fd)
@@ -474,7 +602,7 @@ index 0000000..8517366
+ waker_pipe = fds[1];
+
+ waker_fd.fd = fds[0];
-+ waker_fd.cb = waker_consume;
++ waker_fd.cb = signal_consume;
+ uloop_fd_add(&waker_fd, ULOOP_READ);
+
+ return 0;
@@ -523,7 +651,7 @@ index 0000000..8517366
+ return false;
+}
+
-+static void uloop_run_events(int timeout)
++static void uloop_run_events(int64_t timeout)
+{
+ struct uloop_fd_event *cur;
+ struct uloop_fd *fd;
@@ -585,6 +713,10 @@ index 0000000..8517366
+ if (ret < 0)
+ goto out;
+
++ if (uloop_fd_set_cb)
++ uloop_fd_set_cb(sock, flags);
++
++ sock->flags = flags;
+ sock->registered = true;
+ sock->eof = false;
+ sock->error = false;
@@ -595,6 +727,7 @@ index 0000000..8517366
+
+int uloop_fd_delete(struct uloop_fd *fd)
+{
++ int ret;
+ int i;
+
+ for (i = 0; i < cur_nfds; i++) {
@@ -607,12 +740,18 @@ index 0000000..8517366
+ if (!fd->registered)
+ return 0;
+
++ if (uloop_fd_set_cb)
++ uloop_fd_set_cb(fd, 0);
++
+ fd->registered = false;
+ uloop_fd_stack_event(fd, -1);
-+ return __uloop_fd_delete(fd);
++ ret = __uloop_fd_delete(fd);
++ fd->flags = 0;
++
++ return ret;
+}
+
-+static int tv_diff(struct timeval *t1, struct timeval *t2)
++static int64_t tv_diff(struct timeval *t1, struct timeval *t2)
+{
+ return
+ (t1->tv_sec - t2->tv_sec) * 1000 +
@@ -682,6 +821,26 @@ index 0000000..8517366
+
+int uloop_timeout_remaining(struct uloop_timeout *timeout)
+{
++ int64_t td;
++ struct timeval now;
++
++ if (!timeout->pending)
++ return -1;
++
++ uloop_gettime(&now);
++
++ td = tv_diff(&timeout->time, &now);
++
++ if (td > INT_MAX)
++ return INT_MAX;
++ else if (td < INT_MIN)
++ return INT_MIN;
++ else
++ return (int)td;
++}
++
++int64_t uloop_timeout_remaining64(struct uloop_timeout *timeout)
++{
+ struct timeval now;
+
+ if (!timeout->pending)
@@ -754,10 +913,30 @@ index 0000000..8517366
+
+}
+
-+static void uloop_signal_wake(void)
++int uloop_interval_set(struct uloop_interval *timer, unsigned int msecs)
+{
++ return timer_register(timer, msecs);
++}
++
++int uloop_interval_cancel(struct uloop_interval *timer)
++{
++ return timer_remove(timer);
++}
++
++int64_t uloop_interval_remaining(struct uloop_interval *timer)
++{
++ return timer_next(timer);
++}
++
++static void uloop_signal_wake(int signo)
++{
++ uint8_t sigbyte = signo;
++
++ if (signo == SIGCHLD)
++ do_sigchld = true;
++
+ do {
-+ if (write(waker_pipe, "w", 1) < 0) {
++ if (write(waker_pipe, &sigbyte, 1) < 0) {
+ if (errno == EINTR)
+ continue;
+ }
@@ -769,13 +948,7 @@ index 0000000..8517366
+{
+ uloop_status = signo;
+ uloop_cancelled = true;
-+ uloop_signal_wake();
-+}
-+
-+static void uloop_sigchld(int signo)
-+{
-+ do_sigchld = true;
-+ uloop_signal_wake();
++ uloop_signal_wake(signo);
+}
+
+static void uloop_install_handler(int signum, void (*handler)(int), struct sigaction* old, bool add)
@@ -832,35 +1005,90 @@ index 0000000..8517366
+ uloop_install_handler(SIGTERM, uloop_handle_sigint, &old_sigterm, add);
+
+ if (uloop_handle_sigchld)
-+ uloop_install_handler(SIGCHLD, uloop_sigchld, &old_sigchld, add);
++ uloop_install_handler(SIGCHLD, uloop_signal_wake, &old_sigchld, add);
+
+ uloop_ignore_signal(SIGPIPE, add);
+}
+
-+static int uloop_get_next_timeout(struct timeval *tv)
++int uloop_signal_add(struct uloop_signal *s)
++{
++ struct list_head *h = &signals;
++ struct uloop_signal *tmp;
++ struct sigaction sa;
++
++ if (s->pending)
++ return -1;
++
++ list_for_each_entry(tmp, &signals, list) {
++ if (tmp->signo > s->signo) {
++ h = &tmp->list;
++ break;
++ }
++ }
++
++ list_add_tail(&s->list, h);
++ s->pending = true;
++
++ sigaction(s->signo, NULL, &s->orig);
++
++ if (s->orig.sa_handler != uloop_signal_wake) {
++ sa.sa_handler = uloop_signal_wake;
++ sa.sa_flags = 0;
++ sigemptyset(&sa.sa_mask);
++ sigaction(s->signo, &sa, NULL);
++ }
++
++ return 0;
++}
++
++int uloop_signal_delete(struct uloop_signal *s)
++{
++ if (!s->pending)
++ return -1;
++
++ list_del(&s->list);
++ s->pending = false;
++
++ if (s->orig.sa_handler != uloop_signal_wake)
++ sigaction(s->signo, &s->orig, NULL);
++
++ return 0;
++}
++
++int uloop_get_next_timeout(void)
+{
+ struct uloop_timeout *timeout;
-+ int diff;
++ struct timeval tv;
++ int64_t diff;
+
+ if (list_empty(&timeouts))
+ return -1;
+
++ uloop_gettime(&tv);
++
+ timeout = list_first_entry(&timeouts, struct uloop_timeout, list);
-+ diff = tv_diff(&timeout->time, tv);
++ diff = tv_diff(&timeout->time, &tv);
+ if (diff < 0)
+ return 0;
++ if (diff > INT_MAX)
++ return INT_MAX;
+
+ return diff;
+}
+
-+static void uloop_process_timeouts(struct timeval *tv)
++static void uloop_process_timeouts(void)
+{
+ struct uloop_timeout *t;
++ struct timeval tv;
++
++ if (list_empty(&timeouts))
++ return;
+
++ uloop_gettime(&tv);
+ while (!list_empty(&timeouts)) {
+ t = list_first_entry(&timeouts, struct uloop_timeout, list);
+
-+ if (tv_diff(&t->time, tv) > 0)
++ if (tv_diff(&t->time, &tv) > 0)
+ break;
+
+ uloop_timeout_cancel(t);
@@ -893,16 +1121,13 @@ index 0000000..8517366
+int uloop_run_timeout(int timeout)
+{
+ int next_time = 0;
-+ struct timeval tv;
+
+ uloop_run_depth++;
+
+ uloop_status = 0;
+ uloop_cancelled = false;
-+ while (!uloop_cancelled)
-+ {
-+ uloop_gettime(&tv);
-+ uloop_process_timeouts(&tv);
++ do {
++ uloop_process_timeouts();
+
+ if (do_sigchld)
+ uloop_handle_processes();
@@ -910,13 +1135,11 @@ index 0000000..8517366
+ if (uloop_cancelled)
+ break;
+
-+ uloop_gettime(&tv);
-+
-+ next_time = uloop_get_next_timeout(&tv);
-+ if (timeout >= 0 && timeout < next_time)
-+ next_time = timeout;
++ next_time = uloop_get_next_timeout();
++ if (timeout >= 0 && (next_time < 0 || timeout < next_time))
++ next_time = timeout;
+ uloop_run_events(next_time);
-+ }
++ } while (!uloop_cancelled && timeout < 0);
+
+ --uloop_run_depth;
+
@@ -944,10 +1167,10 @@ index 0000000..8517366
+}
diff --git a/uloop.h b/uloop.h
new file mode 100644
-index 0000000..36084f5
+index 0000000..4313dfe
--- /dev/null
+++ b/uloop.h
-@@ -0,0 +1,115 @@
+@@ -0,0 +1,153 @@
+/*
+ * uloop - event loop implementation
+ *
@@ -985,10 +1208,14 @@ index 0000000..36084f5
+struct uloop_fd;
+struct uloop_timeout;
+struct uloop_process;
++struct uloop_interval;
++struct uloop_signal;
+
+typedef void (*uloop_fd_handler)(struct uloop_fd *u, unsigned int events);
+typedef void (*uloop_timeout_handler)(struct uloop_timeout *t);
+typedef void (*uloop_process_handler)(struct uloop_process *c, int ret);
++typedef void (*uloop_interval_handler)(struct uloop_interval *t);
++typedef void (*uloop_signal_handler)(struct uloop_signal *s);
+
+#define ULOOP_READ (1 << 0)
+#define ULOOP_WRITE (1 << 1)
@@ -1033,20 +1260,54 @@ index 0000000..36084f5
+ pid_t pid;
+};
+
++struct uloop_interval
++{
++ uloop_interval_handler cb;
++ uint64_t expirations;
++
++ union {
++ struct uloop_fd ufd;
++ struct {
++ int64_t fired;
++ unsigned int msecs;
++ } time;
++ } priv;
++};
++
++struct uloop_signal
++{
++ struct list_head list;
++ struct sigaction orig;
++ bool pending;
++
++ uloop_signal_handler cb;
++ int signo;
++};
++
+extern bool uloop_cancelled;
+extern bool uloop_handle_sigchld;
++extern uloop_fd_handler uloop_fd_set_cb;
+
+int uloop_fd_add(struct uloop_fd *sock, unsigned int flags);
+int uloop_fd_delete(struct uloop_fd *sock);
+
++int uloop_get_next_timeout(void);
+int uloop_timeout_add(struct uloop_timeout *timeout);
+int uloop_timeout_set(struct uloop_timeout *timeout, int msecs);
+int uloop_timeout_cancel(struct uloop_timeout *timeout);
-+int uloop_timeout_remaining(struct uloop_timeout *timeout);
++int uloop_timeout_remaining(struct uloop_timeout *timeout) __attribute__((deprecated("use uloop_timeout_remaining64")));
++int64_t uloop_timeout_remaining64(struct uloop_timeout *timeout);
+
+int uloop_process_add(struct uloop_process *p);
+int uloop_process_delete(struct uloop_process *p);
+
++int uloop_interval_set(struct uloop_interval *timer, unsigned int msecs);
++int uloop_interval_cancel(struct uloop_interval *timer);
++int64_t uloop_interval_remaining(struct uloop_interval *timer);
++
++int uloop_signal_add(struct uloop_signal *s);
++int uloop_signal_delete(struct uloop_signal *s);
++
+bool uloop_cancelling(void);
+
+static inline void uloop_end(void)
@@ -1065,10 +1326,10 @@ index 0000000..36084f5
+#endif
diff --git a/utils.h b/utils.h
new file mode 100644
-index 0000000..5c53cc0
+index 0000000..dacac6e
--- /dev/null
+++ b/utils.h
-@@ -0,0 +1,258 @@
+@@ -0,0 +1,270 @@
+/*
+ * utils - misc libubox utility functions
+ *
@@ -1298,6 +1559,18 @@ index 0000000..5c53cc0
+#define __hidden __attribute__((visibility("hidden")))
+#endif
+
++#ifndef __has_attribute
++# define __has_attribute(x) 0
++#endif
++
++#ifndef fallthrough
++# if __has_attribute(__fallthrough__)
++# define fallthrough __attribute__((__fallthrough__))
++# else
++# define fallthrough do {} while (0) /* fallthrough */
++# endif
++#endif
++
+int b64_encode(const void *src, size_t src_len,
+ void *dest, size_t dest_len);
+
@@ -1328,5 +1601,5 @@ index 0000000..5c53cc0
+
+#endif
--
-2.31.0
+2.44.0