Ravenports generated: 08 Feb 2023 00:14
[ravenports.git] / bucket_D7 / wayland
1 # Buildsheet autogenerated by ravenadm tool -- Do not edit.
2
3 NAMEBASE=               wayland
4 VERSION=                1.21.0
5 KEYWORDS=               graphics
6 VARIANTS=               standard
7 SDESC[standard]=        Wayland Display Protocol implementation
8 HOMEPAGE=               https://wayland.freedesktop.org/
9 CONTACT=                Peeter_Must[karu.pruun@gmail.com]
10
11 DOWNLOAD_GROUPS=        main
12 SITES[main]=            https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.21.0/downloads/
13 DISTFILE[1]=            wayland-1.21.0.tar.xz:main
14 DF_INDEX=               1
15 SPKGS[standard]=        complete
16                         primary
17
18 OPTIONS_AVAILABLE=      none
19 OPTIONS_STANDARD=       none
20
21 ONLY_FOR_OPSYS=         dragonfly
22
23 BUILD_DEPENDS=          libxslt:single:standard
24 BUILDRUN_DEPENDS=       libffi:single:standard
25
26 USES=                   cpe meson pkgconfig expat
27 GNOME_COMPONENTS=       libxml2
28
29 LICENSE=                MIT:complete
30 LICENSE_FILE=           MIT:{{WRKSRC}}/COPYING
31 LICENSE_SCHEME=         solo
32
33 FPC_EQUIVALENT=         graphics/wayland
34 MESON_ARGS=             -Ddocumentation=false
35
36 INSTALL_TARGET=         install-strip
37 INSTALL_REQ_TOOLCHAIN=  yes
38
39 [FILE:131:descriptions/desc.primary]
40 Wayland is intended as a simpler replacement for X, easier to develop
41 and maintain. GNOME and KDE are expected to be ported to it.
42
43
44 [FILE:100:distinfo]
45 6dc64d7fc16837a693a51cfdb2e568db538bfdc9f457d4656285bb9594ef11ac       225936 wayland-1.21.0.tar.xz
46
47
48 [FILE:798:manifests/plist.primary]
49 bin/wayland-scanner
50 include/
51  wayland-client-core.h
52  wayland-client-protocol.h
53  wayland-client.h
54  wayland-cursor.h
55  wayland-egl-backend.h
56  wayland-egl-core.h
57  wayland-egl.h
58  wayland-server-core.h
59  wayland-server-protocol.h
60  wayland-server.h
61  wayland-util.h
62  wayland-version.h
63 lib/
64  libwayland-client.so
65  libwayland-client.so.0
66  libwayland-client.so.0.21.0
67  libwayland-cursor.so
68  libwayland-cursor.so.0
69  libwayland-cursor.so.0.21.0
70  libwayland-egl.so
71  libwayland-egl.so.1
72  libwayland-egl.so.1.21.0
73  libwayland-server.so
74  libwayland-server.so.0
75  libwayland-server.so.0.21.0
76 lib/pkgconfig/
77  wayland-client.pc
78  wayland-cursor.pc
79  wayland-egl-backend.pc
80  wayland-egl.pc
81  wayland-scanner.pc
82  wayland-server.pc
83 share/aclocal/wayland-scanner.m4
84 share/wayland/
85  wayland-scanner.mk
86  wayland.dtd
87  wayland.xml
88
89
90 [FILE:1508:patches/patch-meson.build]
91 --- meson.build.orig    2022-10-22 10:59:58.476779000 +0200
92 +++ meson.build 2022-10-31 16:12:58.994390000 +0100
93 @@ -16,7 +16,7 @@
94  config_h.set_quoted('PACKAGE_VERSION', meson.project_version())
95  
96  cc_args = []
97 -if host_machine.system() != 'freebsd'
98 +if host_machine.system() != 'dragonfly'
99         cc_args += ['-D_POSIX_C_SOURCE=200809L']
100  endif
101  add_project_arguments(cc_args, language: 'c')
102 @@ -43,7 +43,6 @@
103         'mkostemp',
104         'posix_fallocate',
105         'prctl',
106 -       'memfd_create',
107         'mremap',
108         'strndup',
109  ]
110 @@ -52,11 +51,11 @@
111  endforeach
112  config_h.set10('HAVE_XUCRED_CR_PID', cc.has_member('struct xucred', 'cr_pid', prefix : '#include <sys/ucred.h>'))
113  have_broken_msg_cmsg_cloexec = false
114 -if host_machine.system() == 'freebsd'
115 +if host_machine.system() == 'freebsd' or host_machine.system() == 'dragonfly'
116         have_broken_msg_cmsg_cloexec = not cc.compiles('''
117  #include <sys/param.h> /* To get __FreeBSD_version. */
118  #if __FreeBSD_version < 1300502 || \
119 -    (__FreeBSD_version >= 1400000 && __FreeBSD_version < 1400006)
120 +    (__FreeBSD_version >= 1400000 && __FreeBSD_version < 1400006) || defined(__DragonFly__)
121  /*
122   * FreeBSD had a broken implementation of MSG_CMSG_CLOEXEC between 2015 and
123   * 2021. Check if we are compiling against a version that includes the fix
124 @@ -80,8 +79,6 @@
125         ffi_dep = dependency('libffi')
126  
127         decls = [
128 -               { 'header': 'sys/signalfd.h', 'symbol': 'SFD_CLOEXEC' },
129 -               { 'header': 'sys/timerfd.h', 'symbol': 'TFD_CLOEXEC' },
130                 { 'header': 'time.h', 'symbol': 'CLOCK_MONOTONIC' },
131         ]
132  
133
134
135 [FILE:1350:patches/patch-src_connection.c]
136 --- src/connection.c.orig       2022-10-22 10:58:12.859174000 +0200
137 +++ src/connection.c    2022-11-01 18:50:36.315356000 +0100
138 @@ -38,6 +38,7 @@
139  #include <sys/types.h>
140  #include <sys/socket.h>
141  #include <time.h>
142 +#include <poll.h>
143  #include <ffi.h>
144  
145  #include "wayland-util.h"
146 @@ -306,7 +307,10 @@
147  
148                 msg.msg_iov = iov;
149                 msg.msg_iovlen = count;
150 -               msg.msg_control = (clen > 0) ? cmsg : NULL;
151 +               if (clen == 0)
152 +                       msg.msg_control = NULL;
153 +               else
154 +                       msg.msg_control = cmsg;
155                 msg.msg_controllen = clen;
156  
157                 do {
158 @@ -376,11 +380,25 @@
159  wl_connection_write(struct wl_connection *connection,
160                     const void *data, size_t count)
161  {
162 -       if (connection->out.head - connection->out.tail +
163 +       struct pollfd pfd;
164 +
165 +       while (connection->out.head - connection->out.tail +
166             count > ARRAY_LENGTH(connection->out.data)) {
167 -               connection->want_flush = 1;
168 -               if (wl_connection_flush(connection) < 0)
169 -                       return -1;
170 +               if (wl_connection_flush(connection) < 0) {
171 +                       if (errno == EAGAIN) {
172 +                               pfd.fd = connection->fd;
173 +                               pfd.events = POLLWRNORM;
174 +                               pfd.revents = 0;
175 +                               int ret;
176 +                               do {
177 +                                       ret = poll(&pfd, 1, -1);
178 +                               } while (ret == -1 && errno == EINTR);
179 +                       } else {
180 +                               wl_log("%s: wl_connection_flush failed: %s\n",
181 +                                   __func__, strerror(errno));
182 +                               return -1;
183 +                       }
184 +               }
185         }
186  
187         if (ring_buffer_put(&connection->out, data, count) < 0)
188
189
190 [FILE:16870:patches/patch-src_event-loop.c]
191 --- src/event-loop.c.orig       2022-11-01 19:04:03.507533000 +0100
192 +++ src/event-loop.c    2022-11-01 19:04:05.187496000 +0100
193 @@ -34,10 +34,9 @@
194  #include <string.h>
195  #include <fcntl.h>
196  #include <sys/socket.h>
197 +#include <sys/types.h>
198 +#include <sys/event.h>
199  #include <sys/un.h>
200 -#include <sys/epoll.h>
201 -#include <sys/signalfd.h>
202 -#include <sys/timerfd.h>
203  #include <unistd.h>
204  #include "wayland-util.h"
205  #include "wayland-private.h"
206 @@ -68,7 +67,7 @@
207  };
208  
209  struct wl_event_loop {
210 -       int epoll_fd;
211 +       int event_fd;
212         struct wl_list check_list;
213         struct wl_list idle_list;
214         struct wl_list destroy_list;
215 @@ -80,7 +79,7 @@
216  
217  struct wl_event_source_interface {
218         int (*dispatch)(struct wl_event_source *source,
219 -                       struct epoll_event *ep);
220 +                       struct kevent *kv);
221  };
222  
223  
224 @@ -94,22 +93,22 @@
225  
226  static int
227  wl_event_source_fd_dispatch(struct wl_event_source *source,
228 -                           struct epoll_event *ep)
229 +                           struct kevent *ev)
230  {
231         struct wl_event_source_fd *fd_source = (struct wl_event_source_fd *) source;
232         uint32_t mask;
233  
234         mask = 0;
235 -       if (ep->events & EPOLLIN)
236 +       if (ev->filter == EVFILT_READ)
237                 mask |= WL_EVENT_READABLE;
238 -       if (ep->events & EPOLLOUT)
239 +       if (ev->filter == EVFILT_WRITE)
240                 mask |= WL_EVENT_WRITABLE;
241 -       if (ep->events & EPOLLHUP)
242 +       if (ev->flags & EV_EOF)
243                 mask |= WL_EVENT_HANGUP;
244 -       if (ep->events & EPOLLERR)
245 +       if (ev->flags & EV_ERROR)
246                 mask |= WL_EVENT_ERROR;
247  
248 -       return fd_source->func(fd_source->fd, mask, source->data);
249 +       return fd_source->func(source->fd, mask, source->data);
250  }
251  
252  struct wl_event_source_interface fd_source_interface = {
253 @@ -120,30 +119,10 @@
254  add_source(struct wl_event_loop *loop,
255            struct wl_event_source *source, uint32_t mask, void *data)
256  {
257 -       struct epoll_event ep;
258 -
259 -       if (source->fd < 0) {
260 -               free(source);
261 -               return NULL;
262 -       }
263 -
264         source->loop = loop;
265         source->data = data;
266         wl_list_init(&source->link);
267  
268 -       memset(&ep, 0, sizeof ep);
269 -       if (mask & WL_EVENT_READABLE)
270 -               ep.events |= EPOLLIN;
271 -       if (mask & WL_EVENT_WRITABLE)
272 -               ep.events |= EPOLLOUT;
273 -       ep.data.ptr = source;
274 -
275 -       if (epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, source->fd, &ep) < 0) {
276 -               close(source->fd);
277 -               free(source);
278 -               return NULL;
279 -       }
280 -
281         return source;
282  }
283  
284 @@ -179,6 +158,9 @@
285  {
286         struct wl_event_source_fd *source;
287  
288 +       struct kevent events[2];
289 +       unsigned int num_events = 0;
290 +
291         source = zalloc(sizeof *source);
292         if (source == NULL)
293                 return NULL;
294 @@ -187,8 +169,36 @@
295         source->base.fd = wl_os_dupfd_cloexec(fd, 0);
296         source->func = func;
297         source->fd = fd;
298 +       add_source(loop, &source->base, mask, data);
299 +
300 +       if (source->base.fd < 0) {
301 +               fprintf(stderr, "Could not add source\n: %s\n",
302 +                       strerror(errno));
303 +               free(source);
304 +               return NULL;
305 +       }
306  
307 -       return add_source(loop, &source->base, mask, data);
308 +       if (mask & WL_EVENT_READABLE) {
309 +               EV_SET(&events[num_events], source->base.fd, EVFILT_READ,
310 +                     EV_ADD | EV_ENABLE, 0, 0, &source->base);
311 +               num_events++;
312 +       }
313 +
314 +       if (mask & WL_EVENT_WRITABLE) {
315 +               EV_SET(&events[num_events], source->base.fd, EVFILT_WRITE,
316 +                     EV_ADD | EV_ENABLE, 0, 0, &source->base);
317 +               num_events++;
318 +       }
319 +
320 +       if (kevent(loop->event_fd, events, num_events, NULL, 0, NULL) < 0) {
321 +               fprintf(stderr, "Error adding source %i (%p) to loop %p: %s\n",
322 +                      source->fd, source, loop, strerror(errno));
323 +               close(source->base.fd);
324 +               free(source);
325 +               return NULL;
326 +       }
327 +
328 +       return &source->base;
329  }
330  
331  /** Update a file descriptor source's event mask
332 @@ -215,16 +225,22 @@
333  wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask)
334  {
335         struct wl_event_loop *loop = source->loop;
336 -       struct epoll_event ep;
337 +       struct kevent events[2];
338 +       unsigned int num_events = 0;
339 +
340 +       if (mask & WL_EVENT_READABLE) {
341 +               EV_SET(&events[num_events], source->fd, EVFILT_READ,
342 +                      EV_ADD | EV_ENABLE, 0, 0, source);
343 +               num_events++;
344 +       }
345  
346 -       memset(&ep, 0, sizeof ep);
347 -       if (mask & WL_EVENT_READABLE)
348 -               ep.events |= EPOLLIN;
349 -       if (mask & WL_EVENT_WRITABLE)
350 -               ep.events |= EPOLLOUT;
351 -       ep.data.ptr = source;
352 +       if (mask & WL_EVENT_WRITABLE) {
353 +               EV_SET(&events[num_events], source->fd, EVFILT_WRITE,
354 +                      EV_ADD | EV_ENABLE, 0, 0, source);
355 +               num_events++;
356 +       }
357  
358 -       return epoll_ctl(loop->epoll_fd, EPOLL_CTL_MOD, source->fd, &ep);
359 +       return kevent(loop->event_fd, events, num_events, NULL, 0, NULL);
360  }
361  
362  /** \cond INTERNAL */
363 @@ -239,7 +255,7 @@
364  
365  static int
366  noop_dispatch(struct wl_event_source *source,
367 -             struct epoll_event *ep) {
368 +             struct kevent *ep) {
369         return 0;
370  }
371  
372 @@ -257,25 +273,47 @@
373  }
374  
375  static int
376 -set_timer(int timerfd, struct timespec deadline) {
377 -       struct itimerspec its;
378 +set_timer(int timerfd,
379 +          struct timespec deadline,
380 +          struct wl_timer_heap *timers)
381 +{
382 +       struct kevent ev;
383 +       struct timespec now;
384 +       time_t diff_sec;
385 +       long diff_nsec;
386 +       long rel_deadline;  /* msec */
387 +
388 +       if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
389 +               return -1;
390 +
391 +       if (!time_lt(now, deadline))
392 +               return -1;
393 +
394 +       diff_sec = deadline.tv_sec - now.tv_sec;
395 +       diff_nsec = deadline.tv_nsec - now.tv_nsec;
396 +       if (diff_nsec < 0) {
397 +               diff_sec--;
398 +               diff_nsec += 1000000000L;
399 +       }
400  
401 -       its.it_interval.tv_sec = 0;
402 -       its.it_interval.tv_nsec = 0;
403 -       its.it_value = deadline;
404 -       return timerfd_settime(timerfd, TFD_TIMER_ABSTIME, &its, NULL);
405 +       rel_deadline = (long) ((diff_sec * 1000) + (diff_nsec / 1000000));
406 +       if ((diff_nsec % 1000000) > 499999)
407 +               rel_deadline++;
408 +
409 +       EV_SET(&ev, timerfd, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_ONESHOT,
410 +              0, rel_deadline, timers);
411 +
412 +       return kevent(timers->base.loop->event_fd, &ev, 1, NULL, 0, NULL);
413  }
414  
415  static int
416 -clear_timer(int timerfd)
417 +clear_timer(int timerfd, struct wl_timer_heap *timers)
418  {
419 -       struct itimerspec its;
420 +       struct kevent ev;
421  
422 -       its.it_interval.tv_sec = 0;
423 -       its.it_interval.tv_nsec = 0;
424 -       its.it_value.tv_sec = 0;
425 -       its.it_value.tv_nsec = 0;
426 -       return timerfd_settime(timerfd, 0, &its, NULL);
427 +       EV_SET(&ev, timerfd, EVFILT_TIMER, EV_ADD | EV_DISABLE,
428 +              0, 0, timers);
429 +       return kevent(timers->base.loop->event_fd, &ev, 1, NULL, 0, NULL);
430  }
431  
432  static void
433 @@ -296,37 +334,43 @@
434  static void
435  wl_timer_heap_release(struct wl_timer_heap *timers)
436  {
437 -       if (timers->base.fd != -1) {
438 -               close(timers->base.fd);
439 -       }
440         free(timers->data);
441  }
442  
443 +/*
444 + * Timers are now kept in a binary heap. There is only one timer source
445 + * which is used for all timer events. This routine ensures that the single
446 + * kevent timer is created.
447 + */
448  static int
449  wl_timer_heap_ensure_timerfd(struct wl_timer_heap *timers)
450  {
451 -       struct epoll_event ep;
452 -       int timer_fd;
453 -
454 -       if (timers->base.fd != -1)
455 -               return 0;
456 -
457 -       memset(&ep, 0, sizeof ep);
458 -       ep.events = EPOLLIN;
459 -       ep.data.ptr = timers;
460 -
461 -       timer_fd = timerfd_create(CLOCK_MONOTONIC,
462 -                                 TFD_CLOEXEC | TFD_NONBLOCK);
463 -       if (timer_fd < 0)
464 -               return -1;
465 -
466 -       if (epoll_ctl(timers->base.loop->epoll_fd,
467 -                     EPOLL_CTL_ADD, timer_fd, &ep) < 0) {
468 -               close(timer_fd);
469 +       struct kevent ev;
470 +       /*
471 +        * Deprecated.
472 +        * We don't need a static counter any more, but keep it here for now.
473 +        * It must be => 0.
474 +        */
475 +       static int timer_id = 1;
476 +
477 +       /*
478 +        * We need to add timer filter already here. This avoids error messages
479 +        * when the timer filter is removed before ever updating it.
480 +        * Note the timer will not be enabled, this happens only in the update
481 +        * routine which arms/disarms the timer.)
482 +        */
483 +       EV_SET(&ev, timer_id,
484 +              EVFILT_TIMER, EV_ADD | EV_DISABLE | EV_ONESHOT, 0, 0, timers);
485 +       if (kevent(timers->base.loop->event_fd, &ev, 1, NULL, 0, NULL) < 0) {
486 +               fprintf(stderr, "Could not add timer: %s\n",
487 +                       strerror(errno));
488                 return -1;
489         }
490  
491 -       timers->base.fd = timer_fd;
492 +       timers->base.fd = timer_id;
493 +       /* Deprecated, same as above. */
494 +       timer_id++;
495 +
496         return 0;
497  }
498  
499 @@ -484,7 +528,6 @@
500         heap_sift_up(timers->data, source);
501  }
502  
503 -
504  static int
505  wl_timer_heap_dispatch(struct wl_timer_heap *timers)
506  {
507 @@ -511,10 +554,10 @@
508                 list_tail->next_due = NULL;
509  
510         if (timers->active > 0) {
511 -               if (set_timer(timers->base.fd, timers->data[0]->deadline) < 0)
512 +               if (set_timer(timers->base.fd, timers->data[0]->deadline, timers) < 0)
513                         return -1;
514         } else {
515 -               if (clear_timer(timers->base.fd) < 0)
516 +               if (clear_timer(timers->base.fd, timers) < 0)
517                         return -1;
518         }
519  
520 @@ -531,7 +574,7 @@
521  
522  static int
523  wl_event_source_timer_dispatch(struct wl_event_source *source,
524 -                              struct epoll_event *ep)
525 +                              struct kevent *ev)
526  {
527         struct wl_event_source_timer *timer;
528  
529 @@ -639,7 +682,7 @@
530                 if (tsource->heap_idx == 0) {
531                         /* Only update the timerfd if the new deadline is
532                          * the earliest */
533 -                       if (set_timer(timers->base.fd, deadline) < 0)
534 +                       if (set_timer(timers->base.fd, timers->data[0]->deadline, timers) < 0)
535                                 return -1;
536                 }
537         } else {
538 @@ -650,7 +693,7 @@
539                 if (timers->active == 0) {
540                         /* Only update the timerfd if this was the last
541                          * active timer */
542 -                       if (clear_timer(timers->base.fd) < 0)
543 +                       if (clear_timer(timers->base.fd, timers) < 0)
544                                 return -1;
545                 }
546         }
547 @@ -670,17 +713,11 @@
548  
549  static int
550  wl_event_source_signal_dispatch(struct wl_event_source *source,
551 -                               struct epoll_event *ep)
552 +                               struct kevent *ev)
553  {
554 -       struct wl_event_source_signal *signal_source =
555 -               (struct wl_event_source_signal *) source;
556 -       struct signalfd_siginfo signal_info;
557 -       int len;
558 -
559 -       len = read(source->fd, &signal_info, sizeof signal_info);
560 -       if (!(len == -1 && errno == EAGAIN) && len != sizeof signal_info)
561 -               /* Is there anything we can do here?  Will this ever happen? */
562 -               wl_log("signalfd read error: %s\n", strerror(errno));
563 +       struct wl_event_source_signal *signal_source;
564 +
565 +       signal_source = (struct wl_event_source_signal *) source;
566  
567         return signal_source->func(signal_source->signal_number,
568                                    signal_source->base.data);
569 @@ -717,6 +754,7 @@
570  {
571         struct wl_event_source_signal *source;
572         sigset_t mask;
573 +       struct kevent ev;
574  
575         source = zalloc(sizeof *source);
576         if (source == NULL)
577 @@ -724,15 +762,26 @@
578  
579         source->base.interface = &signal_source_interface;
580         source->signal_number = signal_number;
581 +       source->func = func;
582  
583         sigemptyset(&mask);
584         sigaddset(&mask, signal_number);
585 -       source->base.fd = signalfd(-1, &mask, SFD_CLOEXEC | SFD_NONBLOCK);
586         sigprocmask(SIG_BLOCK, &mask, NULL);
587  
588 -       source->func = func;
589 +       source->base.fd = 0;
590 +       add_source(loop, &source->base, WL_EVENT_READABLE, data);
591 +
592 +       EV_SET(&ev, signal_number, EVFILT_SIGNAL, EV_ADD | EV_ENABLE, 0, 0,
593 +              source);
594 +
595 +       if (kevent(loop->event_fd, &ev, 1, NULL, 0, NULL) < 0) {
596 +               fprintf(stderr, "Error adding signal for %i (%p), %p: %s\n",
597 +                       signal_number, source, loop, strerror(errno));
598 +               free(source);
599 +               return NULL;
600 +       }
601  
602 -       return add_source(loop, &source->base, WL_EVENT_READABLE, data);
603 +       return &source->base;
604  }
605  
606  /** \cond INTERNAL */
607 @@ -829,24 +878,100 @@
608  wl_event_source_remove(struct wl_event_source *source)
609  {
610         struct wl_event_loop *loop = source->loop;
611 +       int ret = 0, saved_errno = 0;
612 +
613 +       /*
614 +        * Since BSD doesn't treat all event sources as FDs, we need to
615 +        * differentiate by source interface.
616 +        */
617 +       if (source->interface == &fd_source_interface && source->fd >= 0) {
618 +               struct kevent ev[2];
619 +               int _ret[2], _saved_errno[2];
620 +
621 +               /*
622 +                * We haven't stored state about the mask used when adding the
623 +                * source, so we have to try and remove both READ and WRITE
624 +                * filters. One may fail, which is OK. Removal of the source has
625 +                * only failed if _both_ kevent() calls fail. We have to do two
626 +                * kevent() calls so that we can get independent return values
627 +                * for the two kevents.
628 +                */
629 +               EV_SET(&ev[0], source->fd, EVFILT_READ, EV_DELETE, 0, 0,
630 +                     source);
631 +               EV_SET(&ev[1], source->fd, EVFILT_WRITE, EV_DELETE, 0, 0,
632 +                     source);
633 +
634 +               _ret[0] = kevent(loop->event_fd, &ev[0], 1, NULL, 0, NULL);
635 +               _saved_errno[0] = errno;
636 +               _ret[1] = kevent(loop->event_fd, &ev[1], 1, NULL, 0, NULL);
637 +               _saved_errno[1] = errno;
638 +
639 +               if (_ret[0] >= _ret[1]) {
640 +                       ret = _ret[0];
641 +                       saved_errno = _saved_errno[0];
642 +               } else {
643 +                       ret = _ret[1];
644 +                       saved_errno = _saved_errno[1];
645 +               }
646 +
647 +               if ((_ret[0] < 0) && (_ret[1] < 0)) {
648 +                       fprintf(stderr,
649 +                               "Error removing fd = %i from kqueue: %s\n",
650 +                               source->fd, strerror(saved_errno));
651 +               }
652  
653 -       /* We need to explicitly remove the fd, since closing the fd
654 -        * isn't enough in case we've dup'ed the fd. */
655 -       if (source->fd >= 0) {
656 -               epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, source->fd, NULL);
657                 close(source->fd);
658                 source->fd = -1;
659 -       }
660 +       } else if (source->interface == &timer_source_interface) {
661 +
662 +               /*
663 +                * There is only timer event source with fd = 1 which is used
664 +                * for all timer events. Generally we do not need to remove
665 +                * the event source from kqueue.
666 +                */
667 +               if (source->fd >= 0) {
668 +                       struct kevent ev;
669 +
670 +                       EV_SET(&ev, source->fd, EVFILT_TIMER, EV_DELETE, 0, 0, source);
671 +                       ret = kevent(loop->event_fd, &ev, 1, NULL, 0, NULL);
672 +                       saved_errno = errno;
673 +
674 +                       if (ret < 0) {
675 +                               fprintf(stderr,
676 +                                       "Error removing timer = %i from kqueue: %s\n",
677 +                                       source->fd, strerror(saved_errno));
678 +                       }
679 +               }
680  
681 -       if (source->interface == &timer_source_interface &&
682 -           source->fd != TIMER_REMOVED) {
683 -               /* Disarm the timer (and the loop's timerfd, if necessary),
684 -                * before removing its space in the loop timer heap */
685 -               wl_event_source_timer_update(source, 0);
686 -               wl_timer_heap_unreserve(&loop->timers);
687 -               /* Set the fd field to to indicate that the timer should NOT
688 -                * be dispatched in `wl_event_loop_dispatch` */
689 -               source->fd = TIMER_REMOVED;
690 +               if (source->fd != TIMER_REMOVED) {
691 +                       /* Disarm the timer (and the loop's timerfd, if necessary),
692 +                        * before removing its space in the loop timer heap */
693 +                       wl_event_source_timer_update(source, 0);
694 +                       wl_timer_heap_unreserve(&loop->timers);
695 +                       /* Set the fd field to to indicate that the timer should NOT
696 +                        * be dispatched in `wl_event_loop_dispatch` */
697 +                       source->fd = TIMER_REMOVED;
698 +               }
699 +       } else if (source->interface == &signal_source_interface) {
700 +               struct kevent ev;
701 +               int signal_number;
702 +               struct wl_event_source_signal *_source;
703 +
704 +               /* Only one kevent() call needed. */
705 +               _source = (struct wl_event_source_signal *) source;
706 +               signal_number = _source->signal_number;
707 +
708 +               EV_SET(&ev, signal_number, EVFILT_SIGNAL, EV_DELETE, 0, 0,
709 +                     source);
710 +               ret = kevent(loop->event_fd, &ev, 1, NULL, 0, NULL);
711 +               saved_errno = errno;
712 +
713 +               if (ret < 0) {
714 +                       fprintf(stderr,
715 +                               "Error removing signal = %i from kqueue: %s\n",
716 +                               source->fd, strerror(saved_errno));
717 +               }
718 +               source->fd = -1;
719         }
720  
721         wl_list_remove(&source->link);
722 @@ -889,8 +1014,8 @@
723         if (loop == NULL)
724                 return NULL;
725  
726 -       loop->epoll_fd = wl_os_epoll_create_cloexec();
727 -       if (loop->epoll_fd < 0) {
728 +       loop->event_fd = wl_os_kqueue_create_cloexec();
729 +       if (loop->event_fd < 0) {
730                 free(loop);
731                 return NULL;
732         }
733 @@ -925,22 +1050,21 @@
734  
735         wl_event_loop_process_destroy_list(loop);
736         wl_timer_heap_release(&loop->timers);
737 -       close(loop->epoll_fd);
738 +       close(loop->event_fd);
739         free(loop);
740  }
741  
742  static bool
743  post_dispatch_check(struct wl_event_loop *loop)
744  {
745 -       struct epoll_event ep;
746 +       struct kevent ev;
747         struct wl_event_source *source, *next;
748         bool needs_recheck = false;
749  
750 -       ep.events = 0;
751         wl_list_for_each_safe(source, next, &loop->check_list, link) {
752                 int dispatch_result;
753  
754 -               dispatch_result = source->interface->dispatch(source, &ep);
755 +               dispatch_result = source->interface->dispatch(source, &ev);
756                 if (dispatch_result < 0) {
757                         wl_log("Source dispatch function returned negative value!\n");
758                         wl_log("This would previously accidentally suppress a follow-up dispatch\n");
759 @@ -994,19 +1118,25 @@
760  WL_EXPORT int
761  wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout)
762  {
763 -       struct epoll_event ep[32];
764 +       struct kevent ev[64];
765         struct wl_event_source *source;
766         int i, count;
767 +       struct timespec timeout_spec;
768         bool has_timers = false;
769  
770         wl_event_loop_dispatch_idle(loop);
771  
772 -       count = epoll_wait(loop->epoll_fd, ep, ARRAY_LENGTH(ep), timeout);
773 +       /* timeout is provided in milliseconds */
774 +       timeout_spec.tv_sec = (time_t) (timeout / 1000);
775 +       timeout_spec.tv_nsec = (long) (timeout % 1000) * 1000000L;
776 +
777 +       count = kevent(loop->event_fd, NULL, 0, ev, ARRAY_LENGTH(ev),
778 +                      (timeout != -1) ? &timeout_spec : NULL);
779         if (count < 0)
780                 return -1;
781  
782         for (i = 0; i < count; i++) {
783 -               source = ep[i].data.ptr;
784 +               source = ev[i].udata;
785                 if (source == &loop->timers.base)
786                         has_timers = true;
787         }
788 @@ -1022,9 +1152,10 @@
789         }
790  
791         for (i = 0; i < count; i++) {
792 -               source = ep[i].data.ptr;
793 -               if (source->fd != -1)
794 -                       source->interface->dispatch(source, &ep[i]);
795 +               source = ev[i].udata;
796 +               if (source->fd != -1) {
797 +                      source->interface->dispatch(source, &ev[i]);
798 +               }
799         }
800  
801         wl_event_loop_process_destroy_list(loop);
802 @@ -1055,7 +1186,7 @@
803  WL_EXPORT int
804  wl_event_loop_get_fd(struct wl_event_loop *loop)
805  {
806 -       return loop->epoll_fd;
807 +       return loop->event_fd;
808  }
809  
810  /** Register a destroy listener for an event loop context
811
812
813 [FILE:1352:patches/patch-src_wayland-os.c]
814 --- src/wayland-os.c.orig       2022-10-22 10:58:42.178509000 +0200
815 +++ src/wayland-os.c    2022-10-31 16:39:33.763815000 +0100
816 @@ -33,7 +33,7 @@
817  #include <fcntl.h>
818  #include <errno.h>
819  #include <string.h>
820 -#include <sys/epoll.h>
821 +#include <sys/event.h>
822  #include <sys/mman.h>
823  #include <sys/un.h>
824  #ifdef HAVE_SYS_UCRED_H
825 @@ -69,17 +69,19 @@
826  {
827         int fd;
828  
829 +#ifdef SOCK_CLOEXEC
830         fd = socket(domain, type | SOCK_CLOEXEC, protocol);
831         if (fd >= 0)
832                 return fd;
833         if (errno != EINVAL)
834                 return -1;
835 +#endif
836  
837         fd = socket(domain, type, protocol);
838         return set_cloexec_or_close(fd);
839  }
840  
841 -#if defined(__FreeBSD__)
842 +#if defined(__FreeBSD__) || defined(__DragonFly__)
843  int
844  wl_os_socket_peercred(int sockfd, uid_t *uid, gid_t *gid, pid_t *pid)
845  {
846 @@ -87,7 +89,7 @@
847         struct xucred ucred;
848  
849         len = sizeof(ucred);
850 -       if (getsockopt(sockfd, SOL_LOCAL, LOCAL_PEERCRED, &ucred, &len) < 0 ||
851 +       if (getsockopt(sockfd, 0, LOCAL_PEERCRED, &ucred, &len) < 0 ||
852             ucred.cr_version != XUCRED_VERSION)
853                 return -1;
854         *uid = ucred.cr_uid;
855 @@ -189,19 +191,11 @@
856  }
857  
858  int
859 -wl_os_epoll_create_cloexec(void)
860 +wl_os_kqueue_create_cloexec(void)
861  {
862         int fd;
863  
864 -#ifdef EPOLL_CLOEXEC
865 -       fd = epoll_create1(EPOLL_CLOEXEC);
866 -       if (fd >= 0)
867 -               return fd;
868 -       if (errno != EINVAL)
869 -               return -1;
870 -#endif
871 -
872 -       fd = epoll_create(1);
873 +       fd = kqueue();
874         return set_cloexec_or_close(fd);
875  }
876  
877
878
879 [FILE:367:patches/patch-src_wayland-os.h]
880 --- src/wayland-os.h.orig       2022-10-31 16:28:37.828288000 +0100
881 +++ src/wayland-os.h    2022-10-31 16:28:58.707858000 +0100
882 @@ -42,7 +42,7 @@
883  wl_os_recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags);
884  
885  int
886 -wl_os_epoll_create_cloexec(void);
887 +wl_os_kqueue_create_cloexec(void);
888  
889  int
890  wl_os_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
891
892
893 [FILE:758:patches/patch-src_wayland-server.c]
894 --- src/wayland-server.c.orig   2022-10-31 16:48:01.102621000 +0100
895 +++ src/wayland-server.c        2022-11-01 14:08:34.644016000 +0100
896 @@ -40,7 +40,6 @@
897  #include <assert.h>
898  #include <sys/time.h>
899  #include <fcntl.h>
900 -#include <sys/eventfd.h>
901  #include <sys/file.h>
902  #include <sys/stat.h>
903  
904 @@ -1075,10 +1074,6 @@
905                 return NULL;
906         }
907  
908 -       display->terminate_efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
909 -       if (display->terminate_efd < 0)
910 -               goto err_eventfd;
911 -
912         display->term_source = wl_event_loop_add_fd(display->loop,
913                                                     display->terminate_efd,
914                                                     WL_EVENT_READABLE,
915 @@ -1109,10 +1104,6 @@
916  
917  err_term_source:
918         close(display->terminate_efd);
919 -err_eventfd:
920 -       wl_event_loop_destroy(display->loop);
921 -       free(display);
922 -       return NULL;
923  }
924  
925  static void
926
927
928 [FILE:915:patches/patch-tests_os-wrappers-test.c]
929 --- tests/os-wrappers-test.c.orig       2022-11-01 14:26:03.250878000 +0100
930 +++ tests/os-wrappers-test.c    2022-11-01 14:28:28.137680000 +0100
931 @@ -39,7 +39,6 @@
932  #include <stdarg.h>
933  #include <fcntl.h>
934  #include <stdio.h>
935 -#include <sys/epoll.h>
936  
937  #include "wayland-private.h"
938  #include "test-runner.h"
939 @@ -152,15 +151,7 @@
940  __attribute__ ((visibility("default"))) int
941  epoll_create1(int flags)
942  {
943 -       wrapped_calls_epoll_create1++;
944 -
945 -       if (fall_back) {
946 -               wrapped_calls_epoll_create1++; /* epoll_create() not wrapped */
947 -               errno = EINVAL;
948 -               return -1;
949 -       }
950 -
951 -       return real_epoll_create1(flags);
952 +       return 0;
953  }
954  
955  static void
956 @@ -375,6 +366,7 @@
957         do_os_wrappers_recvmsg_cloexec(1);
958  }
959  
960 +#if !defined(__DragonFly__)
961  static void
962  do_os_wrappers_epoll_create_cloexec(int n)
963  {
964 @@ -406,5 +398,6 @@
965         init_fallbacks(1);
966         do_os_wrappers_epoll_create_cloexec(2);
967  }
968 +#endif
969  
970  /* FIXME: add tests for wl_os_accept_cloexec() */
971
972
973 [FILE:2778:patches/patch-tests_test-runner.c]
974 --- tests/test-runner.c.orig    2022-11-01 14:11:31.710109000 +0100
975 +++ tests/test-runner.c 2022-11-01 14:24:36.312796000 +0100
976 @@ -29,6 +29,7 @@
977  #include <unistd.h>
978  #include <stdio.h>
979  #include <stdlib.h>
980 +#include <signal.h>
981  #include <sys/types.h>
982  #include <sys/wait.h>
983  #include <sys/stat.h>
984 @@ -42,7 +43,9 @@
985  #ifdef HAVE_SYS_PROCCTL_H
986  #include <sys/procctl.h>
987  #elif defined(HAVE_SYS_PRCTL_H)
988 +#ifndef __DragonFly__
989  #include <sys/prctl.h>
990 +#endif
991  #ifndef PR_SET_PTRACER
992  # define PR_SET_PTRACER 0x59616d61
993  #endif
994 @@ -276,17 +279,22 @@
995                 close(pipefd[0]);
996                 if (buf == '-')
997                         _exit(1);
998 +#ifndef __DragonFly__
999                 if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) != 0)
1000                         _exit(1);
1001 +#endif
1002                 if (!waitpid(-1, NULL, 0))
1003                         _exit(1);
1004 +#ifndef __DragonFly__
1005                 ptrace(PTRACE_CONT, NULL, NULL);
1006                 ptrace(PTRACE_DETACH, ppid, NULL, NULL);
1007 +#endif
1008                 _exit(0);
1009         } else {
1010                 close(pipefd[0]);
1011  
1012                 /* Enable child to ptrace the parent process */
1013 +#ifndef __DragonFly__
1014                 rc = prctl(PR_SET_PTRACER, pid);
1015                 if (rc != 0 && errno != EINVAL) {
1016                         /* An error prevents us from telling if a debugger is attached.
1017 @@ -300,6 +308,7 @@
1018                         /* Signal to client that parent is ready by passing '+' */
1019                         write(pipefd[1], "+", 1);
1020                 }
1021 +#endif
1022                 close(pipefd[1]);
1023  
1024                 waitpid(pid, &status, 0);
1025 @@ -315,18 +324,16 @@
1026         const struct test *t;
1027         pid_t pid;
1028         int total, pass;
1029 +#ifdef __DragonFly__
1030 +       int status;
1031 +#else
1032         siginfo_t info;
1033 +#endif
1034  
1035         if (isatty(fileno(stderr)))
1036                 is_atty = 1;
1037 -
1038 -       if (is_debugger_attached()) {
1039 -               fd_leak_check_enabled = 0;
1040 -               timeouts_enabled = 0;
1041 -       } else {
1042 -               fd_leak_check_enabled = !getenv("WAYLAND_TEST_NO_LEAK_CHECK");
1043 -               timeouts_enabled = !getenv("WAYLAND_TEST_NO_TIMEOUTS");
1044 -       }
1045 +       fd_leak_check_enabled = !getenv("WAYLAND_TEST_NO_LEAK_CHECK");
1046 +       timeouts_enabled = !getenv("WAYLAND_TEST_NO_TIMEOUTS");
1047  
1048         if (argc == 2 && strcmp(argv[1], "--help") == 0)
1049                 usage(argv[0], EXIT_SUCCESS);
1050 @@ -358,6 +365,12 @@
1051                 if (pid == 0)
1052                         run_test(t); /* never returns */
1053  
1054 +#ifdef __DragonFly__
1055 +               if (wait(&status)) {
1056 +                       fprintf(stderr, "waitid failed: %m\n");
1057 +                       abort();
1058 +               }
1059 +#else
1060                 if (waitid(P_PID, pid, &info, WEXITED)) {
1061                         stderr_set_color(RED);
1062                         fprintf(stderr, "waitid failed: %s\n",
1063 @@ -366,6 +379,21 @@
1064  
1065                         abort();
1066                 }
1067 +#endif
1068 +
1069 +               fprintf(stderr, "test \"%s\":\t", t->name);
1070 +#ifdef __DragonFly__
1071 +               if (WIFEXITED(status)) {
1072 +                       fprintf(stderr, "exit status %d", WEXITSTATUS(status));
1073 +                       if (WEXITSTATUS(status) == EXIT_SUCCESS)
1074 +                               success = 1;
1075 +                       break;
1076 +               } else if (WIFSIGNALED(status) || WCOREDUMP(status)) {
1077 +                       fprintf(stderr, "signal %d", WTERMSIG(status));
1078 +                       break;
1079 +               }
1080 +#else
1081 +       
1082  
1083                 switch (info.si_code) {
1084                 case CLD_EXITED:
1085 @@ -390,6 +418,7 @@
1086  
1087                         break;
1088                 }
1089 +#endif
1090  
1091                 if (success) {
1092                         pass++;
1093