dbus_noop_shim.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435
  1. // LD_PRELOAD shim for headless test environments with no D-Bus session bus (no dbus-daemon,
  2. // no /etc/machine-id, no permission to create one - e.g. a minimal container).
  3. //
  4. // The engine already treats a failed dbus_bus_get() as non-fatal in most places (returns
  5. // nullptr, callers null-check), but at least one call path (a periodic MPRIS "detect player"
  6. // retry) calls dbus_connection_send_with_reply_and_block() without checking for a null
  7. // connection first, which aborts the whole process instead of just skipping that feature.
  8. // This shim intercepts that one libdbus entry point: if the connection is NULL, return NULL
  9. // (which is exactly what the real function would do on failure) instead of hitting libdbus's
  10. // own internal assertion and calling abort().
  11. //
  12. // Build: gcc -shared -fPIC -o dbus_noop_shim.so dbus_noop_shim.c -ldl
  13. // Use: LD_PRELOAD=/path/to/dbus_noop_shim.so ./linux-wallpaperengine ...
  14. #define _GNU_SOURCE
  15. #include <dlfcn.h>
  16. #include <stdio.h>
  17. typedef struct DBusConnection DBusConnection;
  18. typedef struct DBusMessage DBusMessage;
  19. typedef struct DBusError DBusError;
  20. typedef DBusMessage *(*real_fn_t)(DBusConnection *, DBusMessage *, int, DBusError *);
  21. DBusMessage *dbus_connection_send_with_reply_and_block(DBusConnection *connection, DBusMessage *message,
  22. int timeout_milliseconds, DBusError *error) {
  23. if (connection == NULL) {
  24. fprintf(stderr, "[dbus_noop_shim] blocked send_with_reply_and_block on NULL connection\n");
  25. return NULL;
  26. }
  27. static real_fn_t real = NULL;
  28. if (!real) {
  29. real = (real_fn_t) dlsym(RTLD_NEXT, "dbus_connection_send_with_reply_and_block");
  30. }
  31. return real(connection, message, timeout_milliseconds, error);
  32. }