diff options
author | Dobroslaw Kijowski | 2024-03-24 20:53:40 +0100 |
---|---|---|
committer | Dobroslaw Kijowski | 2024-03-24 20:53:40 +0100 |
commit | 8469cb985a9cf74b0ca9aca338f12e66ec642029 (patch) | |
tree | 010a36fde5222bbce8e80e6618d2bd2e825398c9 /0001-libubox-import-list-uloop-utils-.h-uloop-epoll-.c.patch | |
parent | 7a22fb06e7c4fc217cda23837bc8a4e29feb3d42 (diff) | |
download | aur-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.patch | 397 |
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 |