diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 970af56b08a42..e1e4e71748fe2 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -33,10 +33,16 @@ static SDL_DBusContext dbus; static int LoadDBUSSyms(void) { +#define SDL_DBUS_SYM2_OPTIONAL(TYPE, x, y) \ + dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y) + #define SDL_DBUS_SYM2(TYPE, x, y) \ if (!(dbus.x = (TYPE)SDL_LoadFunction(dbus_handle, #y))) \ return -1 +#define SDL_DBUS_SYM_OPTIONAL(TYPE, x) \ + SDL_DBUS_SYM2_OPTIONAL(TYPE, x, dbus_##x) + #define SDL_DBUS_SYM(TYPE, x) \ SDL_DBUS_SYM2(TYPE, x, dbus_##x) @@ -77,6 +83,7 @@ static int LoadDBUSSyms(void) SDL_DBUS_SYM(dbus_bool_t (*)(const DBusError *), error_is_set); SDL_DBUS_SYM(void (*)(DBusError *), error_free); SDL_DBUS_SYM(char *(*)(void), get_local_machine_id); + SDL_DBUS_SYM_OPTIONAL(char *(*)(DBusError *), try_get_local_machine_id); SDL_DBUS_SYM(void (*)(void *), free); SDL_DBUS_SYM(void (*)(char **), free_string_array); SDL_DBUS_SYM(void (*)(void), shutdown); @@ -502,4 +509,38 @@ void SDL_DBus_PumpEvents(void) } } } + +/* + * 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 diff --git a/src/core/linux/SDL_dbus.h b/src/core/linux/SDL_dbus.h index 6326ba7c2b77d..9234c5926cbce 100644 --- a/src/core/linux/SDL_dbus.h +++ b/src/core/linux/SDL_dbus.h @@ -75,6 +75,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); @@ -99,6 +100,7 @@ extern void SDL_DBus_ScreensaverTickle(void); extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit); extern void SDL_DBus_PumpEvents(void); +extern char *SDL_DBus_GetLocalMachineId(void); #endif /* HAVE_DBUS_DBUS_H */ diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index 4b5d4bbe083cb..92475c2579fae 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -411,7 +411,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",