···109109 ${CMAKE_BINARY_DIR}/${DARLING_SDK_RELATIVE_PATH}/usr/include/libxml2
110110)
111111112112+add_subdirectory(external/libkqueue)
113113+112114# needs to come before libplatform because it generates mig headers that libplatform needs
113115add_subdirectory(kernel)
114116
···1111#include "../bsdthread/workq_kernreturn.h"
1212#include "kevent64.h"
13131414-// not static because `mach_init.c` needs to reset it on fork
1515-// (but since we're using symbol visibility, no one else will be able to see it, so it's ok)
1616-// we can remove this once our LKM supports kqueue workqs and workloops (at that point, this syscall will turn into a simple trap into the LKM)
1717-int default_kq = -1;
1414+static int default_kq = -1;
18151916extern void* memmove(void* dst, const void* src, __SIZE_TYPE__ n);
2020-2121-// we have an LKM trap for kevent_qos, but due to our LKM not supporting workqs and workloops yet,
2222-// it's easier to keep our old behavior and translate this into a kevent64 call and handle workq stuff ourselves.
2323-// TODO: support workqs and workloops in the LKM (requires in-kernel pthread operations)
24172518static void kevent_qos_to_64(const struct kevent_qos_s *ev, struct kevent64_s* ev64);
2619static void kevent_64_to_qos(const struct kevent64_s* ev64, struct kevent_qos_s *ev);
···3831 if ((kq == -1) != !!(flags & KEVENT_FLAG_WORKQ))
3932 return -EINVAL;
40334141- if (kq < 0) {
4242- if (default_kq == -1) {
4343- default_kq = sys_kqueue();
4444- }
4545- kq = default_kq;
3434+ if (default_kq == -1)
3535+ {
3636+ default_kq = sys_kqueue();
3737+ sys_fcntl(default_kq, F_SETFD, FD_CLOEXEC);
4638 }
47394840 if (changelist != NULL && nchanges > 0)
···77#include <lkm/api.h>
88#include "../simple.h"
991010+__attribute__((weak))
1111+__attribute__((visibility("default")))
1212+int kqueue_close(int kq) { return -1; }
1313+1014long sys_close(int fd)
1115{
1216 CANCELATION_POINT();
···2529 ret = LINUX_SYSCALL1(__NR_close, fd);
2630 if (ret < 0)
2731 ret = errno_linux_to_bsd(ret);
3232+ else
3333+ kqueue_close(fd);
28342935 return ret;
3036}
···39454046 return ret;
4147}
4848+4949+// Special variant for libkqueue to avoid recursion into kqueue_close()
5050+__attribute__((visibility("default")))
5151+long __close_for_kqueue(int fd)
5252+{
5353+ return close_internal(fd);
5454+}
5555+
+6
src/kernel/emulation/linux/unistd/dup.c
···33#include "../errno.h"
44#include <linux-syscalls/linux.h>
5566+__attribute__((weak))
77+__attribute__((visibility("default")))
88+void kqueue_dup(int oldfd, int newfd) { }
99+610long sys_dup(int fd)
711{
812 int ret;
···1014 ret = LINUX_SYSCALL1(__NR_dup, fd);
1115 if (ret < 0)
1216 ret = errno_linux_to_bsd(ret);
1717+ else
1818+ kqueue_dup(fd, ret);
13191420 return ret;
1521}
+4
src/kernel/emulation/linux/unistd/dup2.c
···66#include "../mach/lkm.h"
77#include <lkm/api.h>
8899+extern void kqueue_dup(int oldfd, int newfd);
1010+911long sys_dup2(int fd_from, int fd_to)
1012{
1113 int ret;
···2224 #endif
2325 if (ret < 0)
2426 ret = errno_linux_to_bsd(ret);
2727+ else
2828+ kqueue_dup(fd_from, fd_to);
25292630 return ret;
2731}
-4
src/kernel/libsyscall/mach/mach_init.c
···64646565#ifdef DARLING
6666#include <darling/lkm/api.h>
6767-6868-extern int default_kq;
6967#endif
70687169mach_port_t bootstrap_port = MACH_PORT_NULL;
···141139_mach_fork_child(void)
142140{
143141#ifdef DARLING
144144- // we only have to reset to `-1`; the LKM takes care of closing it for us
145145- default_kq = -1;
146142 mach_init_doit(NULL);
147143#else
148144 mach_init_doit();