From e9179314c481e88f7adf24260423e5abfde86ec7 Mon Sep 17 00:00:00 2001
From: Andrei Alexeyev <[EMAIL REDACTED]>
Date: Wed, 11 Aug 2021 21:27:42 +0300
Subject: [PATCH] joystick/linux: fix memleaks; streamline joylist item removal
---
src/joystick/linux/SDL_sysjoystick.c | 116 ++++++++++-----------------
1 file changed, 41 insertions(+), 75 deletions(-)
diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index eeaf6c81f..001db4ce9 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -268,6 +268,15 @@ static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_clas
}
#endif /* SDL_USE_LIBUDEV */
+static void
+FreeJoylistItem(SDL_joylist_item *item)
+{
+ SDL_free(item->mapping);
+ SDL_free(item->path);
+ SDL_free(item->name);
+ SDL_free(item);
+}
+
static int
MaybeAddDevice(const char *path)
{
@@ -308,21 +317,18 @@ MaybeAddDevice(const char *path)
return -1;
}
- item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
+ item = (SDL_joylist_item *) SDL_calloc(1, sizeof (SDL_joylist_item));
if (item == NULL) {
return -1;
}
- SDL_zerop(item);
item->devnum = sb.st_rdev;
item->path = SDL_strdup(path);
item->name = name;
item->guid = guid;
if ((item->path == NULL) || (item->name == NULL)) {
- SDL_free(item->path);
- SDL_free(item->name);
- SDL_free(item);
+ FreeJoylistItem(item);
return -1;
}
@@ -342,6 +348,31 @@ MaybeAddDevice(const char *path)
return numjoysticks;
}
+static void
+RemoveJoylistItem(SDL_joylist_item *item, SDL_joylist_item *prev)
+{
+ if (item->hwdata) {
+ item->hwdata->item = NULL;
+ }
+
+ if (prev != NULL) {
+ prev->next = item->next;
+ } else {
+ SDL_assert(SDL_joylist == item);
+ SDL_joylist = item->next;
+ }
+
+ if (item == SDL_joylist_tail) {
+ SDL_joylist_tail = prev;
+ }
+
+ /* Need to decrement the joystick count before we post the event */
+ --numjoysticks;
+
+ SDL_PrivateJoystickRemoved(item->device_instance);
+ FreeJoylistItem(item);
+}
+
static int
MaybeRemoveDevice(const char *path)
{
@@ -356,30 +387,7 @@ MaybeRemoveDevice(const char *path)
/* found it, remove it. */
if (SDL_strcmp(path, item->path) == 0) {
const int retval = item->device_instance;
- if (item->hwdata) {
- item->hwdata->item = NULL;
- }
- if (prev != NULL) {
- prev->next = item->next;
- } else {
- SDL_assert(SDL_joylist == item);
- SDL_joylist = item->next;
- }
- if (item == SDL_joylist_tail) {
- SDL_joylist_tail = prev;
- }
-
- /* Need to decrement the joystick count before we post the event */
- --numjoysticks;
-
- SDL_PrivateJoystickRemoved(item->device_instance);
-
- if (item->mapping) {
- SDL_free(item->mapping);
- }
- SDL_free(item->path);
- SDL_free(item->name);
- SDL_free(item);
+ RemoveJoylistItem(item, prev);
return retval;
}
prev = item;
@@ -396,26 +404,7 @@ HandlePendingRemovals(void)
while (item != NULL) {
if (item->hwdata && item->hwdata->gone) {
- item->hwdata->item = NULL;
-
- if (prev != NULL) {
- prev->next = item->next;
- } else {
- SDL_assert(SDL_joylist == item);
- SDL_joylist = item->next;
- }
- if (item == SDL_joylist_tail) {
- SDL_joylist_tail = prev;
- }
-
- /* Need to decrement the joystick count before we post the event */
- --numjoysticks;
-
- SDL_PrivateJoystickRemoved(item->device_instance);
-
- SDL_free(item->path);
- SDL_free(item->name);
- SDL_free(item);
+ RemoveJoylistItem(item, prev);
if (prev != NULL) {
item = prev->next;
@@ -444,9 +433,7 @@ static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickG
item->m_bSteamController = SDL_TRUE;
if ((item->path == NULL) || (item->name == NULL)) {
- SDL_free(item->path);
- SDL_free(item->name);
- SDL_free(item);
+ FreeJoylistItem(item);
return SDL_FALSE;
}
@@ -474,26 +461,7 @@ static void SteamControllerDisconnectedCallback(int device_instance)
for (item = SDL_joylist; item != NULL; item = item->next) {
/* found it, remove it. */
if (item->device_instance == device_instance) {
- if (item->hwdata) {
- item->hwdata->item = NULL;
- }
- if (prev != NULL) {
- prev->next = item->next;
- } else {
- SDL_assert(SDL_joylist == item);
- SDL_joylist = item->next;
- }
- if (item == SDL_joylist_tail) {
- SDL_joylist_tail = prev;
- }
-
- /* Need to decrement the joystick count before we post the event */
- --numjoysticks;
-
- SDL_PrivateJoystickRemoved(item->device_instance);
-
- SDL_free(item->name);
- SDL_free(item);
+ RemoveJoylistItem(item, prev);
return;
}
prev = item;
@@ -1405,9 +1373,7 @@ LINUX_JoystickQuit(void)
for (item = SDL_joylist; item; item = next) {
next = item->next;
- SDL_free(item->path);
- SDL_free(item->name);
- SDL_free(item);
+ FreeJoylistItem(item);
}
SDL_joylist = SDL_joylist_tail = NULL;