diff --git a/clients/calibrator.c b/clients/calibrator.c index b98a676..41a309b 100644 --- a/clients/calibrator.c +++ b/clients/calibrator.c @@ -34,7 +34,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" diff --git a/clients/clickdot.c b/clients/clickdot.c index 4a946df..29839e0 100644 --- a/clients/clickdot.c +++ b/clients/clickdot.c @@ -36,7 +36,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" diff --git a/clients/cliptest.c b/clients/cliptest.c index bdff3db..f4abd3b 100644 --- a/clients/cliptest.c +++ b/clients/cliptest.c @@ -51,7 +51,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "libweston/matrix.h" diff --git a/clients/constraints.c b/clients/constraints.c index e53389f..d98c53a 100644 --- a/clients/constraints.c +++ b/clients/constraints.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include "../shared/input-event-codes.h" #include #include "shared/helpers.h" diff --git a/clients/content_protection.c b/clients/content_protection.c index 6a5c63c..8ff4351 100644 --- a/clients/content_protection.c +++ b/clients/content_protection.c @@ -32,7 +32,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "weston-content-protection-client-protocol.h" #include "window.h" diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c index 0722e95..d64c7b2 100644 --- a/clients/desktop-shell.c +++ b/clients/desktop-shell.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include "../shared/input-event-codes.h" #include #include #include diff --git a/clients/editor.c b/clients/editor.c index ed67fd1..7f360fd 100644 --- a/clients/editor.c +++ b/clients/editor.c @@ -33,7 +33,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include diff --git a/clients/flower.c b/clients/flower.c index 3676c40..dcbc414 100644 --- a/clients/flower.c +++ b/clients/flower.c @@ -33,7 +33,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" diff --git a/clients/fullscreen.c b/clients/fullscreen.c index 5b3c906..ba0b1f3 100644 --- a/clients/fullscreen.c +++ b/clients/fullscreen.c @@ -33,7 +33,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" #include diff --git a/clients/image.c b/clients/image.c index b48d7f4..830f398 100644 --- a/clients/image.c +++ b/clients/image.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include "../shared/input-event-codes.h" #include diff --git a/clients/ivi-shell-user-interface.c b/clients/ivi-shell-user-interface.c index 2bf164e..b4c873a 100644 --- a/clients/ivi-shell-user-interface.c +++ b/clients/ivi-shell-user-interface.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include "../shared/input-event-codes.h" #include #include #include diff --git a/clients/keyboard.c b/clients/keyboard.c index 49b94ba..6689a71 100644 --- a/clients/keyboard.c +++ b/clients/keyboard.c @@ -31,7 +31,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" diff --git a/clients/meson.build b/clients/meson.build index 7cf5906..79ec40f 100644 --- a/clients/meson.build +++ b/clients/meson.build @@ -23,14 +23,25 @@ srcs_toytoolkit = [ viewporter_client_protocol_h, viewporter_protocol_c, ] +# libutil may not exist on all platforms (e.g., macOS) +dep_util = cc.find_library('util', required: false) + +# libepoll-shim is needed on BSD/macOS for epoll compatibility +dep_epoll_shim = dependency('epoll-shim', required: false) + deps_toytoolkit = [ dep_wayland_client, dep_lib_cairo_shared, dep_matrix_c, dep_xkbcommon, dependency('wayland-cursor'), - cc.find_library('util'), ] +if dep_util.found() + deps_toytoolkit += dep_util +endif +if dep_epoll_shim.found() + deps_toytoolkit += dep_epoll_shim +endif lib_toytoolkit = static_library( 'toytoolkit', srcs_toytoolkit, @@ -79,7 +90,7 @@ simple_clients = [ dep_libshared, dep_pixman, dep_libdrm, - dependency('libudev', version: '>= 136'), + dependency('libudev', version: '>= 136', required: simple_build_all or simple_clients_enabled.contains('dmabuf-feedback')), # gbm_bo_get_fd_for_plane() from 21.1.0 dependency('gbm', version: '>= 21.1.1', required: simple_build_all or simple_clients_enabled.contains('dmabuf-feedback'), @@ -452,14 +463,34 @@ if get_option('demo-clients') foreach t : demo_clients t_name = 'weston-' + t.get('basename') t_srcs = [ t.get('basename') + '.c' ] + t.get('add_sources', []) - t_deps = [ dep_toytoolkit, t.get('dep_objs', []) ] + + # Check if all dep_objs are available (skip if any stub dependency) + skip_client = false + t_dep_objs = t.get('dep_objs', []) + foreach dep_obj : t_dep_objs + if not dep_obj.found() + message('Skipping @0@ - missing internal dependency'.format(t_name)) + skip_client = true + break + endif + endforeach + if skip_client + continue + endif + + t_deps = [ dep_toytoolkit ] + t_dep_objs foreach depname : t.get('deps', []) dep = dependency(depname, required: false) if not dep.found() - error('@0@ requires \'@1@\' which was not found. If you rather not build this, set \'-Ddemo-clients=false\'.'.format(t_name, depname)) + message('Skipping @0@ - missing @1@'.format(t_name, depname)) + skip_client = true + break endif t_deps += dep endforeach + if skip_client + continue + endif executable( t_name, t_srcs, diff --git a/clients/resizor.c b/clients/resizor.c index 3caad55..6809f51 100644 --- a/clients/resizor.c +++ b/clients/resizor.c @@ -33,7 +33,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" diff --git a/clients/scaler.c b/clients/scaler.c index 3948fa2..0250a71 100644 --- a/clients/scaler.c +++ b/clients/scaler.c @@ -29,9 +29,10 @@ #include #include #include +#include #include -#include +#include "../shared/input-event-codes.h" #include "window.h" #include "viewporter-client-protocol.h" diff --git a/clients/simple-dmabuf-v4l.c b/clients/simple-dmabuf-v4l.c index 8ed3a0b..202c468 100644 --- a/clients/simple-dmabuf-v4l.c +++ b/clients/simple-dmabuf-v4l.c @@ -42,7 +42,7 @@ #include #include #include -#include +#include "../shared/input-event-codes.h" #include #include diff --git a/clients/simple-egl.c b/clients/simple-egl.c index 7cc98ea..4a7cf3a 100644 --- a/clients/simple-egl.c +++ b/clients/simple-egl.c @@ -32,7 +32,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include diff --git a/clients/simple-im.c b/clients/simple-im.c index a9ed27f..ba11a27 100644 --- a/clients/simple-im.c +++ b/clients/simple-im.c @@ -32,7 +32,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include "window.h" #include "input-method-unstable-v1-client-protocol.h" diff --git a/clients/simple-shm.c b/clients/simple-shm.c index 534acfa..d83e370 100644 --- a/clients/simple-shm.c +++ b/clients/simple-shm.c @@ -36,7 +36,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "shared/os-compatibility.h" diff --git a/clients/simple-timing.c b/clients/simple-timing.c index ed5b6ea..4f12b84 100644 --- a/clients/simple-timing.c +++ b/clients/simple-timing.c @@ -37,7 +37,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "shared/os-compatibility.h" diff --git a/clients/simple-vulkan.c b/clients/simple-vulkan.c index f795ec4..4dfc1dc 100644 --- a/clients/simple-vulkan.c +++ b/clients/simple-vulkan.c @@ -38,7 +38,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include diff --git a/clients/stacking.c b/clients/stacking.c index 6802559..71894ed 100644 --- a/clients/stacking.c +++ b/clients/stacking.c @@ -31,7 +31,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include diff --git a/clients/subsurfaces.c b/clients/subsurfaces.c index 530ee19..b27c371 100644 --- a/clients/subsurfaces.c +++ b/clients/subsurfaces.c @@ -34,7 +34,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include diff --git a/clients/tablet.c b/clients/tablet.c index 112fc4b..a902f98 100644 --- a/clients/tablet.c +++ b/clients/tablet.c @@ -30,7 +30,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" diff --git a/clients/terminal.c b/clients/terminal.c index beeea4b..265695a 100644 --- a/clients/terminal.c +++ b/clients/terminal.c @@ -33,15 +33,24 @@ #include #include #include -#include #include +#include + +/* PTY header varies by platform */ +#if defined(__APPLE__) +#include +#elif defined(__FreeBSD__) || defined(__DragonFly__) +#include +#else +#include +#endif #include #include #include #include #include -#include +#include "../shared/input-event-codes.h" #include @@ -3004,10 +3013,8 @@ terminal_create(struct display *display) /* Compute the average ascii glyph width */ cairo_text_extents(cr, TERMINAL_DRAW_SINGLE_WIDE_CHARACTERS, &text_extents); - terminal->average_width = howmany - (text_extents.width, - strlen(TERMINAL_DRAW_SINGLE_WIDE_CHARACTERS)); - terminal->average_width = ceil(terminal->average_width); + terminal->average_width = ceil(text_extents.width / + (double)strlen(TERMINAL_DRAW_SINGLE_WIDE_CHARACTERS)); cairo_destroy(cr); cairo_surface_destroy(surface); diff --git a/clients/touch-calibrator.c b/clients/touch-calibrator.c index 374ae49..906aca0 100644 --- a/clients/touch-calibrator.c +++ b/clients/touch-calibrator.c @@ -38,6 +38,12 @@ #include +/* program_invocation_short_name is a GNU extension */ +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#include +#define program_invocation_short_name getprogname() +#endif + #include "clients/window.h" #include "shared/helpers.h" #include diff --git a/clients/transformed.c b/clients/transformed.c index 1c1b9e9..4f0e0a0 100644 --- a/clients/transformed.c +++ b/clients/transformed.c @@ -32,7 +32,7 @@ #include #include -#include +#include "../shared/input-event-codes.h" #include #include "window.h" diff --git a/clients/window.c b/clients/window.c index 90440c1..d0ff05e 100644 --- a/clients/window.c +++ b/clients/window.c @@ -39,15 +39,16 @@ #include #include #include -#include #include +#include "../shared/platform-compat.h" + #include #include #include -#include +#include "../shared/input-event-codes.h" #include #include "shared/cairo-util.h" #include "shared/helpers.h" diff --git a/clients/window.h b/clients/window.h index 8b3d9d1..8b7b48a 100644 --- a/clients/window.h +++ b/clients/window.h @@ -28,6 +28,7 @@ #include #include +#include "../shared/platform-compat.h" #include #include #include diff --git a/meson.build b/meson.build index 1d8b62d..a80d329 100644 --- a/meson.build +++ b/meson.build @@ -87,7 +87,7 @@ optional_libc_funcs = [ 'mkostemp', 'strchrnul', 'initgroups', 'posix_fallocate', - 'memfd_create', 'unreachable', + 'memfd_create', 'unreachable', 'pipe2', 'timerfd_create', ] foreach func : optional_libc_funcs if cc.has_function(func) @@ -140,36 +140,55 @@ config_h.set_quoted('MODULEDIR', dir_module_weston) config_h.set_quoted('LIBWESTON_MODULEDIR', dir_module_libweston) +# Determine if we're building any compositor backends +building_any_backend = get_option('backend-drm') or get_option('backend-headless') or get_option('backend-pipewire') or get_option('backend-rdp') or get_option('backend-vnc') or get_option('backend-wayland') or get_option('backend-x11') + backend_default = get_option('backend-default') -if backend_default == 'auto' +if backend_default == 'auto' and building_any_backend foreach b : [ 'headless', 'x11', 'wayland', 'drm' ] if get_option('backend-' + b) backend_default = b endif endforeach endif -config_h.set_quoted('WESTON_NATIVE_BACKEND', backend_default) -message('The default backend is ' + backend_default) -if not get_option('backend-' + backend_default) - error('Backend @0@ was chosen as native but is not being built.'.format(backend_default)) + +if building_any_backend + config_h.set_quoted('WESTON_NATIVE_BACKEND', backend_default) + message('The default backend is ' + backend_default) + if backend_default not in ['auto', 'none'] and not get_option('backend-' + backend_default) + error('Backend @0@ was chosen as native but is not being built.'.format(backend_default)) + endif +else + config_h.set_quoted('WESTON_NATIVE_BACKEND', '') + message('No backends are being built (clients-only build)') endif dep_wayland_server = dependency('wayland-server', version: '>= 1.22.0') dep_wayland_client = dependency('wayland-client', version: '>= 1.22.0') dep_pixman = dependency('pixman-1', version: '>= 0.25.2') dep_xkbcommon = dependency('xkbcommon', version: '>= 0.5.0') -dep_libinput = dependency('libinput', version: '>= 1.2.0') -if dep_xkbcommon.version().version_compare('>= 1.8.0') - if dep_libinput.version().version_compare('>= 1.26.0') - config_h.set('HAVE_COMPOSE_AND_KANA', '1') + +# Linux-specific dependencies - only required when building backends +if building_any_backend + dep_libinput = dependency('libinput', version: '>= 1.2.0') + if dep_xkbcommon.version().version_compare('>= 1.8.0') + if dep_libinput.version().version_compare('>= 1.26.0') + config_h.set('HAVE_COMPOSE_AND_KANA', '1') + endif endif + dep_libevdev = dependency('libevdev') + dep_libdrm = dependency('libdrm', version: '>= 2.4.108') + dep_libdrm_headers = dep_libdrm.partial_dependency(compile_args: true) +else + # Provide stub dependencies for clients-only build + dep_libinput = dependency('', required: false) + dep_libevdev = dependency('', required: false) + dep_libdrm = dependency('', required: false) + dep_libdrm_headers = dependency('', required: false) endif -dep_libevdev = dependency('libevdev') dep_libm = cc.find_library('m') -dep_libdl = cc.find_library('dl') -dep_libdrm = dependency('libdrm', version: '>= 2.4.108') -dep_libdrm_headers = dep_libdrm.partial_dependency(compile_args: true) +dep_libdl = cc.find_library('dl', required: false) dep_threads = dependency('threads') dep_lcms2 = dependency('lcms2', version: '>= 2.9', required: false) @@ -177,15 +196,19 @@ config_h.set('HAVE_LCMS', '1') endif -dep_libdisplay_info = dependency( - 'libdisplay-info', - version: ['>= 0.2.0', '< 0.4.0'], - fallback: ['display-info', 'di_dep'], - default_options: [ - 'werror=false', - ], - required: true, -) +if building_any_backend + dep_libdisplay_info = dependency( + 'libdisplay-info', + version: ['>= 0.2.0', '< 0.4.0'], + fallback: ['display-info', 'di_dep'], + default_options: [ + 'werror=false', + ], + required: true, + ) +else + dep_libdisplay_info = dependency('', required: false) +endif prog_python = import('python').find_installation('python3') files_xxd_py = files('tools/xxd.py') @@ -228,15 +251,24 @@ subdir('include') subdir('protocol') subdir('shared') -subdir('libweston') -subdir('xwayland') -subdir('frontend') -subdir('desktop-shell') -subdir('ivi-shell') -subdir('kiosk-shell') -subdir('lua-shell') -subdir('remoting') -subdir('pipewire') + +# Compositor components - only build when backends are enabled +if building_any_backend + subdir('libweston') + subdir('xwayland') + subdir('frontend') + subdir('desktop-shell') + subdir('ivi-shell') + subdir('kiosk-shell') + subdir('lua-shell') + subdir('remoting') + subdir('pipewire') +else + # Stub dependencies for clients that optionally use libweston components + dep_libweston_private = dependency('', required: false) + dep_vertex_clipping = dependency('', required: false) +endif + subdir('clients') if get_option('tests') subdir('tests') diff --git a/meson_options.txt b/meson_options.txt index 0ebaee5..fd44274 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -47,9 +47,9 @@ option( option( 'backend-default', type: 'combo', - choices: [ 'auto', 'drm', 'wayland', 'x11', 'headless', 'rdp' ], - value: 'drm', - description: 'Default backend when no parent display server detected' + choices: [ 'auto', 'drm', 'wayland', 'x11', 'headless', 'rdp', 'none' ], + value: 'auto', + description: 'Default backend when no parent display server detected (use none for clients-only build)' ) option( diff --git a/shared/config-parser.c b/shared/config-parser.c index cd93e5f..1a4e636 100644 --- a/shared/config-parser.c +++ b/shared/config-parser.c @@ -44,6 +44,7 @@ #include #include "helpers.h" #include "string-helpers.h" +#include "os-compatibility.h" /** * \defgroup weston-config Weston configuration diff --git a/shared/frame.c b/shared/frame.c index e8d4cde..9248eac 100644 --- a/shared/frame.c +++ b/shared/frame.c @@ -31,7 +31,8 @@ #include #include #include -#include + +#include "input-event-codes.h" #include "cairo-util.h" #include "shared/file-util.h" diff --git a/shared/input-event-codes.h b/shared/input-event-codes.h new file mode 100644 index 0000000..8ffa188 --- /dev/null +++ b/shared/input-event-codes.h @@ -0,0 +1,148 @@ +/* + * Input event codes compatibility header for non-Linux systems + * + * On Linux, these come from or + * On other systems, we provide the subset needed by Weston clients. + */ + +#ifndef INPUT_EVENT_CODES_H +#define INPUT_EVENT_CODES_H + +#ifdef __linux__ +#include +#else + +/* Event types */ +#define EV_SYN 0x00 +#define EV_KEY 0x01 +#define EV_REL 0x02 +#define EV_ABS 0x03 + +/* Mouse buttons */ +#define BTN_MISC 0x100 +#define BTN_LEFT 0x110 +#define BTN_RIGHT 0x111 +#define BTN_MIDDLE 0x112 +#define BTN_SIDE 0x113 +#define BTN_EXTRA 0x114 + +/* Keyboard keys - common subset */ +#define KEY_RESERVED 0 +#define KEY_ESC 1 +#define KEY_1 2 +#define KEY_2 3 +#define KEY_3 4 +#define KEY_4 5 +#define KEY_5 6 +#define KEY_6 7 +#define KEY_7 8 +#define KEY_8 9 +#define KEY_9 10 +#define KEY_0 11 +#define KEY_MINUS 12 +#define KEY_EQUAL 13 +#define KEY_BACKSPACE 14 +#define KEY_TAB 15 +#define KEY_Q 16 +#define KEY_W 17 +#define KEY_E 18 +#define KEY_R 19 +#define KEY_T 20 +#define KEY_Y 21 +#define KEY_U 22 +#define KEY_I 23 +#define KEY_O 24 +#define KEY_P 25 +#define KEY_LEFTBRACE 26 +#define KEY_RIGHTBRACE 27 +#define KEY_ENTER 28 +#define KEY_LEFTCTRL 29 +#define KEY_A 30 +#define KEY_S 31 +#define KEY_D 32 +#define KEY_F 33 +#define KEY_G 34 +#define KEY_H 35 +#define KEY_J 36 +#define KEY_K 37 +#define KEY_L 38 +#define KEY_SEMICOLON 39 +#define KEY_APOSTROPHE 40 +#define KEY_GRAVE 41 +#define KEY_LEFTSHIFT 42 +#define KEY_BACKSLASH 43 +#define KEY_Z 44 +#define KEY_X 45 +#define KEY_C 46 +#define KEY_V 47 +#define KEY_B 48 +#define KEY_N 49 +#define KEY_M 50 +#define KEY_COMMA 51 +#define KEY_DOT 52 +#define KEY_SLASH 53 +#define KEY_RIGHTSHIFT 54 +#define KEY_KPASTERISK 55 +#define KEY_LEFTALT 56 +#define KEY_SPACE 57 +#define KEY_CAPSLOCK 58 +#define KEY_F1 59 +#define KEY_F2 60 +#define KEY_F3 61 +#define KEY_F4 62 +#define KEY_F5 63 +#define KEY_F6 64 +#define KEY_F7 65 +#define KEY_F8 66 +#define KEY_F9 67 +#define KEY_F10 68 +#define KEY_NUMLOCK 69 +#define KEY_SCROLLLOCK 70 +#define KEY_KP7 71 +#define KEY_KP8 72 +#define KEY_KP9 73 +#define KEY_KPMINUS 74 +#define KEY_KP4 75 +#define KEY_KP5 76 +#define KEY_KP6 77 +#define KEY_KPPLUS 78 +#define KEY_KP1 79 +#define KEY_KP2 80 +#define KEY_KP3 81 +#define KEY_KP0 82 +#define KEY_KPDOT 83 +#define KEY_F11 87 +#define KEY_F12 88 +#define KEY_KPENTER 96 +#define KEY_RIGHTCTRL 97 +#define KEY_KPSLASH 98 +#define KEY_RIGHTALT 100 +#define KEY_HOME 102 +#define KEY_UP 103 +#define KEY_PAGEUP 104 +#define KEY_LEFT 105 +#define KEY_RIGHT 106 +#define KEY_END 107 +#define KEY_DOWN 108 +#define KEY_PAGEDOWN 109 +#define KEY_INSERT 110 +#define KEY_DELETE 111 +#define KEY_KPEQUAL 117 +#define KEY_PAUSE 119 +#define KEY_LEFTMETA 125 +#define KEY_RIGHTMETA 126 +#define KEY_COMPOSE 127 + +/* Relative axes */ +#define REL_X 0x00 +#define REL_Y 0x01 +#define REL_WHEEL 0x08 + +/* Absolute axes */ +#define ABS_X 0x00 +#define ABS_Y 0x01 +#define ABS_PRESSURE 0x18 + +#endif /* __linux__ */ + +#endif /* INPUT_EVENT_CODES_H */ diff --git a/shared/meson.build b/shared/meson.build index eb2f30d..c6c5ee6 100644 --- a/shared/meson.build +++ b/shared/meson.build @@ -6,7 +6,13 @@ srcs_libshared = [ 'process-util.c', 'hash.c', ] + +# libepoll-shim is needed on BSD/macOS for epoll compatibility in os-compatibility.c +dep_epoll_shim_shared = dependency('epoll-shim', required: false) deps_libshared = [dep_wayland_client, dep_pixman, deps_for_libweston_users, dep_egl, dep_vulkan] +if dep_epoll_shim_shared.found() + deps_libshared += dep_epoll_shim_shared +endif lib_libshared = static_library( 'shared', @@ -105,12 +111,17 @@ dep_matrix_c = declare_dependency( dependencies: dep_libm ) -dep_client_buffer = declare_dependency( - sources: [ - 'client-buffer-util.c', - linux_dmabuf_unstable_v1_client_protocol_h, - linux_dmabuf_unstable_v1_protocol_c, - ], - include_directories: public_inc, - dependencies: [ dep_libm, dep_libdrm_headers ] -) +# dep_client_buffer requires libdrm headers which may not be available +if dep_libdrm_headers.found() + dep_client_buffer = declare_dependency( + sources: [ + 'client-buffer-util.c', + linux_dmabuf_unstable_v1_client_protocol_h, + linux_dmabuf_unstable_v1_protocol_c, + ], + include_directories: public_inc, + dependencies: [ dep_libm, dep_libdrm_headers ] + ) +else + dep_client_buffer = dependency('', required: false) +endif diff --git a/shared/os-compatibility.c b/shared/os-compatibility.c index d19d0a4..2a4825c 100644 --- a/shared/os-compatibility.c +++ b/shared/os-compatibility.c @@ -30,8 +30,20 @@ #include #include #include -#include #include + +/* + * On macOS/BSD with libepoll-shim installed, we use the epoll API + * provided by libepoll-shim (which internally uses kqueue). + * Only fall back to raw kqueue if sys/epoll.h is not available. + */ +#if __has_include() +#include +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#include +#include +#define USE_KQUEUE 1 +#endif #include #include #include @@ -119,6 +131,11 @@ os_epoll_create_cloexec(void) { int fd; +#if defined(USE_KQUEUE) + /* kqueue-based implementation for BSD/macOS */ + fd = kqueue(); + return set_cloexec_or_close(fd); +#else #ifdef EPOLL_CLOEXEC fd = epoll_create1(EPOLL_CLOEXEC); if (fd >= 0) @@ -129,6 +146,7 @@ os_epoll_create_cloexec(void) fd = epoll_create(1); return set_cloexec_or_close(fd); +#endif } static int diff --git a/shared/platform-compat.h b/shared/platform-compat.h new file mode 100644 index 0000000..34c320d --- /dev/null +++ b/shared/platform-compat.h @@ -0,0 +1,56 @@ +/* + * Platform compatibility header for non-Linux systems + */ + +#ifndef PLATFORM_COMPAT_H +#define PLATFORM_COMPAT_H + +#include "config.h" + +#include +#include +#include + +#ifdef __linux__ +#include +#else +/* + * timerfd support for BSD/macOS via libepoll-shim. + * We need to define itimerspec before including timerfd.h + */ + +/* itimerspec might not be defined on all systems */ +#if !defined(_STRUCT_ITIMERSPEC) && !defined(EPOLL_SHIM_ITIMERSPEC) +#define _STRUCT_ITIMERSPEC +struct itimerspec { + struct timespec it_interval; + struct timespec it_value; +}; +#endif + +/* Now include libepoll-shim's timerfd.h for the functions */ +#include + +#endif /* __linux__ */ + +/* pipe2() compatibility */ +#ifndef HAVE_PIPE2 +static inline int pipe2(int pipefd[2], int flags) +{ + int ret = pipe(pipefd); + if (ret == -1) + return -1; + + if (flags & O_CLOEXEC) { + fcntl(pipefd[0], F_SETFD, FD_CLOEXEC); + fcntl(pipefd[1], F_SETFD, FD_CLOEXEC); + } + if (flags & O_NONBLOCK) { + fcntl(pipefd[0], F_SETFL, O_NONBLOCK); + fcntl(pipefd[1], F_SETFL, O_NONBLOCK); + } + return 0; +} +#endif /* HAVE_PIPE2 */ + +#endif /* PLATFORM_COMPAT_H */ diff --git a/shared/xalloc.h b/shared/xalloc.h index a2747f9..aa670dd 100644 --- a/shared/xalloc.h +++ b/shared/xalloc.h @@ -36,6 +36,12 @@ extern "C" { #include #include +/* program_invocation_short_name is a GNU extension */ +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#include +#define program_invocation_short_name getprogname() +#endif + static inline void * abort_oom_if_null(void *p) {