diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 15720492d..f2358343f 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -36,6 +36,9 @@ static SDL_DBusContext dbus; static int LoadDBUSSyms(void) { +#define SDL_DBUS_SYM2_OPTIONAL(x, y) \ + dbus.x = SDL_LoadFunction(dbus_handle, #y) + #define SDL_DBUS_SYM2(x, y) \ if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) \ return -1 @@ -43,6 +46,9 @@ static int LoadDBUSSyms(void) #define SDL_DBUS_SYM(x) \ SDL_DBUS_SYM2(x, dbus_##x) +#define SDL_DBUS_SYM_OPTIONAL(x) \ + SDL_DBUS_SYM2_OPTIONAL(x, dbus_##x) + SDL_DBUS_SYM(bus_get_private); SDL_DBUS_SYM(bus_register); SDL_DBUS_SYM(bus_add_match); @@ -80,6 +86,7 @@ static int LoadDBUSSyms(void) SDL_DBUS_SYM(error_is_set); SDL_DBUS_SYM(error_free); SDL_DBUS_SYM(get_local_machine_id); + SDL_DBUS_SYM_OPTIONAL(try_get_local_machine_id); SDL_DBUS_SYM(free); SDL_DBUS_SYM(free_string_array); SDL_DBUS_SYM(shutdown); @@ -493,6 +500,40 @@ SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit) return SDL_TRUE; } + +/* + * Get the machine ID if possible. Result must be freed with dbus->free(). + */ +char *SDL_DBus_GetLocalMachineId(void) +{ + DBusError err; + char *result; + + dbus.error_init(&err); + + if (dbus.try_get_local_machine_id) { + /* Available since dbus 1.12.0, has proper error-handling */ + result = dbus.try_get_local_machine_id(&err); + } else { + /* Available since time immemorial, but has no error-handling: + * if the machine ID can't be read, many versions of libdbus will + * treat that as a fatal mis-installation and abort() */ + result = dbus.get_local_machine_id(); + } + + if (result) { + return result; + } + + if (dbus.error_is_set(&err)) { + SDL_SetError("%s: %s", err.name, err.message); + dbus.error_free(&err); + } else { + SDL_SetError("Error getting D-Bus machine ID"); + } + + return NULL; +} #endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/core/linux/SDL_dbus.h b/src/core/linux/SDL_dbus.h index 07e017cf4..cda279eca 100644 --- a/src/core/linux/SDL_dbus.h +++ b/src/core/linux/SDL_dbus.h @@ -72,6 +72,7 @@ typedef struct SDL_DBusContext dbus_bool_t (*error_is_set)(const DBusError *); void (*error_free)(DBusError *); char *(*get_local_machine_id)(void); + char *(*try_get_local_machine_id)(DBusError *); void (*free)(void *); void (*free_string_array)(char **); void (*shutdown)(void); @@ -95,6 +96,8 @@ extern SDL_bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const c extern void SDL_DBus_ScreensaverTickle(void); extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit); +extern char *SDL_DBus_GetLocalMachineId(void); + #endif /* HAVE_DBUS_DBUS_H */ #endif /* SDL_dbus_h_ */ diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index 60b69b708..4241cd4ad 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -410,7 +410,12 @@ static char *IBus_GetDBusAddressFilename(void) (void)SDL_snprintf(config_dir, sizeof(config_dir), "%s/.config", home_env); } - key = dbus->get_local_machine_id(); + key = SDL_DBus_GetLocalMachineId(); + + if (key == NULL) { + SDL_free(display); + return NULL; + } SDL_memset(file_path, 0, sizeof(file_path)); (void)SDL_snprintf(file_path, sizeof(file_path), "%s/ibus/bus/%s-%s-%s",